BS2000-LMS

 view release on metacpan or  search on metacpan

LMS.xs  view on Meta::CPAN

/* the code:								*/
/* -------------------------------------------------------------------- */

/* ToDo: sv_2mortal after each hv_fetch??? */

#define GET_INTEGER_FROM_HASH(variable,hash,key) \
	l_pScalarValue = hv_fetch(hash, KEY(key), 0); \
	if (l_pScalarValue == NULL  ||  *l_pScalarValue == NULL) \
	  XSRETURN_UNDEF; \
	variable = SvIV(*l_pScalarValue)
#define GET_STRING_FROM_HASH(variable,hash,key) \
	l_pScalarValue = hv_fetch(hash, KEY(key), 0); \
	if (l_pScalarValue == NULL  ||  *l_pScalarValue == NULL) \
	  XSRETURN_UNDEF; \
	strfill(variable, SvPV(*l_pScalarValue, l_iDummy), sizeof(variable))
#define GET_OPTIONAL_CHAR_FROM_HASH(variable,hash,key) \
	l_pScalarValue = hv_fetch(hash, KEY(key), 0); \
	if (l_pScalarValue != NULL  &&  *l_pScalarValue != NULL) \
	  strfill(&(variable), SvPV(*l_pScalarValue, l_iDummy), 1)
#define GET_OPTIONAL_INTEGER_FROM_HASH(variable,hash,key) \
	l_pScalarValue = hv_fetch(hash, KEY(key), 0); \
	if (l_pScalarValue != NULL  &&  *l_pScalarValue != NULL) \
	  variable = SvIV(*l_pScalarValue)
#define GET_OPTIONAL_STRING_FROM_HASH(variable,hash,key) \
	l_pScalarValue = hv_fetch(hash, KEY(key), 0); \
	if (l_pScalarValue != NULL  &&  *l_pScalarValue != NULL) \
	  strfill(variable, SvPV(*l_pScalarValue, l_iDummy), sizeof(variable))
#define PUT_CHAR_INTO_HASH(variable,hash,key) \
	if (NULL == hv_store(hash, KEY(key), newSVpv(&(variable), 1), 0)) \
	  XSRETURN_UNDEF
#define PUT_INTEGER_INTO_HASH(variable,hash,key) \
	if (NULL == hv_store(hash, KEY(key), newSViv(variable), 0)) \
	  XSRETURN_UNDEF
/* trailing blanks in strings are removed for this one: */
#define PUT_STRING_INTO_HASH(variable,hash,key) \
	if (NULL == hv_store(hash, KEY(key), \
			     newSVpv_trimmed(FIELD(variable)), 0)) \
	  XSRETURN_UNDEF
/* not used yet:
#define PUT_UNTRIMMED_STRING_INTO_HASH(variable,hash,key) \
	if (NULL == hv_store(hash, KEY(key), \
			     newSVpv(FIELD(variable)), 0)) \
	  XSRETURN_UNDEF
*/

/************************************************************************/
/* global lock for TOC ID (for multi threaded access to LMS TOC):	*/
/* We use a poor man's semaphor here as a real mutex produces massive	*/
/* system overhead.							*/
/************************************************************************/
#define MAX_TOC_ID 10
int g_toc_semaphor = 0;
int g_toc_id_used[MAX_TOC_ID] = { 0, 0, 0, 0, 0,  0, 0, 0, 0, 0 };

/************************************************************************/
/* Description:								*/
/* -------------------------------------------------------------------- */
/* lock the poor man's semaphor:					*/
/* -------------------------------------------------------------------- */
/* Parameter: -								*/
/* Result   : 1 if semaphor got locked, 0 otherwise			*/
/************************************************************************/
int lock_semaphor()		/* invariant (proof for correctness): */
{
    int l_iCountdown = 10;	/* g_toc_semaphor >= 0 */
    ++g_toc_semaphor;		/* g_toc_semaphor >= 1 */
    while (1 < g_toc_semaphor)	/*			  g_toc_semaphor>1 */
    {				/* g_toc_semaphor >= 1 */
	--g_toc_semaphor;	/* g_toc_semaphor >= 0 */
	if (--l_iCountdown <= 0)
	  return 0;
	sleep(1);		/* g_toc_semaphor >= 0 */
	++g_toc_semaphor;	/* g_toc_semaphor >= 1 */
    }				/* g_toc_semaphor>=1 || ! g_toc_semaphor>1 */
    return 1;			/* g_toc_semaphor == 1 */
}
/************************************************************************/
/* Description:								*/
/* -------------------------------------------------------------------- */
/* unlock the poor man's semaphor:					*/
/* -------------------------------------------------------------------- */
/* Parameter: -								*/
/* Result   : -								*/
/************************************************************************/
void unlock_semaphor()
{
    --g_toc_semaphor;
}

/************************************************************************/
/* Description:								*/
/* -------------------------------------------------------------------- */
/* get a unique TOC ID (for multi threaded access to LMS TOC):		*/
/* -------------------------------------------------------------------- */
/* Parameter: -								*/
/* Result   : 0 (if no ID is free) or an ID (1..MAX_TOC_ID)		*/
/************************************************************************/
int get_toc_id()
{
    int l_iID = 0;
    if (lock_semaphor())
    {
	/* find (backwards) first free TOC ID: */
	for (l_iID = MAX_TOC_ID; l_iID > 0; --l_iID)
	{
	    if (0 == g_toc_id_used[ l_iID - 1 ])
	    {
		g_toc_id_used[ l_iID - 1 ] = 1;
		break;
	    }
	}
	unlock_semaphor();
    }
    return l_iID;
}

/************************************************************************/
/* Description:								*/
/* -------------------------------------------------------------------- */
/* release the unique TOC ID reserved with get_toc_id:			*/
/* -------------------------------------------------------------------- */



( run in 0.598 second using v1.01-cache-2.11-cpan-df04353d9ac )