Example #1
0
/*{
**  Name:	MOset - set value associated with an instance
**
**  Description:
**
**	Attempts to set the value associated with the instance.
**
**	If the call succeeds, it must also call the monitors for the
**	class with the MO_SET event, the instance id, and the new value.
**  Inputs:
**	 valid_perms
**		the roles currently in effect, to be and-ed with object
**		permissions to determine access rights.
**	 class
**		the class whose value should be altered.
**	 instance
**		the instance in question.
**	 val
**		pointer to the string containing the new value.
**  Outputs:
**	 none
**  Returns:
**	 OK
**		if the value was set
**	 MO_NO_INSTANCE
**		if the class is not attached
**	 MO_NO_WRITE
**		if the class may not be changed.
**	 other
**		error status returned by a method.
**  History:
**	23-sep-92 (daveb)
**	    documented
**	 6-Apr-04 (gordy)
**	    Permit access if MO_ANY_WRITE attribute is set.
**	24-Oct-05 (toumi01) BUG 115449
**	    Don't hold onto MO mutex if class' processing will try
**	    to take the mutex, and would thus deadlock on ourself.
*/
STATUS
MOset(i4 valperms,
      char *classid,
      char *instance,
      char *val )
{
    STATUS stat = OK;
    MO_CLASS *cp;
    PTR idata;

    MO_once();
    stat = MO_mutex();
    if( stat != OK )
	return( stat );
    MO_nset++;

    /* get class and instance data */

    if( OK == (stat = MO_getclass( classid, &cp ) ) )
    {
	if( (cp->perms & MO_ANY_WRITE) != 0  ||  
	    (valperms & MO_WRITE & cp->perms) != 0 )
	    stat = (*cp->idx)( MO_GET, cp->cdata, 0, instance, &idata );
	else
	    stat = MO_NO_WRITE;
    }

    if( stat == OK )
    {
	if (cp->cflags & MO_NO_MUTEX)
	    (VOID) MO_unmutex();
	stat = (*cp->set)( cp->offset, 0, val, cp->size, idata );
	if (cp->cflags & MO_NO_MUTEX)
	{
	    stat = MO_mutex();
	    if( stat != OK )
		return( stat );
	}
    }

    if( stat == OK )
	(VOID) MO_tell_class( cp, instance, val, MO_SET );

    (VOID) MO_unmutex();
    return( stat );
}
Example #2
0
STATUS
MOget(i4 valperms,
      char *classid,
      char *instance,
      i4  *lsbufp,
      char *sbuf,
      i4  *operms )
{
    STATUS stat;
    MO_once();
    stat = MO_mutex();
    if( stat == OK )
    {
	stat = MO_get( valperms, classid, instance, lsbufp, sbuf, operms );
	(VOID) MO_unmutex();
    }
    return( stat );
}
Example #3
0
STATUS
MOtell_monitor( char *classid, char *instance, char *value, i4  msg )
{
    MO_CLASS *cp;
    STATUS ret_val = OK;

    MO_once();
    ret_val = MO_mutex();
    if( ret_val == OK )
    {
	ret_val = MO_getclass( classid, &cp );
	if( ret_val == OK && cp->monitor != NULL )
	    ret_val = MO_tell_class( cp, instance, value, msg );

	(VOID) MO_unmutex();
    }
    return( ret_val );
}
Example #4
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 #5
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 );
}