/*{ ** 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 ); }
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 ); }
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 ); }