void v_subscriberRemoveReader( 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); found = c_remove(s->readers,r,NULL,NULL); v_partitionAdminWalk(s->partitions,collectPartitions,iter); while ((d = c_iterTakeFirst(iter)) != NULL) { /* ES, dds1576: The unsubscribe here is performed for all partitions, * however for the K_DATAREADER class not all partitions were * actually subscribed too. Instead of verifying if a partition was * subscribed too or not, the unsubscribe is just executed every time * as this is 'cheaper' then performing the access check again. * If a partition was not subscribed too then the unsubcribe will have no * effect. */ v_readerUnSubscribe(r,d); c_free(d); } c_lockUnlock(&s->lock); c_iterFree(iter); c_free(found); }
v_result v_participantSetQos( v_participant p, v_participantQos qos) { v_message builtinMsg; v_kernel kernel; v_qosChangeMask cm; v_result result; assert(C_TYPECHECK(p,v_participant)); /* Do not use C_TYPECHECK on qos parameter, since it might be allocated on heap! */ kernel = v_objectKernel(p); c_lockWrite(&p->lock); result = v_participantQosSet(p->qos, qos, &cm); if ((result == V_RESULT_OK) && (cm != 0)) { builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); c_lockUnlock(&p->lock); v_writeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); } else { c_lockUnlock(&p->lock); } return result; }
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_partition v_addPartition( v_kernel kernel, v_partition partition) { v_partition found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(partition != NULL); assert(C_TYPECHECK(partition,v_partition)); c_lockWrite(&kernel->lock); found = c_insert(kernel->partitions,partition); c_lockUnlock(&kernel->lock); if (found != partition) { assert(v_objectKind(found) == K_DOMAIN); if (v_objectKind(found) != K_DOMAIN) { partition = NULL; } else { partition = found; } } return partition; }
void v_subscriberUnSubscribe( v_subscriber s, const c_char *partitionExpr) { v_partition d; v_dataReaderConnectionChanges arg; v_partitionPolicy old; assert(s != NULL); assert(C_TYPECHECK(s,v_subscriber)); arg.addedPartitions = NULL; c_lockWrite(&s->lock); arg.removedPartitions = v_partitionAdminRemove(s->partitions, partitionExpr); old = s->qos->partition; s->qos->partition = v_partitionPolicyRemove(old, partitionExpr, c_getBase(c_object(s))); c_free(old); c_setWalk(s->readers, qosChangedAction, &arg); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); } c_iterFree(arg.removedPartitions); c_lockUnlock(&s->lock); }
void v_participantRenewLease( v_participant p, v_duration leasePeriod) { assert(p != NULL); assert(C_TYPECHECK(p, v_participant)); c_lockWrite(&p->lock); v_leaseRenew(p->lease, leasePeriod); c_lockUnlock(&p->lock); }
void v_enableStatistics( v_kernel k, const char *categoryName) { v_statisticsCategory category; c_lockWrite(&k->lock); /* Only add this if it is not yet enabled */ if (!isEnabledStatisticsUnlocked(k, categoryName)) { category = v_statisticsCategoryNew(k, categoryName); c_append(k->enabledStatisticsCategories, category); } c_lockUnlock(&k->lock); }
void v_participantNotify( v_participant _this, v_event event, c_voidp userData) { /* This Notify method is part of the observer-observable pattern. * It is designed to be invoked when _this object as observer receives * an event from an observable object. * It must be possible to pass the event to the subclass of itself by * calling <subclass>Notify(_this, event, userData). * This implies that _this as observer cannot be locked within any * Notify method to avoid deadlocks. * For consistency _this must be locked by v_observerLock(_this) before * calling this method. */ assert(_this != NULL); assert(C_TYPECHECK(_this,v_participant)); if (event) { switch (event->kind) { case V_EVENT_NEW_GROUP: assert(event->userData); c_mutexLock(&_this->newGroupListMutex); c_listInsert(_this->newGroupList,v_group(event->userData)); c_mutexUnlock(&_this->newGroupListMutex); break; case V_EVENT_LIVELINESS_ASSERT: c_lockWrite(&_this->lock); c_walk(_this->entities, assertLivelinessPublisher, event); c_lockUnlock(&_this->lock); break; case V_EVENT_SERVICESTATE_CHANGED: case V_EVENT_DATA_AVAILABLE: case V_EVENT_HISTORY_DELETE: case V_EVENT_HISTORY_REQUEST: case V_EVENT_PERSISTENT_SNAPSHOT: /*Do nothing here.*/ break; default: OS_REPORT_1(OS_WARNING,"v_participantNotify",0, "Notify encountered unknown event kind (%d)", event->kind); break; } } }
void v_participantAssertLiveliness( v_participant p) { C_STRUCT(v_event) event; assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); event.kind = V_EVENT_LIVELINESS_ASSERT; event.source = v_publicHandle(v_public(p)); event.userData = NULL; /* Walk over all entities and assert liveliness on all writers */ c_lockWrite(&p->lock); c_walk(p->entities, assertLivelinessPublisher, &event); c_lockUnlock(&p->lock); }
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_participantRemove( 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_remove(p->entities,e,NULL,NULL); c_lockUnlock(&p->lock); c_free(found); }
v_participant v_removeParticipant( v_kernel kernel, v_participant p) { v_participant found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); c_lockWrite(&kernel->lock); found = c_remove(kernel->participants,p,NULL,NULL); c_lockUnlock(&kernel->lock); return found; }
void v_participantConnectNewGroup ( v_participant _this, v_event event) { v_group g; c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); while (g) { c_mutexUnlock(&_this->newGroupListMutex); c_lockWrite(&_this->lock); c_walk(_this->entities, connectNewGroup, g); c_lockUnlock(&_this->lock); c_mutexLock(&_this->newGroupListMutex); g = c_take(_this->newGroupList); } c_mutexUnlock(&_this->newGroupListMutex); }
void v_subscriberConnectNewGroup( v_subscriber s, v_group g) { c_bool connect; c_iter addedPartitions; v_partition d; c_lockWrite(&s->lock); connect = v_partitionAdminFitsInterest(s->partitions, g->partition); if (connect) { addedPartitions = v_partitionAdminAdd(s->partitions, v_partitionName(g->partition)); d = v_partition(c_iterTakeFirst(addedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(addedPartitions)); } c_iterFree(addedPartitions); c_setWalk(s->readers, (c_action)v_readerSubscribeGroup, g); } else { /* * Check if group fits interest. This extra steps are needed because * the groupActionStream does not create the groups that match the * subscriber qos partition expression on creation. It only needs to * connect to new groups once they are created. This is a different * approach then for a data reader. */ /* * Because already existing partitions are created and added to the * subscriber of the groupActionStream at creation time, these * partitions can be resolved from the subscriber. This is necessary to * determine whether the groupActionStream should connect to the new * group or if it is already connected. */ if (v_partitionAdminExists(s->partitions, v_partitionName(g->partition))) { c_setWalk(s->readers, (c_action)notifyGroupQueues, g); } } c_lockUnlock(&s->lock); }
v_partition v_removePartition( v_kernel kernel, v_partition partition) { v_partition found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(partition != NULL); assert(C_TYPECHECK(partition,v_partition)); c_lockWrite(&kernel->lock); found = c_remove(kernel->partitions,partition,NULL,NULL); c_lockUnlock(&kernel->lock); if (found == NULL) { return NULL; } if (v_objectKind(found) != K_DOMAIN) { return NULL; } return found; }
v_topic v_removeTopic( v_kernel kernel, v_topic topic) { v_topic found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(topic != NULL); assert(C_TYPECHECK(topic,v_topic)); c_lockWrite(&kernel->lock); found = c_remove(kernel->topics,topic,NULL,NULL); c_lockUnlock(&kernel->lock); if (found == NULL) { return NULL; } if (v_objectKind(found) != K_TOPIC) { return NULL; } return found; }
v_topic v__addTopic( v_kernel kernel, v_topic topic) { v_topic found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(topic != NULL); assert(C_TYPECHECK(topic,v_topic)); c_lockWrite(&kernel->lock); found = c_insert(kernel->topics,topic); c_lockUnlock(&kernel->lock); if (found != topic) { if (v_objectKind(found) != K_TOPIC) { return NULL; } topic = found; } return topic; }
/************************************************************** * Public functions **************************************************************/ c_bool v_serviceStateChangeState( v_serviceState serviceState, v_serviceStateKind stateKind) { c_bool changed; C_STRUCT(v_event) event; assert(C_TYPECHECK(serviceState, v_serviceState)); c_lockWrite(&serviceState->lock); switch (stateKind) { case STATE_NONE: break; case STATE_DIED: if ((serviceState->stateKind != STATE_NONE) && (serviceState->stateKind != STATE_TERMINATED)) { serviceState->stateKind = stateKind; } break; case STATE_INITIALISING: if ((serviceState->stateKind == STATE_NONE) || (serviceState->stateKind == STATE_DIED)) { serviceState->stateKind = stateKind; } break; case STATE_OPERATIONAL: if (serviceState->stateKind == STATE_INITIALISING) { serviceState->stateKind = stateKind; } break; case STATE_INCOMPATIBLE_CONFIGURATION: if ((serviceState->stateKind == STATE_OPERATIONAL) || (serviceState->stateKind == STATE_INITIALISING)) { serviceState->stateKind = stateKind; } break; case STATE_TERMINATING: if ((serviceState->stateKind == STATE_INITIALISING) || (serviceState->stateKind == STATE_OPERATIONAL)) { serviceState->stateKind = stateKind; } break; case STATE_TERMINATED: if (serviceState->stateKind == STATE_TERMINATING) { serviceState->stateKind = stateKind; } break; default: OS_REPORT_1(OS_ERROR,"Kernel::ServiceState",0, "Unkown state (%d) kind provided.",stateKind); assert(FALSE); /* unknown state */ break; } if (serviceState->stateKind == stateKind) { changed = TRUE; } else { changed = FALSE; } c_lockUnlock(&serviceState->lock); event.kind = V_EVENT_SERVICESTATE_CHANGED; event.source = v_publicHandle(v_public(serviceState)); event.userData = NULL; v_observableNotify(v_observable(serviceState),&event); return changed; }
v_result v_subscriberSetQos( v_subscriber s, v_subscriberQos qos) { v_result result; v_qosChangeMask cm; v_dataReaderConnectionChanges arg; v_partition d; v_accessMode access; assert(s != NULL); arg.addedPartitions = NULL; arg.removedPartitions = NULL; c_lockWrite(&s->lock); /* ES, dds1576: When the QoS is being set we have to verify that the partitions * listed in the qos do not have an invalid access mode set. For a subscriber * an invalid mode is characterized as 'write' mode. If the partitionAccess * check returns ok, then everything continue as normal. If the * partitionAccess check returns something else, then the setQos operation * is aborted. Please see the partitionAccess check operation to know when * a partition expression is not allowed. */ if(qos && qos->partition) { access = v_kernelPartitionAccessMode(v_objectKernel(s), qos->partition); } else { access = V_ACCESS_MODE_READ_WRITE;/* default */ } if(access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_READ) { result = v_subscriberQosSet(s->qos, qos, v_entity(s)->enabled, &cm); if ((result == V_RESULT_OK) && (cm != 0)) { c_lockUnlock(&s->lock); /* since creation builtin topic might lock subscriber again. */ if (cm & V_POLICY_BIT_PARTITION) { /* partition policy has changed! */ v_partitionAdminSet(s->partitions, s->qos->partition, &arg.addedPartitions, &arg.removedPartitions); } c_setWalk(s->readers, qosChangedAction, &arg); d = v_partition(c_iterTakeFirst(arg.addedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.addedPartitions)); } c_iterFree(arg.addedPartitions); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); while (d != NULL) { c_free(d); d = v_partition(c_iterTakeFirst(arg.removedPartitions)); } c_iterFree(arg.removedPartitions); } else { c_lockUnlock(&s->lock); } } else { result = V_RESULT_PRECONDITION_NOT_MET; c_lockUnlock(&s->lock); } return result; }