Пример #1
0
MO_INSTANCE *
MO_getinstance( char *classid, char *instance )
{
    MO_CLASS	cb;
    MO_INSTANCE	ib;
    MO_INSTANCE	*ip;

    cb.node.key = classid;
    ib.classdef = &cb;
    ib.instance = instance;
    ib.node.key = (PTR)&ib;

    if( instance != NULL )	/* find exact match */
    {
	ip = (MO_INSTANCE *)SPlookup( &ib.node, MO_instances );
    }
    else			/* find first of that class */
    {
	/*
	** This relies on the comparison function returning -1
	** when classids are equal, and the input instance is NULL.
	** After the enq, ib is the lowest block of the class; the
	** next one is the old first.
	*/
	(VOID) SPenq( &ib.node, MO_instances );
	ip = (MO_INSTANCE *)SPnext( &ib.node, MO_instances );
	SPdelete( &ib.node, MO_instances );

	if( ip != NULL && !STequal( (char *)ip->classdef->node.key, classid ) )
	    ip = NULL;
    }

# ifdef xDEBUG
    SIprintf("getinstance %s:%s -> %s:%s\n",
	     classid ? classid : "<nil>",
	     instance ? instance : "<nil>",
	     ip ? ip->classdef->node.key : "<nil>",
	     ip ? ip->instance : "<nil>" );
# endif

    return( ip );
}
Пример #2
0
STATUS
MOattach( i4  flags, char *classid, char *instance, PTR idata )
{
    MO_INSTANCE	*ip;
    MO_CLASS	*cp;
    STATUS	stat;

    stat = OK;

    if( MO_disabled )
	return( stat );

    MO_once();
    stat = MO_mutex();
    if( stat == OK )		/* got mutex */
    {
	do
	{
	    if( stat != OK )
		break;

	    MO_nattach++;

# ifdef xDEBUG
	    SIprintf("attach %s:%s object %p\n",
		     classid,
		     instance,
		     idata );
# endif

	    /* check for special error cases */

	    ip = MO_getinstance( classid, instance );
	    if( ip != NULL )
	    {
		stat = MO_ALREADY_ATTACHED;
		break;
	    }

	    /* Get class, error if missing */

	    if( OK != MO_getclass( classid, &cp ) )
	    {
		stat = MO_NO_CLASSID;
		break;
	    }

	    /* Release mutex to prevent deadlock in MO_alloc call */
	    (VOID) MO_unmutex();
	    ip = (MO_INSTANCE *)MO_alloc( sizeof(*ip), &stat );
            stat = MO_mutex();
	    if( NULL == ip )
		break;

	    ip->classdef = cp;
	    ip->iflags = flags;
	    if( (flags & MO_INSTANCE_VAR) == 0 )
	    {
		ip->instance = instance;
	    }
	    else
	    {
		ip->instance = MO_defstring( instance, &stat );
		if( ip->instance == NULL )
		{
		    MO_free( (PTR)ip, sizeof(*ip) );
		    break;
		}
	    }
	    ip->idata = idata;
	    ip->node.key = (PTR)ip;

	    (VOID) SPenq( &ip->node, MO_instances );

	} while( FALSE );

	(VOID) MO_unmutex();

	/* Attach twin if needed */

	if( stat == OK && cp->twin != NULL && !CMdigit( (char *)cp->node.key ) )
	    stat = MOattach( flags, cp->twin->node.key, instance, idata );
    }

# if xDEBUG
    if( stat != OK )
	TRdisplay("attach (%s:%s) failed status %d\n",
		  classid, instance, stat );
# endif

    if( stat == OK )
    {
	if ( (stat = MO_mutex()) == OK)
	{
	    (VOID) MO_tell_class( cp, instance, (char *)NULL, MO_ATTACH );
            MO_unmutex ();
	}
    }

    return( stat );
}
Пример #3
0
STATUS
MOset_monitor(	char *classid,
		PTR mon_data,
		char *qual_regexp,
		MO_MONITOR_FUNC *monitor,
		MO_MONITOR_FUNC **old_monitor )
{
    MO_MON_BLOCK *mp;		/* our monitor block */
    MO_MON_BLOCK *fmp;		/* first monitor block */
    MO_MON_BLOCK *pmp;		/* previous monitor block */
    MO_CLASS *cp;		/* class in question (not classid) */
    char *saved_qual = NULL;

    STATUS ret_val = OK;
    STATUS mutex_stat;

    mutex_stat = MO_mutex();
    do
    {
	if( mutex_stat != OK )
	    break;

	/* if we'll need it, save any qual_regexp string */

	if( monitor != NULL && qual_regexp != NULL )
	{
	    saved_qual = MO_defstring( qual_regexp, &ret_val );
	    if( saved_qual == NULL )
		break;

	    /* FIXME maybe compile it here too? */
	}

	/* locate the class def, we need it everywhere */

	if( (ret_val = MO_getclass( classid, &cp )) != OK )
	    break;

	/* see if this is a replacement for an existing monitor */

	mp = NULL;
	if( (mp = MO_getmon( cp, mon_data ) ) != NULL )
	{
	    /* yes, replace it with new values as appropriate */

	    *old_monitor = mp->monitor;
	    if( monitor == NULL ) /* delete this monitor */
	    {
		MO_delmon( mp );
	    }
	    else		/* replace this one's values */
	    {
		mp->monitor = monitor;
		mp->mon_data = mon_data;

		/* delete old qual string */
		if( mp->qual_regexp != NULL )
		    MO_delstring( mp->qual_regexp );
		mp->qual_regexp = saved_qual;
	    }
	}
	else if( monitor == NULL ) /* huh!? */
	{
	    ret_val = MO_BAD_MONITOR;
	    break;
	}
	else			/* make a new one and link it in. */
	{
	    *old_monitor = NULL;

	    /* if it's an OID, get the class def instead */

	    if( CMdigit( (char *)cp->node.key ) && cp->twin != NULL )
		cp = cp->twin;

	    /* get a new monitor block */

	    mp = (MO_MON_BLOCK *)MO_alloc( sizeof( *mp ), &ret_val );
	    if( mp == NULL )
		break;

	    /* fill in the new block, and link in to the tree */

	    mp->node.key = (PTR)mp;
	    mp->mo_class = cp;
	    mp->monitor = monitor;
	    mp->mon_data = mon_data;
	    mp->qual_regexp = saved_qual;
	    (void) SPenq( &mp->node, MO_monitors );

	    /* Fill in the class with first monitor for the class.
	       The loop below goes backwards until pmp is null or
	       doesn't have the same class definition.  When it exits,
	       fmp is at the first monitor block for the class */

	    for( fmp = mp;
		(pmp = (MO_MON_BLOCK *)SPfprev( &fmp->node )) != NULL &&
		pmp->mo_class == cp; fmp = pmp )
		continue;

	    fmp->mo_class->monitor = fmp;
	    if( cp->twin )
		cp->twin->monitor = fmp;
	}

    } while ( FALSE );

    if( mutex_stat != OK )
    {
	ret_val = mutex_stat;
    }
    else
    {
	if( ret_val == OK )
	    MO_nset_monitor++;
	else if( saved_qual != NULL )
	    MO_delstring( saved_qual );

	(void) MO_unmutex();
    }

    return( ret_val );
}