c_bool v_leaseAddObserverNoLock( v_lease _this, v_leaseManager observer) { c_bool added; v_leaseManager found; assert(_this != NULL); assert(C_TYPECHECK(_this, v_lease)); assert(observer != NULL); assert(C_TYPECHECK(observer, v_leaseManager)); if(_this->observers) { found = c_setInsert(_this->observers, observer); if (found == observer) { added = TRUE; } else { added = FALSE; } } else { added = FALSE; } return added; }
void v_subscriberAddReader( v_subscriber s, v_reader r) { v_reader found; v_partition d; c_iter iter; assert(s != NULL); assert(r != NULL); iter = c_iterNew(NULL); c_lockWrite(&s->lock); v_partitionAdminWalk(s->partitions,collectPartitions,iter); while ((d = c_iterTakeFirst(iter)) != NULL) { v_readerSubscribe(r,d); c_free(d); } found = c_setInsert(s->readers,r); c_lockUnlock(&s->lock); if (found != r) { OS_REPORT_1(OS_ERROR, "v_subscriberAddReader", 0, "shared <%s> name already defined", r->qos->share.name); } c_iterFree(iter); }
v_entry v_readerAddEntry( v_reader r, v_entry e) { v_entry found; assert(C_TYPECHECK(r,v_reader)); assert(C_TYPECHECK(e,v_entry)); v_readerEntrySetLock(r); found = c_setInsert(r->entrySet.entries, e); v_readerEntrySetUnlock(r); return c_keep(found); }
void v_participantAdd( v_participant p, v_entity e) { v_entity found; assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); assert(e != NULL); assert(C_TYPECHECK(e,v_entity)); c_lockWrite(&p->lock); found = c_setInsert(p->entities,e); c_lockUnlock(&p->lock); assert(found == e); }
void v_serviceFillNewGroups( v_service service) { c_set newGroups; C_STRUCT(v_event) ge; v_group g, oldGroup; c_iter oldGroups; v_kernel kernel; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); kernel = v_objectKernel(service); newGroups = (c_voidp)c_setNew(v_kernelType(kernel, K_GROUP)); if (newGroups != NULL) { addAllGroups(newGroups, kernel->groupSet); v_observerLock(v_observer(service)); g = v_group(c_read(newGroups)); /* need a group for the event */ if(v_observer(service)->eventData != NULL){ oldGroups = ospl_c_select((c_set)v_observer(service)->eventData, 0); oldGroup = v_group(c_iterTakeFirst(oldGroups)); while(oldGroup){ newGroups = c_setInsert(newGroups, oldGroup); c_free(oldGroup); oldGroup = v_group(c_iterTakeFirst(oldGroups)); } c_iterFree(oldGroups); } /* just for safety, when assertion are compiled out, free the prev set */ c_free((c_object)v_observer(service)->eventData); v_observer(service)->eventData = (c_voidp)newGroups; ge.kind = V_EVENT_NEW_GROUP; ge.source = v_publicHandle(v_public(kernel)); ge.userData = g; v_observerNotify(v_observer(service), &ge, NULL); v_observerUnlock(v_observer(service)); c_free(g); } }
/************************************************************** * register/deregister of leases **************************************************************/ v_result v_leaseManagerRegister( v_leaseManager _this, v_lease lease, v_leaseActionId actionId, v_public actionObject, c_bool repeatLease) { c_bool obsAdded; v_leaseAction leaseAction; v_leaseAction found; v_result result; v_kernel k; assert(_this != NULL); assert(C_TYPECHECK(_this, v_leaseManager)); assert(lease != NULL); assert(C_TYPECHECK(lease, v_lease)); assert(actionObject != NULL); assert(C_TYPECHECK(actionObject, v_public)); /* Step 1: Create a lease action object. This object will contain the relevant * information needed when reacting to an expired lease. This action information * can be different depending on which lease manager a lease is being registered * to, hence why the leaseAction object resides at leaseManager level and not * at lease level as it did in the past */ k = v_objectKernel(_this); leaseAction = v_leaseAction(v_objectNew(k, K_LEASEACTION)); if(!leaseAction) { OS_REPORT(OS_ERROR, "v_leaseManager", 0, "Failed to create a v_leaseManager object. " "Most likely not enough shared memory available to " "complete the operation."); result = V_RESULT_OUT_OF_MEMORY; } else { leaseAction->lease = v_lease(c_keep(lease)); assert(leaseAction->lease); leaseAction->actionId = actionId; leaseAction->actionObject = v_publicHandle(actionObject); leaseAction->repeat = repeatLease; /* Step 2: insert the leaseAction object into the set of leases. */ c_mutexLock(&_this->mutex); found = c_setInsert(_this->leases, leaseAction); if(!found) { /* Because the leaseAction object was just allocated we only have * to check if found is a NULL pointer. As it can never find the * action already being present in the set. */ OS_REPORT(OS_ERROR, "v_leaseManager", 0, "Unable to register the lease to the list of " "leases of the leaseManager object! Most likely not enough shared " "memory available to complete the operation."); result = V_RESULT_OUT_OF_MEMORY; c_free(leaseAction); leaseAction = NULL; } else { assert(found == leaseAction); /* Step 3: Determine if the newly inserted leaseAction will become the * 'next lease to expire'. E.G., if the lease contained within the * leaseAction object has an expiry time that is the closest to the * present time compared to the other leases managed within this lease * manager. To prevent the lease time from changing while we evaluate the * lease we will lock the lease object. */ v_leaseLock(lease); if(!_this->firstLeaseToExpire) { _this->firstLeaseToExpire = c_keep(leaseAction); /* head changed, so signal */ c_condBroadcast(&_this->cond); } else if ((_this->firstLeaseToExpire->lease != lease) && (c_timeCompare(v_leaseExpiryTime(_this->firstLeaseToExpire->lease), v_leaseExpiryTimeNoLock(lease)) == C_GT)) { c_free(_this->firstLeaseToExpire); _this->firstLeaseToExpire = c_keep(leaseAction); /* head changed, so signal */ c_condBroadcast(&_this->cond); }/* else do nothing as the newly added lease expires after the firstLeaseToExpire */ /* Step 4: Now that the lease was successfully inserted into the lease manager, * we need to register the leaseManager as an observer of the lease to ensure that the * lease manager is notified if the lease expiry time and/or duration changes. */ obsAdded = v_leaseAddObserverNoLock(lease, _this); if(!obsAdded) { OS_REPORT(OS_ERROR, "v_leaseManager", 0, "Unable to register the lease manager to the list of " "observers of the lease object! Possibly not enough " "shared memory available to complete the operation."); result = V_RESULT_INTERNAL_ERROR; v_leaseUnlock(lease); /* Remove the lease from the leaseManager */ found = c_setRemove(_this->leases, leaseAction, NULL, NULL); if(found != leaseAction) { OS_REPORT(OS_ERROR, "v_leaseManager", 0, "Unable to unregister the lease to the list of " "leases of the leaseManager object after previous internal error!"); } c_free(leaseAction); leaseAction = NULL; } else { /* Now that the lease manager is in the observer list of the lease, we can unlock the lease * as from now on we will be notified of any changes to the lease expiry time and/or duration */ v_leaseUnlock(lease); result = V_RESULT_OK; } } c_mutexUnlock(&_this->mutex); } if(leaseAction) { /* Done with the leaseAction object in this operation. If the object is not a NULL * pointer then everything went ok. The leases set of the leaseManager should be * the only one maintaining a ref count now (and possibly the 'firstLeaseToExpire' * attribute. But we do not need the leaseAction object in this operation anymore * and we are not returning it, so we need to lower the ref count for the new operation */ c_free(leaseAction); }/* else do nothing */ return result; }