Example #1
0
STATUS
MO_ipindex(i4 msg,
	   PTR cdata,
	   i4  linstance,
	   char *instance,
	   PTR *instdata )
{
    STATUS stat = MO_NO_INSTANCE;
    MO_INSTANCE *ip;

    ip = MO_getinstance( (char *)cdata, instance );

    switch( msg )
    {
    case MO_GET:

	if( ip != NULL )
	    stat = OK;
	break;

    case MO_GETNEXT:

	if( ip != NULL )
	{
	    ip = (MO_INSTANCE *) SPnext( &ip->node, MO_instances );
	    if( ip != NULL &&
	       !STequal( (char *)ip->classdef->node.key, (char *)cdata ) )
		ip = NULL;
	}
	else			/* didn't find directly */
	{
	    if( *instance == EOS  )
		ip = MO_getinstance( (char *)cdata, (char *)NULL );
	    else
		break;
	}

	if( ip == NULL )
	    stat = MO_NO_NEXT;
	else
	    stat = MOstrout( MO_INSTANCE_TRUNCATED,
			     ip->instance, linstance, instance );
	break;

    default:

	stat = MO_BAD_MSG;
	break;
    }

    *instdata = (PTR)ip;

    return( stat );
}
Example #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 );
}
Example #3
0
/*{
**  Name:	MOdetach - detach an attached instance
**
**  Description:
**
**	Detaches an attached instance.  Subsequent attempts to get or
**	set it will fail, and an attempts to attach it will succeed.
**
**	Frees memory allocated by MOattach using MEfree.
**
**	If the call succeeds, it must also call the monitors for the
**	class with the MO_DETACH event, the instance id, and a NULL
**	value.
**
**  Inputs:
**	 classid
**		the classid of the object.
**	 instance
**		the instance of the object.
**  Outputs:
**	 none
**  Returns:
**	 OK
**		if the classid was detached.
**	 MO_NO_INSTANCE
**		if classid is not attached.
**	 MO_NO_DETACH
**		if the object was attached as MO_PERMANENT.
**
**    History:
**	15-jul-92 (daveb)
**	    Go back to single-instance attach/detach, as with
**	    MOcdata_index most bulky static one-offs will be
**	    right in the class definitions anyway, and this
**	    is simpler for the dynamic attach.
**	02-sep-1999 (somsa01)
**	    We were calling MO_tell_class AFTER releasing the MO mutex.
*/
STATUS
MOdetach( char *classid, char *instance )
{
    MO_INSTANCE	*ip;
    MO_CLASS	*cp;
    STATUS stat = OK;
    STATUS mutex_stat = OK;

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

	MO_ndetach++;

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

	cp = ip->classdef;
	if( cp->perms & MO_PERMANENT )
	{
	    stat = MO_NO_DETACH;
	    break;
	}

	/*
	** We have detachable instance, do it
	*/

	/* detach twin, if any, giving up it it won't go away */

	if( CMalpha( classid ) && NULL != cp->twin &&
	   (stat = MOdetach( cp->twin->node.key, ip->instance)) != OK )
	    break;

	/* delete saved instance string */

	if( (ip->iflags & MO_INSTANCE_VAR) != 0 )
	    MO_delstring( ip->instance );

	/* and finally delete this node */

	SPdelete( &ip->node, MO_instances );
	MO_free( (PTR)ip, sizeof(*ip) );

    } while( FALSE );

    if( mutex_stat == OK )
	(VOID) MO_unmutex();
    else
	stat = mutex_stat;

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

    return( stat );
}
Example #4
0
STATUS
MO_getnext(i4 valperms,
	   i4  lclassid,
	   i4  linstance,
	   char *classid,
	   char *instance,
	   i4  *lsbufp,
	   char *sbuf,
	   i4  *operms )
{
    STATUS stat = OK;
    STATUS xstat = OK;

    MO_INSTANCE *ip;
    MO_CLASS *cp;		/* this class */
    PTR idata;

    MO_ngetnext++;

# ifdef xDEBUG
    SIprintf("getnext entry: %s:%s\n", classid, instance );
# endif

    ip = NULL;
    cp = NULL;
    *sbuf = EOS;

    if( *instance != EOS )
    {
	ip = MO_getinstance( classid, instance );
	if( ip != NULL )
	    cp = ip->classdef;
	else if( OK != MO_getclass( classid, &cp ) )
	    stat = MO_NO_CLASSID;
    }
    else if( *classid != EOS && OK != MO_getclass( classid, &cp ) )
    {
	stat = MO_NO_CLASSID;
    }

    /*
    ** Now do the real work:  Given the starting point implied
    ** by ip and cp, find the next visible instance.
    */
    if( stat == OK )
    {
	if( cp == NULL )	/* start with first class */
	{
	    cp = (MO_CLASS *) SPfhead( MO_classes );
	    ip = NULL;
	}

	/*
	 ** Loop over classes looking for the next valid instance.
	 **
	 ** On exit, if cp != NULL, it's the class of the found instance;
	 **	if NULL, then we never found a good instance.
	 */
	for( ; cp != NULL ; cp = (MO_CLASS *)SPnext( &cp->node, MO_classes ) )
	{
	    if( (cp->perms & MO_ANY_READ) != 0  ||
		(valperms & MO_READ & cp->perms) != 0 )
	    {
		stat = (*cp->idx)( MO_GETNEXT, cp->cdata,
			      linstance, instance, &idata );
		if( stat == OK )
		{
		    stat = (*cp->get)( cp->offset,
				      cp->size, idata,
				      *lsbufp, sbuf  );
		    if( stat == OK )
			break;
		}
	    }
	    /* Now caller's ip and instance are bogus; set to search state */

	    ip = NULL;
	    *instance = EOS;
	}

	if( cp == NULL )
	    stat = MO_NO_NEXT;

	if( stat == OK || MO_IS_TRUNCATED( stat ) )
	    xstat = MOstrout( MO_CLASSID_TRUNCATED,
			      cp->node.key, lclassid, classid );

	if( stat == OK )
	    stat = xstat;
    }

    *lsbufp = (i4)STlength( sbuf );

    if( stat == OK || stat == MO_VALUE_TRUNCATED )
    {
	*operms = cp->perms;
	(VOID) MO_tell_class( cp, instance, sbuf, MO_GET );
    }

# ifdef xDEBUG
    SIprintf("getnext exit: (%d) %s:%s - %s\n",
	     stat, classid, instance, sbuf );
# endif
    return( stat );
}