STATUS MO_tell_class( MO_CLASS *cp, char *instance, char *value, i4 msg ) { MO_MON_BLOCK *mp; STATUS ret_val = OK; for( mp = cp->monitor; ret_val == OK && mp != NULL && mp->mo_class == cp; mp = (MO_MON_BLOCK *)SPfnext( &mp->node ) ) { /* FIXME: handle REmatch correctly */ if( mp->qual_regexp == NULL /* || REmatch( mp->qual_regexp, instance ) */ ) { MO_ntell_monitor++; ret_val = (*mp->monitor)( cp->node.key, cp->twin ? cp->twin->node.key : NULL, instance, value, mp->mon_data, msg ); } } return( ret_val ); }
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++; }
static STATUS GM_subpindex(i4 msg, PTR cdata, i4 linstance, char *instance, PTR *instdata ) { STATUS cl_stat = MO_NO_INSTANCE; GM_PLACE_BLK *pb; SPBLK lookup; lookup.key = instance; pb = (GM_PLACE_BLK *)SPlookup( &lookup, &GM_globals.gwm_places ); switch( msg ) { case MO_GET: if( pb != NULL ) cl_stat = OK; break; case MO_GETNEXT: if( pb != NULL ) { pb = (GM_PLACE_BLK *) SPfnext( &pb->place_blk ); } else /* didn't find directly */ { if( *instance == EOS ) pb = (GM_PLACE_BLK *)SPfhead( &GM_globals.gwm_places ); else break; } if( pb == NULL ) cl_stat = MO_NO_NEXT; else cl_stat = MOstrout( MO_INSTANCE_TRUNCATED, pb->place_key, linstance, instance ); break; default: cl_stat = MO_BAD_MSG; break; } *instdata = (PTR)pb; return( cl_stat ); }
STATUS GM_cindex(i4 msg, PTR cdata, i4 linstance, char *instance, PTR *instdata ) { STATUS cl_stat = MO_NO_INSTANCE; GM_PLACE_BLK *pb; GM_CONN_BLK *cb; GM_SRVR_BLK *sb; PTR conn_key; i4 got_place = FALSE; i4 got_srvr = FALSE; GM_dc_conn_instance( instance, &conn_key ); do { if( GM_gt_sem( &GM_globals.gwm_places_sem ) != OK ) break; else got_place = TRUE; switch( msg ) { case MO_GET: cl_stat = GM_gt_conn( instance, conn_key, &pb, &cb ); if( cl_stat == OK ) { /* assert: pb->place_sem is now held */ got_srvr = TRUE; sb = &pb->place_srvr; } break; case MO_GETNEXT: /* empty instance means find first connection */ if( *instance == EOS ) { pb = NULL; cb = NULL; } else /* next after known connection */ { /* if input instance doesn't exist, NO_INSTANCE */ cl_stat = GM_gt_conn( instance, conn_key, &pb, &cb ); if( cl_stat != OK ) break; got_srvr = TRUE; sb = &pb->place_srvr; } do /* search for next connection */ { if( got_srvr ) { GM_release_sem( &pb->place_sem ); got_srvr = FALSE; } /* if we have cb, try next on this server */ if( cb != NULL ) cb = (GM_CONN_BLK *)SPfnext( &cb->conn_blk ); /* if still null, try next server */ if( cb == NULL ) { /* may be null on first call to find first. */ if( pb == NULL ) { pb = (GM_PLACE_BLK *)SPfhead( &GM_globals.gwm_places ); } else /* not initial trip */ { sb = &pb->place_srvr; pb = (GM_PLACE_BLK *)SPfnext( &pb->place_blk ); } /* if this is a server, grab sem and then the head of the connection tree. */ if( pb != NULL && pb->place_type == GM_PLACE_SRVR ) { sb = &pb->place_srvr; if( GM_gt_sem( &pb->place_sem ) != OK ) { pb = NULL; } else { got_srvr = TRUE; cb = (GM_CONN_BLK *)SPfhead( &sb->srvr_conns ); } } } } while( cb == NULL && pb != NULL ); if( cb == NULL ) { cl_stat = MO_NO_NEXT; } else { cl_stat = GM_mk_conn_instance( pb->place_blk.key, cb->conn_blk.key, linstance, instance ); } break; default: cl_stat = MO_BAD_MSG; break; } } while ( FALSE ); if( cl_stat == OK ) *instdata = (PTR)cb; if( got_place ) GM_release_sem( &GM_globals.gwm_places_sem ); if( got_srvr ) GM_release_sem( &pb->place_sem ); return( cl_stat ); }
STATUS MO_oid_set(i4 offset, i4 luserbuf, char *userbuf, i4 objsize, PTR object ) { STATUS cl_stat = OK; MO_CLASS *cp = (MO_CLASS *)object; MO_CLASS *twin_cp; MO_INSTANCE *ip; MO_INSTANCE *next_ip; MO_CLASS_DEF mo_class; do { /* if it has a twin already, error */ if( cp->twin != NULL ) { cl_stat = MO_NO_WRITE; break; } mo_class.flags = MO_CLASSID_VAR | cp->cflags; mo_class.classid = userbuf; mo_class.size = cp->size; mo_class.perms = cp->perms; mo_class.index = cp->index; mo_class.get = cp->get; mo_class.set = cp->set; mo_class.cdata = cp->cdata; mo_class.idx = cp->idx; if( OK != (cl_stat = MOclassdef( 1, &mo_class ) ) ) break; if( OK != (cl_stat = MO_getclass( userbuf, &twin_cp ) ) ) break; cp->twin = twin_cp; twin_cp->twin = cp; twin_cp->monitor = cp->monitor; /* now attach all objects of the class as twins */ for( ip = (MO_INSTANCE *)SPfhead( MO_instances ); ip != NULL ; ip = next_ip ) { next_ip = (MO_INSTANCE *)SPfnext( (SPBLK *)ip ); if( ip->classdef == cp ) { /* create one for the twin. */ cl_stat = MOattach( 0, twin_cp->node.key, ip->instance, ip->idata ); if( cl_stat != OK ) break; if( next_ip->classdef != cp ) break; } } } while( FALSE ); return( cl_stat ); }
STATUS MO_mon_index(i4 msg, PTR cdata, i4 linstance, char *instance, PTR *instdata ) { STATUS ret_val = OK; MO_MON_BLOCK *mp; do /* one-time through only */ { mp = NULL; if( *instance || msg == MO_GET ) { mp = MO_igetmon( instance ); if( mp == NULL ) { ret_val = MO_NO_INSTANCE; break; } else { /* FIXME */ } } else { /* FIXME */ } switch( msg ) { case MO_GET: *instdata = (PTR)mp; break; case MO_GETNEXT: mp = (MO_MON_BLOCK *)(mp ? SPfnext( &mp->node ) : SPfhead( MO_monitors ) ); if( mp == NULL ) { ret_val = MO_NO_NEXT; } else { *instdata = (PTR)mp; ret_val = MO_mon_id_get( 0, 0, (PTR)mp, linstance, instance ); if( ret_val == MO_VALUE_TRUNCATED ) ret_val = MO_INSTANCE_TRUNCATED; } break; default: ret_val = MO_BAD_MSG; break; } } while( FALSE ); return( ret_val ); }