VOID MO_delmon( MO_MON_BLOCK *mp ) { MO_MON_BLOCK *nmp; /* next monitor */ MO_CLASS *cp = mp->mo_class; /* free the regexp we saved earlier */ if( mp->qual_regexp != NULL ) MO_delstring( mp->qual_regexp ); /* If this is the first monitor for the class, then we need to point the class at the next one, because this one is going away. If the next one is for a different class, then there are no more monitors for this class. */ if( cp->monitor == mp ) { nmp = (MO_MON_BLOCK *)SPfnext( &mp->node ); cp->monitor = ( nmp != NULL && nmp->mo_class == cp ) ? nmp : NULL; if( cp->twin ) cp->twin->monitor = cp->monitor; } /* slice it out of the tree*/ SPdelete( &mp->node, MO_monitors ); /* recover memory for the node */ MO_free( (PTR)mp, sizeof(*mp) ); MO_ndel_monitor++; }
/*{ ** Name: MO_mon_id_get -- get method for monitor id. ** ** Description: ** A get method to make the monitor id visible. ** ** Re-entrancy: ** yes. ** ** Inputs: ** offset ignored ** objsize ignored ** object an MO_MON_BLOCK ** luserbuf length of out buf ** ** Outputs: ** userbuf out buf ** ** Returns: ** OK ** MO_VALUE_TRUNCATED ** ** Side Effects: ** May temporarily allocated some memory, freed before return. ** ** History: ** 24-sep-92 (daveb) ** documented ** 7-sep-93 (swm) ** call MOptrout() rather than MOulongout() for mp->mon_data to ** avoid i4/pointer truncation errors. */ STATUS MO_mon_id_get(i4 offset, i4 objsize, PTR object, i4 luserbuf, char *userbuf) { STATUS ret_val = OK; MO_MON_BLOCK *mp = (MO_MON_BLOCK *)object; char localbuf[ MO_MAX_NUM_BUF * 3 + 2 ]; char numbuf[ MO_MAX_NUM_BUF ]; i4 len; char *outbuf; (void)MOptrout( 0, mp->mon_data, sizeof( numbuf ), numbuf ); len = (i4)(STlength( mp->mo_class->node.key ) + STlength(numbuf) + 2); if( len <= sizeof( localbuf ) ) outbuf = localbuf; else outbuf = MO_alloc( len, &ret_val ); if( ret_val == OK ) { STprintf( outbuf, "%s.%s", mp->mo_class->node.key, numbuf ); ret_val = MOstrout( MO_VALUE_TRUNCATED, outbuf, luserbuf, userbuf ); if( outbuf != localbuf ) MO_free( outbuf, len ); } # if 0 if( ret_val != OK ) /* FIXME */ # endif return( ret_val ); }
/*{ ** 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 ); }
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 ); }