c_iter v_serviceTakeNewGroups( v_service service) { c_iter result; v_group group; c_set newGroups; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); result = c_iterNew(NULL); v_observerLock(v_observer(service)); newGroups = (c_set)v_observer(service)->eventData; if (newGroups != NULL) { group = v_group(c_take(newGroups)); while (group != NULL) { c_iterInsert(result, group); group = v_group(c_take(newGroups)); } } v_observerUnlock(v_observer(service)); return result; }
void v_participantInit( v_participant p, const c_char *name, v_participantQos qos, v_statistics s, c_bool enable) { v_kernel kernel; c_base base; v_message builtinMsg; c_type writerProxyType; assert(C_TYPECHECK(p,v_participant)); assert(C_TYPECHECK(qos, v_participantQos)); kernel = v_objectKernel(p); base = c_getBase(p); v_observerInit(v_observer(p),name,s,enable); p->entities = c_setNew(c_resolve(base,"kernelModule::v_entity")); p->qos = c_keep(qos); /* Currently default LIVELINESS policy is used: kind=AUTOMATIC, * duration=INFINITE This setting implies no lease registration. */ p->lease = NULL; p->leaseManager = v_leaseManagerNew(kernel); p->resendQuit = FALSE; c_mutexInit(&p->resendMutex, SHARED_MUTEX); c_condInit(&p->resendCond, &p->resendMutex, SHARED_COND); writerProxyType = v_kernelType(kernel,K_PROXY); p->resendWriters = c_tableNew(writerProxyType, "source.index,source.serial"); p->builtinSubscriber = NULL; if (!v_observableAddObserver(v_observable(kernel),v_observer(p), NULL)) { if (name != NULL) { OS_REPORT_1(OS_WARNING,"Kernel Participant",0, "%s: Cannot observe Kernel events",name); } else { OS_REPORT(OS_WARNING,"Kernel Participant",0, "Cannot observe Kernel events"); } } c_mutexInit(&p->newGroupListMutex,SHARED_MUTEX); p->newGroupList = c_listNew(c_resolve(base, "kernelModule::v_group")); v_observerSetEventMask(v_observer(p), V_EVENT_NEW_GROUP); c_lockInit(&p->lock,SHARED_LOCK); c_mutexInit(&p->builtinLock,SHARED_MUTEX); /* Here the Builtin Topic of the participant is published. * This call mabe a noop in case builtin is disabled on kernel level. */ builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_writeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); }
void v_serviceRenewLease( v_service service, v_duration leasePeriod) { assert(service != NULL); assert(C_TYPECHECK(service, v_service)); v_observerLock(v_observer(service)); v_leaseRenew(service->lease, &leasePeriod); v_observerUnlock(v_observer(service)); }
void v_collectionFree( v_collection c) { v_query q; assert(C_TYPECHECK(c,v_collection)); q = v_query(c_take(c->queries)); while (q != NULL) { /* The v_publicFree shouldn't be here, because it should be the * responsibility of the 'creator' of the query to have this * knowledge and perform the v_publicFree. The only thing that should be * required here is freeing the reference to the query by doing a * c_free. * * Because it is not exactly clear where the v_publicFree should be * performed, it is performed here for now. */ v_publicFree(v_public(q)); c_free(q); q = v_query(c_take(c->queries)); } v_observerFree(v_observer(c)); }
/************************************************************** * constructor/destructor **************************************************************/ void v_readerInit( v_reader r, const c_char *name, v_subscriber s, v_readerQos qos, v_statistics rs, c_bool enable) { v_kernel kernel; assert(r != NULL); assert(s != NULL); assert(C_TYPECHECK(r,v_reader)); assert(C_TYPECHECK(s,v_subscriber)); assert(C_TYPECHECK(qos, v_readerQos)); /* We demand the qos to be allocated in the kernel, by v_readerQosNew(). * This way we are sure that the qos is consistent! */ kernel = v_objectKernel(r); v_collectionInit(v_collection(r),name,rs,enable); r->subscriber = s; r->qos = c_keep(qos); r->subQos = c_keep(s->qos); /* reference is readonly */ r->entrySet.entries = c_setNew(v_kernelType(kernel,K_ENTRY)); c_mutexInit(&r->entrySet.mutex, SHARED_MUTEX); r->historicalDataRequest = NULL; r->historicalDataComplete = FALSE; c_condInit(&r->historicalDataCondition, &(v_observer(r)->mutex), SHARED_COND); }
void v_topicAdapterInit( v_topicAdapter adapter, v_topic topic, v_participant p, const c_char *name) { v_eventMask mask = V_EVENT_ALL_DATA_DISPOSED | V_EVENT_INCONSISTENT_TOPIC; assert(adapter != NULL); assert(p != NULL); assert(C_TYPECHECK(adapter, v_topicAdapter)); assert(C_TYPECHECK(p,v_participant)); assert(C_TYPECHECK(topic,v_topic)); v_entityInit(v_entity(adapter), name); adapter->topic = c_keep(topic); (void)v_entityEnable(v_entity(adapter)); (void)v_observerSetEvent(v_observer(adapter), mask); OSPL_ADD_OBSERVER(topic, adapter, mask, NULL); v_participantAdd(p, v_object(adapter)); v_topic(adapter)->owner = p; }
c_bool v_waitsetDetach ( v_waitset _this, v_observable o) { c_bool result; v_proxy found; findProxyArgument arg; void* userDataRemoved = NULL; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); arg.observable = v_publicHandle(v_public(o)); arg.proxy = NULL; v_waitsetLock(_this); c_setWalk(_this->observables,findProxy,&arg); if (arg.proxy != NULL) { /* proxy to the observer found */ found = c_remove(_this->observables,arg.proxy,NULL,NULL); assert(found == arg.proxy); c_free(found); } v_waitsetUnlock(_this); result = v_observableRemoveObserver(o,v_observer(_this), &userDataRemoved); v_waitsetClearRemovedObserverPendingEvents(_this, userDataRemoved); /* wakeup blocking threads to evaluate new condition. */ if (v_observerWaitCount(_this)) { v_waitsetTrigger(_this, NULL); } return result; }
c_bool v_waitsetAttach ( v_waitset _this, v_observable o, c_voidp userData) { c_bool result; v_proxy proxy; findProxyArgument arg; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); arg.observable = v_publicHandle(v_public(o)); arg.proxy = NULL; v_waitsetLock(_this); c_setWalk(_this->observables, findProxy,&arg); if (arg.proxy == NULL) { /* no proxy to the observer exists */ proxy = v_proxyNew(v_objectKernel(_this), arg.observable, userData); c_insert(_this->observables,proxy); c_free(proxy); } v_waitsetUnlock(_this); result = v_observableAddObserver(o,v_observer(_this), userData); /* wakeup blocking threads to evaluate new condition. */ if (v_observerWaitCount(_this)) { v_waitsetTrigger(_this, NULL); } return result; }
v_result v_subscriberEnable ( v_subscriber _this) { v_kernel kernel; c_iter list; c_char *partitionName; v_result result = V_RESULT_ILL_PARAM; if (_this) { kernel = v_objectKernel(_this); v_observableAddObserver(v_observable(kernel->groupSet), v_observer(_this), NULL); if (_this->qos->partition != NULL) { list = v_partitionPolicySplit(_this->qos->partition); while((partitionName = c_iterTakeFirst(list)) != NULL) { v_subscriberSubscribe(_this,partitionName); os_free(partitionName); } c_iterFree(list); } result = V_RESULT_OK; } return result; }
void v_subscriberFree( v_subscriber s) { v_kernel kernel; v_participant p; v_reader o; v_entity found; c_long sc; kernel = v_objectKernel(s); sc = (c_long)pa_decrement(&(s->shareCount)); if (sc > 0) return; if(sc == 0){ v_observableRemoveObserver(v_observable(kernel->groupSet),v_observer(s), NULL); if (s->qos->share.enable) { found = v_removeShare(kernel,v_entity(s)); assert(found == v_entity(s)); c_free(found); } while ((o = c_take(s->readers)) != NULL) { switch (v_objectKind(o)) { case K_DATAREADER: v_dataReaderFree(v_dataReader(o)); break; case K_DELIVERYSERVICE: v_deliveryServiceFree(v_deliveryService(o)); break; case K_GROUPQUEUE: v_groupQueueFree(v_groupQueue(o)); break; case K_NETWORKREADER: v_networkReaderFree(v_networkReader(o)); break; default: OS_REPORT_1(OS_ERROR, "v_subscriber", 0, "Unknown reader %d", v_objectKind(o)); assert(FALSE); break; } c_free(o); } p = v_participant(s->participant); if (p != NULL) { v_participantRemove(p,v_entity(s)); s->participant = NULL; } v_publicFree(v_public(s)); } else { OS_REPORT_1(OS_ERROR, "v_subscriberFree", 0, "subscriber already freed (shareCount is now %d).", sc); assert(sc == 0); } }
/************************************************************** * Protected functions **************************************************************/ void v_serviceNotify( v_service service, v_event event, c_voidp userData) { v_group group; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); if (event != NULL) { switch (event->kind) { case V_EVENT_SERVICESTATE_CHANGED: break; case V_EVENT_NEW_GROUP: group = v_group(event->userData); if ((group != NULL) && (v_observer(service)->eventData != NULL)) { /* Update new group admin */ c_insert((c_set)v_observer(service)->eventData, group); } /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_DELETE: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_HISTORY_REQUEST: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; case V_EVENT_CONNECT_WRITER: case V_EVENT_PERSISTENT_SNAPSHOT: /* This allows receiving the event by means of a waitset.*/ v_observableNotify(v_observable(service), event); break; default: break; } } v_participantNotify(v_participant(service), event, userData); }
void v_collectionDeinit( v_collection c) { assert(C_TYPECHECK(c,v_collection)); v_observerDeinit(v_observer(c)); c_free(c->queries); c->queries = NULL; }
void v_readerFree( v_reader r) { assert(C_TYPECHECK(r,v_reader)); if (r->subscriber != NULL) { v_subscriberRemoveReader(v_subscriber(r->subscriber),r); c_mutexLock(&(v_observer(r)->mutex)); r->subscriber = NULL; c_mutexUnlock(&(v_observer(r)->mutex)); } /* Free all entries */ v_readerWalkEntries(r, entryFree, NULL); /* Call inherited free */ v_collectionFree(v_collection(r)); }
void v_waitsetDeinit( v_waitset _this) { v_waitsetEvent event; v_observable o; v_proxy found; v_handleResult result; void* userDataRemoved = NULL; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); if (_this == NULL) { return; } v_waitsetLock(_this); found = c_take(_this->observables); while (found) { result = v_handleClaim(found->source,(v_object *)&o); if (result == V_HANDLE_OK) { v_observableRemoveObserver(o,v_observer(_this), &userDataRemoved); v_waitsetClearRemovedObserverPendingEvents(_this, userDataRemoved); result = v_handleRelease(found->source); } c_free(found); found = c_take(_this->observables); } /* wakeup blocking threads to evaluate new condition. */ /* remove all events */ while (v_waitsetEvent(v_waitsetEventList(_this)) != NULL) { event = v_waitsetEvent(v_waitsetEventList(_this)); v_waitsetEventList(_this) = event->next; event->next = NULL; c_free(event); } v_waitsetWakeup(_this, NULL, NULL); v_waitsetUnlock(_this); v_observerDeinit(v_observer(_this)); }
/************************************************************** * private functions **************************************************************/ static void v_serviceWatchSplicedaemon( v_service service) { v_kernel k; v_serviceManager m; v_serviceState splicedState; k = v_objectKernel(service); m = v_getServiceManager(k); splicedState = v_serviceManagerGetServiceState(m, V_SPLICED_NAME); v_observableAddObserver(v_observable(splicedState), v_observer(service), NULL); }
v_result v_waitsetTimedWait( v_waitset _this, v_waitsetAction action, c_voidp arg, const c_time time) { v_waitsetEvent event, eventList; v_result result; c_ulong wait_flags; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); wait_flags = 0; v_waitsetLock(_this); eventList = v_waitsetEvent(v_waitsetEventList(_this)); while ((eventList == NULL) && (!(wait_flags & (V_EVENT_OBJECT_DESTROYED | V_EVENT_TIMEOUT)))) { wait_flags = v__observerTimedWait(v_observer(_this),time); eventList = v_waitsetEvent(v_waitsetEventList(_this)); } v__observerClearEventFlags(_this); v_waitsetEventList(_this) = NULL; if (action) { v_waitsetUnlock(_this); event = eventList; while (event) { action(event, arg); event = event->next; } v_waitsetLock(_this); } while (eventList) { event = eventList; eventList = eventList->next; event->next = NULL; /* otherwise entire list is freed! */ v_waitsetEventFree(_this,event); /* free whole list. */ } v_waitsetUnlock(_this); if (wait_flags & V_EVENT_OBJECT_DESTROYED) { result = V_RESULT_DETACHING; } else if (wait_flags & V_EVENT_TIMEOUT) { result = V_RESULT_TIMEOUT; } else { result = V_RESULT_OK; } return result; }
v_waitset v_waitsetNew( v_participant p) { v_waitset _this; v_kernel kernel; c_type proxyType; assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); _this = v_waitset(v_objectNew(kernel,K_WAITSET)); if (_this != NULL) { v_observerInit(v_observer(_this),"Waitset", NULL, TRUE); _this->participant = p; _this->eventCache = NULL; proxyType = v_kernelType(kernel,K_PROXY); _this->observables = c_setNew(proxyType); v_observerSetEventData(v_observer(_this), NULL); v_participantAdd(p, v_entity(_this)); } return _this; }
void v_groupStreamConnectNewGroups( v_groupStream stream, v_group group) { struct groupConnected data; assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); v_observerLock(v_observer(stream)); /* * This means the group is interesting for this * groupActionStream. Now I have to check if the stream is already * connected to this group, because we wouldn't want to connect * multiple times to one single group. */ data.connected = FALSE; data.group = group; c_walk(stream->groups, (c_action)isGroupConnected, &data); if(data.connected == FALSE){ /* * The stream is not connected to the group yet, so connect now. */ v_groupStreamSubscribeGroup(stream, group); } v_observerUnlock(v_observer(stream)); if(data.connected == FALSE){ v_groupStreamHistoricalData(group, stream); } return; }
/************************************************************** * Protected functions **************************************************************/ void v_collectionInit( v_collection c, const c_char *name, v_statistics s, c_bool enable) { c_base base; assert(C_TYPECHECK(c,v_collection)); v_observerInit(v_observer(c), name, s, enable); base = c_getBase(c_object(c)); c->queries = c_setNew(c_resolve(base,"kernelModule::v_query")); }
static void cmx_participantInitDetach( v_public entity, c_voidp args) { v_kernel k; v_serviceManager m; v_serviceState splicedState; OS_UNUSED_ARG(args); k = v_objectKernel(entity); m = v_getServiceManager(k); splicedState = v_serviceManagerGetServiceState(m, V_SPLICED_NAME); v_observableAddObserver(v_observable(splicedState), v_observer(entity), V_EVENTMASK_ALL, NULL); }
void v_serviceDeinit( v_service service) { v_kernel kernel; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); c_free(service->state); service->state = NULL; c_free((c_object)v_observer(service)->eventData); kernel = v_objectKernel(service); v_leaseManagerDeregister(kernel->livelinessLM, service->lease); c_free(service->lease); service->lease = NULL; v_participantDeinit(v_participant(service)); }
void v_participantDeinit( v_participant p) { v_kernel kernel; assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); v_leaseManagerDeregister(kernel->livelinessLM, p->lease); c_free(p->lease); p->lease = NULL; v_leaseManagerFree(p->leaseManager); p->leaseManager = NULL; v_observerDeinit(v_observer(p)); }
void v_waitsetFree( v_waitset _this) { v_kernel kernel; v_participant p; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); kernel = v_objectKernel(_this); p = v_participant(_this->participant); if (p != NULL) { v_participantRemove(p, v_entity(_this)); _this->participant = NULL; } v_observerFree(v_observer(_this)); }
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); } }
void cmx_readerSnapshotNewAction( v_entity e, c_voidp args) { v_dataReader reader; c_iter instances; v_dataReaderInstance instance; v_dataReaderSample sample, prev; v_query query; c_bool release; sd_serializer ser; sd_serializedData data; struct cmx_readerSnapshotArg* arg; release = FALSE; arg = (struct cmx_readerSnapshotArg*)args; reader = NULL; instances = NULL; ser = NULL; switch(v_object(e)->kind){ case K_DATAREADER: reader = v_dataReader(e); arg->success = TRUE; arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot))); v_observerLock(v_observer(reader)); if(reader->index->objects){ instances = c_select(reader->index->notEmptyList, 0); } break; case K_QUERY: case K_DATAREADERQUERY: query = v_query(e); reader = v_dataReader(v_querySource(query)); if(reader != NULL){ release = TRUE; arg->success = TRUE; arg->snapshot = cmx_readerSnapshot(os_malloc(C_SIZEOF(cmx_readerSnapshot))); v_observerLock(v_observer(reader)); switch(v_object(query)->kind){ case K_DATAREADERQUERY: if(v_dataReaderQuery(query)->instanceQ){ instances = c_select((c_collection)(v_dataReaderQuery(query)->instanceQ), 0); } break; default: OS_REPORT_1(OS_ERROR, CM_XML_CONTEXT, 0, "cmx_readerSnapshotNewAction unknown kind (%d).", v_object(query)->kind); break; } } break; default: break; } if(arg->success == TRUE){ arg->snapshot->samples = c_iterNew(NULL); } if(instances != NULL){ instance = v_dataReaderInstance(c_iterTakeFirst(instances)); while(instance != NULL){ sample = c_keep(v_dataReaderInstanceHead(instance)); if(sample != NULL){ prev = sample->prev; sample->prev = NULL; if(ser == NULL){ ser = sd_serializerXMLNewTyped(c_getType(c_object(sample))); } data = sd_serializerSerialize(ser, c_object(sample)); arg->snapshot->samples = c_iterInsert(arg->snapshot->samples, sd_serializerToString(ser, data)); sd_serializedDataFree(data); sample->prev = prev; c_free(sample); } c_free(instance); instance = v_dataReaderInstance(c_iterTakeFirst(instances)); } c_iterFree(instances); } if(reader != NULL){ v_observerUnlock(v_observer(reader)); if(release == TRUE){ c_free(reader); } } if(ser != NULL){ sd_serializerFree(ser); } }
void cmx_readerDataTypeAction( v_entity entity, c_voidp args) { sd_serializer ser; sd_serializedData data; c_type type; v_dataReader r; v_query query; v_topic topic; struct cmx_readerArg *arg; arg = (struct cmx_readerArg *)args; type = NULL; switch(v_object(entity)->kind){ case K_DATAREADER: r = v_dataReader(entity); v_observerLock(v_observer(r)); topic = v_dataReaderGetTopic(r); type = v_topicDataType(topic); c_free(topic); v_observerUnlock(v_observer(r)); break; case K_DATAREADERQUERY: query = v_query(entity); r = v_dataReader(v_querySource(query)); v_observerLock(v_observer(r)); topic = v_dataReaderGetTopic(r); type = v_topicDataType(topic); c_free(topic); v_observerUnlock(v_observer(r)); c_free(r); break; case K_NETWORKREADER: OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0, "Resolving data type of networkReader unsupported.\n"); assert(FALSE); break; case K_GROUPQUEUE: OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0, "Resolving data type of groupQueue unsupported.\n"); assert(FALSE); break; default: OS_REPORT(OS_ERROR, CM_XML_CONTEXT, 0, "Trying to resolve dataType of unknown reader type.\n"); assert(FALSE); break; } if(type != NULL){ ser = sd_serializerXMLMetadataNew(c_getBase(type)); data = sd_serializerSerialize(ser, type); arg->result = sd_serializerToString(ser, data); sd_serializedDataFree(data); sd_serializerFree(ser); } }
void v_subscriberDeinit( v_subscriber s) { v_observerDeinit(v_observer(s)); }
void v_groupStreamNotify( v_groupStream stream, v_event e, c_voidp userData) { struct groupConnected data; c_iter partitions; c_bool interested; v_partition partition, found; OS_UNUSED_ARG(userData); assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); if (e) { if (e->kind == V_EVENT_NEW_GROUP) { v_observerLock(v_observer(stream)); /* * 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. */ partition = v_group(e->userData)->partition; /* * 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. */ partitions = v_subscriberLookupPartitions(v_reader(stream)->subscriber, v_partitionName(partition)); interested = FALSE; found = v_partition(c_iterTakeFirst(partitions)); while(found){ if(interested == FALSE){ if(strcmp(v_partitionName(partition), v_partitionName(found)) == 0){ interested = TRUE; } } c_free(found); found = v_partition(c_iterTakeFirst(partitions)); } c_iterFree(partitions); if(interested == TRUE){ /* * This means the group is interesting for this * groupActionStream. Now I have to check if the stream is already * connected to this group, because we wouldn't want to connect * multiple times to one single group. */ data.connected = FALSE; data.group = v_group(e->userData); c_walk(stream->groups, (c_action)isGroupConnected, &data); if(data.connected == FALSE){ /* * The stream is not connected to the group yet, so connect now. */ v_groupStreamSubscribeGroup(stream, v_group(e->userData)); } } v_observerUnlock(v_observer(stream)); } } return; }
v_subscriber v_subscriberNew( v_participant p, const c_char *name, v_subscriberQos qos, c_bool enable) { v_kernel kernel; v_subscriber s; v_subscriberQos q; v_entity found; v_accessMode access; kernel = v_objectKernel(p); /* ES, dds1576: If a partition policy was provided then we need to verify * if the partition policy does not contain any partition expressions for * which read access is not allowed. * If read access is not allowed for one of the partitions listed in the * partition policy of the qos, then the subscriber will not be created at * all. */ if(qos && qos->partition) { access = v_kernelPartitionAccessMode(kernel, qos->partition); } else { access = V_ACCESS_MODE_READ_WRITE;/* default */ } if(access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_READ) { q = v_subscriberQosNew(kernel,qos); if (q != NULL) { s = v_subscriber(v_objectNew(kernel,K_SUBSCRIBER)); v_observerInit(v_observer(s),name, NULL, enable); s->qos = q; c_mutexInit(&s->sharesMutex, SHARED_MUTEX); if (q->share.enable) { v_lockShares(kernel); found = v_addShareUnsafe(kernel,v_entity(s)); if (found != v_entity(s)) { /* Make sure to set the partition list to NULL, because * v_publicFree will cause a crash in the v_subscriberDeinit * otherwise. */ s->partitions = NULL; /*v_publicFree to free reference held by the handle server.*/ v_publicFree(v_public(s)); /*Now free the local reference as well.*/ c_free(s); pa_increment(&(v_subscriber(found)->shareCount)); v_unlockShares(kernel); return c_keep(found); } s->shares = c_tableNew(v_kernelType(kernel,K_READER), "qos.share.name"); } else { s->shares = NULL; } s->shareCount = 1; s->partitions = v_partitionAdminNew(kernel); s->readers = c_setNew(v_kernelType(kernel,K_READER)); if (q->share.enable) { s->participant = kernel->builtin->participant; } else { s->participant = p; } c_lockInit(&s->lock,SHARED_LOCK); v_participantAdd(v_participant(s->participant),v_entity(s)); if (q->share.enable) { v_unlockShares(kernel); } if (enable) { v_subscriberEnable(s); } } else { OS_REPORT(OS_ERROR, "v_subscriberNew", 0, "Subscriber not created: inconsistent qos"); s = NULL; } } else { OS_REPORT(OS_ERROR, "v_subscriberNew", 0, "Subscriber not created: Access rights for one of the partitions listed in the partition list was not sufficient (i.e. read or readwrite)."); s = NULL; } return s; }
void v_participantFree( v_participant p) { v_message builtinMsg; v_participant found; v_entity e; v_kernel kernel; /* Not clear yet why builtin subscriber lock and participant lock are not taken now? * Also not clear why observer lock is not taken but is freed at the end! */ if (p != NULL) { assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); if (!v_observableRemoveObserver(v_observable(kernel),v_observer(p), NULL)) { if (v_participantName(p) != NULL) { OS_REPORT_1(OS_WARNING,"v_participantFree",0, "Participant '%s' cannot disconnect from Kernel events", v_participantName(p)); } else { OS_REPORT(OS_WARNING,"v_participantFree",0, "Participant cannot disconnect from Kernel events"); } } builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_writeDisposeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_unregisterBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); c_free(builtinMsg); if (p->builtinSubscriber) { v_subscriberFree(p->builtinSubscriber); p->builtinSubscriber = NULL; } while ((e = c_take(p->entities)) != NULL) { switch (v_objectKind(e)) { case K_PUBLISHER: v_publisherFree(v_publisher(e)); break; case K_SUBSCRIBER: v_subscriberFree(v_subscriber(e)); break; case K_WAITSET: v_waitsetFree(v_waitset(e)); break; default: OS_REPORT_1(OS_WARNING,"Kernel Participant",0, "Illegal contained object (%s)", v_participantName(p)); break; } c_free(e); /* deref o since c_take will not */ } found = v_removeParticipant(kernel,p); assert(found == p); c_free(found); v_observerFree(v_observer(p)); } }