c_iter v_partitionLookupSubscribers( v_partition partition) { c_iter participants; c_iter result; c_iter entities; c_iter partitions; v_participant participant; v_entity entity; v_entity partition2; result = NULL; participants = v_resolveParticipants(v_objectKernel(partition), "*"); participant = v_participant(c_iterTakeFirst(participants)); while (participant != NULL) { c_lockRead(&participant->lock); entities = c_select(participant->entities, 0); c_lockUnlock(&participant->lock); entity = v_entity(c_iterTakeFirst(entities)); while (entity != NULL) { if(v_objectKind(entity) == K_SUBSCRIBER) { partitions = v_subscriberLookupPartitions(v_subscriber(entity), v_partitionName(partition)); if (c_iterLength(partitions) > 0) { result = c_iterInsert(result, entity); /* transfer refcount */ } else { c_free(entity); } partition2 = v_entity(c_iterTakeFirst(partitions)); while (partition2 != NULL) { c_free(partition2); partition2 = v_entity(c_iterTakeFirst(partitions)); } c_iterFree(partitions); } /* entity is already free or refcount transferred to result */ entity = v_entity(c_iterTakeFirst(entities)); } c_iterFree(entities); c_free(participant); participant = v_participant(c_iterTakeFirst(participants)); } c_iterFree(participants); return result; }
v_cmsoap v_cmsoapNew( v_serviceManager manager, const c_char *name, const c_char *extStateName, v_participantQos qos) { v_kernel k; v_cmsoap s; v_participantQos q; assert(C_TYPECHECK(manager, v_serviceManager)); assert(name != NULL); k = v_objectKernel(manager); q = v_participantQosNew(k, qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_cmsoapNew", 0, "CMSoap service not created: inconsistent qos"); s = NULL; } else { s = v_cmsoap(v_objectNew(k, K_CMSOAP)); v_serviceInit(v_service(s), manager, name, extStateName, q, v_statistics(v_cmsoapStatisticsNew(k))); c_free(q); /* always add, even when s->state==NULL, since v_participantFree always removes the participant.*/ v_addParticipant(k, v_participant(s)); if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; } } return s; }
u_result u_readerGetMatchedPublications ( u_reader _this, v_statusAction action, c_voidp arg) { v_dataReader reader; v_spliced spliced; v_kernel kernel; u_result result; c_iter participants; v_participant participant; result = U_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { result = u_entityReadClaim(u_entity(_this), (v_entity*)(&reader)); if ((result == U_RESULT_OK) && (reader != NULL)) { kernel = v_objectKernel(reader); participants = v_resolveParticipants(kernel, V_SPLICED_NAME); assert(c_iterLength(participants) == 1); participant = v_participant(c_iterTakeFirst(participants)); spliced = v_spliced(participant); c_free(participant); c_iterFree(participants); result = u_resultFromKernel( v_splicedGetMatchedPublications(spliced, v_dataReader(reader), action, arg)); u_entityRelease(u_entity(_this)); } } return result; }
v_participant v_participantNew( v_kernel kernel, const c_char *name, v_qos qos, v_statistics s, c_bool enable) { v_participant p; v_participantQos q; assert(C_TYPECHECK(kernel,v_kernel)); /* Do not use C_TYPECHECK on qos parameter, * since it might be allocated on heap! */ /* do no use cast method on qos parameter, * it is most likely allocated on heap! */ q = v_participantQosNew(kernel, (v_participantQos)qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_participantNew", 0, "Participant not created: inconsistent qos"); p = NULL; } else { p = v_participant(v_objectNew(kernel,K_PARTICIPANT)); v_participantInit(p,name,q,s,enable); c_free(q); v_addParticipant(kernel,p); } return p; }
void v_publicDispose( v_public o) { assert(C_TYPECHECK(o,v_public)); if (o == NULL) { return; } switch(v_objectKind(o)) { case K_PARTICIPANT: v_participantDeinit(v_participant(o)); break; case K_PUBLISHER: v_publisherDeinit(v_publisher(o)); break; case K_SUBSCRIBER: v_subscriberDeinit(v_subscriber(o)); break; case K_WRITER: v_writerDeinit(v_writer(o)); break; case K_DATAREADER: v_dataReaderDeinit(v_dataReader(o)); break; case K_DELIVERYSERVICE:v_deliveryServiceDeinit(v_deliveryService(o)); break; case K_NETWORKREADER: v_networkReaderDeinit(v_networkReader(o)); break; case K_READER: v_readerDeinit(v_reader(o)); break; case K_GROUPQUEUE: v_groupQueueDeinit(v_groupQueue(o)); break; case K_TOPIC: v_topicDeinit(v_topic(o)); break; case K_ENTITY: break; case K_DOMAIN: v_partitionDeinit(v_partition(o)); break; case K_GROUP: v_groupDeinit(v_group(o)); break; case K_SERVICEMANAGER: /* Is never freed! */ break; case K_SPLICED: v_splicedDeinit(v_spliced(o)); break; case K_NETWORKING: case K_DURABILITY: case K_CMSOAP: case K_SERVICE: v_serviceDeinit(v_service(o)); break; case K_SERVICESTATE: /* Is never freed! */ break; case K_CONFIGURATION: break; case K_QUERY: OS_REPORT(OS_ERROR, "v_publicDispose failure", 0, "deinit of abstract class K_QUERY"); break; case K_DATAREADERQUERY: v_dataReaderQueryDeinit(v_dataReaderQuery(o)); break; case K_DATAVIEWQUERY: v_dataViewQueryDeinit(v_dataViewQuery(o)); break; case K_DATAVIEW: v_dataViewDeinit(v_dataView(o)); break; case K_WAITSET: v_waitsetDeinit(v_waitset(o)); break; case K_WRITERINSTANCE: v_writerInstanceDeinit(v_writerInstance(o)); break; case K_DATAREADERINSTANCE: v_dataReaderInstanceDeinit(v_dataReaderInstance(o)); break; case K_DATAVIEWINSTANCE: v_dataViewInstanceDeinit(v_dataViewInstance(o)); break; default: OS_REPORT_1(OS_ERROR,"v_publicDispose failed",0, "illegal entity kind (%d) specified",v_objectKind(o)); assert(FALSE); break; } c_free(o); }
void v_serviceFree( v_service service) { assert(C_TYPECHECK(service, v_service)); v_participantFree(v_participant(service)); }
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); } }
void v_serviceDeinit( v_service service) { assert(service != NULL); assert(C_TYPECHECK(service, v_service)); v_participantDeinit(v_participant(service)); }
v_networking v_networkingNew( v_serviceManager manager, const c_char *name, const c_char *extStateName, v_participantQos qos) { v_kernel k; v_networking s; v_participantQos q; v_networkingStatistics ns; assert(C_TYPECHECK(manager, v_serviceManager)); assert(name != NULL); k = v_objectKernel(manager); q = v_participantQosNew(k, qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_networkingNew", 0, "Networking service not created: inconsistent qos"); s = NULL; } else { s = v_networking(v_objectNew(k, K_NETWORKING)); if (v_isEnabledStatistics(k, V_STATCAT_NETWORKING)) { ns = v_networkingStatistics(v_networkingStatisticsNew(k)); } else { ns = NULL; } v_serviceInit(v_service(s), manager, name, extStateName, q, v_statistics(ns)); c_free(q); /* always add, even when s->state==NULL, * since v_participantFree always removes the participant. */ v_addParticipant(k, v_participant(s)); if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; } } return s; }
void v_serviceNotify( v_service service, v_event event, c_voidp userData) { assert(service != NULL); assert(C_TYPECHECK(service, v_service)); assert(event != NULL); if (event->kind == V_EVENT_NEW_GROUP) { if (event->data && service->newGroups) { ospl_c_insert(service->newGroups, event->data); } } v_participantNotify(v_participant(service), event, userData); }
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_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)); }
/************************************************************** * 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); }
v_durability v_durabilityNew( v_serviceManager manager, const c_char *name, const c_char *extStateName, v_participantQos qos) { v_kernel k; v_durability s; v_participantQos q; v_durabilityStatistics dStat; assert(C_TYPECHECK(manager, v_serviceManager)); assert(name != NULL); k = v_objectKernel(manager); q = v_participantQosNew(k, qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_durabilityNew", 0, "Durability service not created: inconsistent qos"); s = NULL; } else { s = v_durability(v_objectNew(k, K_DURABILITY)); if (v_isEnabledStatistics(k, V_STATCAT_DURABILITY)) { dStat = v_durabilityStatisticsNew(k); } else { dStat = NULL; } v_serviceInit(v_service(s), manager, name, extStateName, q, v_statistics(dStat)); c_free(q); /* always add, even when s->state==NULL, since v_participantFree always removes the participant.*/ v_addParticipant(k, v_participant(s)); if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; } } return s; }
void v_listenerFree( v_listener _this) { v_participant p; v_listenerEvent event; os_duration delay; assert(_this != NULL); assert(C_TYPECHECK(_this,v_listener)); p = v_participant(_this->participant); assert(p != NULL); c_mutexLock(&_this->mutex); /* wakeup blocking threads to evaluate new condition. */ /* remove all events */ while (_this->eventList != NULL) { event = _this->eventList; _this->eventList = event->next; v_listenerEventDeinit(event); c_free(event); } _this->eventList = NULL; c_free(_this->lastEvent); _this->lastEvent = NULL; _this->terminate = TRUE; c_condBroadcast(&_this->cv); c_mutexUnlock(&_this->mutex); delay = OS_DURATION_INIT(0, 1000); while (_this->waitCount > 0 && !p->processIsZombie) { ospl_os_sleep(delay); } v_participantRemove(p, v_object(_this)); _this->participant = NULL; v_publicFree(v_public(_this)); }
/************************************************************** * constructor/destructor **************************************************************/ v_service v_serviceNew( v_serviceManager manager, const c_char *name, const c_char *extStateName, v_participantQos qos, v_statistics stats) { v_kernel k; v_service s; v_participantQos q; assert(C_TYPECHECK(manager, v_serviceManager)); /* Do not C_TYPECHECK qos parameter, since it might be allocated on heap! */ assert(name != NULL); k = v_objectKernel(manager); /* do no use cast method on qos parameter, * it is most likely allocated on heap! */ q = v_participantQosNew(k, (v_participantQos)qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_serviceNew", 0, "Service not created: inconsistent qos"); s = NULL; } else { s = v_service(v_objectNew(k, K_SERVICE)); v_serviceInit(s, manager, name, extStateName, q, stats); c_free(q); /* always add, even when s->state==NULL, since v_participantFree always removes the participant.*/ v_addParticipant(k, v_participant(s)); if (s->state == NULL) { v_serviceFree(s); s = NULL; } } return s; }
v_rnr v_rnrNew( v_kernel kernel, const c_char *name, const c_char *extStateName, v_participantQos qos, c_bool enable) { v_rnr _this; v_participantQos q; assert(C_TYPECHECK(kernel, v_kernel)); assert(name != NULL); q = v_participantQosNew(kernel, qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_rnrNew", V_RESULT_ILL_PARAM, "Record and Replay service not created: inconsistent qos"); _this = NULL; } else { _this = v_rnr(v_objectNew(kernel, K_RNR)); _this->statistics = v_rnrStatisticsNew (kernel, name); v_serviceInit(v_service(_this), name, extStateName, V_SERVICETYPE_RECORD_REPLAY, q, enable); c_free(q); /* always add, even when s->state==NULL, since v_participantFree always * removes the participant. */ v_addParticipant(kernel, v_participant(_this)); if (v_service(_this)->state == NULL) { v_serviceFree(v_service(_this)); _this = NULL; } else { OSPL_ADD_OBSERVER(kernel, _this, V_EVENT_NEW_GROUP, NULL); } } return _this; }
/** * PRE: v_observerLock has been called. * * When the text 'intentionally no break' is set after a case label * the class specified by the label has not implemented the notify * method. */ void v_observerNotify( v_observer _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 cannot be locked within any Notify method * to avoid deadlocks. * For consistency _this must be locked by v_observerLock(_this) before * calling this method. */ c_ulong trigger; assert(_this != NULL); assert(C_TYPECHECK(_this,v_observer)); /* The observer will be made insensitive to event as soon as the * observer is deinitialized. However it may be that destruction * of the observer has started before the deinit of the observer * is called. In that case the V_EVENT_OBJECT_DESTROYED flag will * be set to avoid processing of incomming events. */ if ((_this->eventFlags & V_EVENT_OBJECT_DESTROYED) == 0) { /* The observer is valid so the event can be processed. */ if (event != NULL ) { trigger = event->kind & _this->eventMask; } else { /* NULL-event always notifies observers */ trigger = V_EVENT_TRIGGER; } /* The following code invokes the observers subclass specific * notification method. * This is a bit strange that the observer has knowledge about * the subclass notification methods, a better model is that * subclasses register the notification method to the observer * instead. The reason for this model is that registering a * function pointer is only valid in the process scope and this * method will typically be called from another process. */ if (trigger != 0) { switch (v_objectKind(_this)) { case K_DATAREADER: v_dataReaderNotify(v_dataReader(_this), event, userData); break; case K_WAITSET: v_waitsetNotify(v_waitset(_this), event, userData); break; case K_PARTICIPANT: v_participantNotify(v_participant(_this), event, userData); break; case K_TOPIC: v_topicNotify(v_topic(_this), event, userData); break; case K_QUERY: /* v_queryNotify(v_query(_this), event, userData); */ break; case K_SPLICED: /* intentionally no break */ case K_SERVICE: case K_NETWORKING: case K_DURABILITY: case K_CMSOAP: v_serviceNotify(v_service(_this), event, userData); break; case K_SERVICEMANAGER: v_serviceManagerNotify(v_serviceManager(_this), event, userData); break; case K_WRITER: /* no action for the following observers */ case K_PUBLISHER: case K_SUBSCRIBER: case K_GROUPQUEUE: break; default: OS_REPORT_1(OS_INFO,"Kernel Observer",0, "Notify an unknown observer type: %d", v_objectKind(_this)); break; } /* * Only trigger condition variable if at least * one thread is waiting AND the event is seen for the first time. */ if ((_this->waitCount > 0) && ((trigger == V_EVENT_TRIGGER) || (~_this->eventFlags & trigger))) { _this->eventFlags |= trigger; /* store event */ c_condBroadcast(&_this->cv); } else { _this->eventFlags |= trigger; /* store event */ } } } /* else observer object destroyed, skip notification */ }
void v_serviceInit( v_service service, const c_char *name, const c_char *extStateName, v_serviceType serviceType, v_participantQos qos, c_bool enable) { c_char *typeName; os_duration lp = 300*OS_DURATION_SECOND; v_kernel kernel; v_serviceManager manager; assert(service != NULL); assert(serviceType != V_SERVICETYPE_NONE); assert(C_TYPECHECK(service, v_service)); assert(C_TYPECHECK(qos, v_participantQos)); assert(name != NULL); kernel = v_objectKernel(service); manager = v_getServiceManager(kernel); /* v_participantInit writes the DCPSParticipant and CMParticipant topics, but * it downcasts to v_service to extract serviceType, and hence needs it available. */ service->serviceType = serviceType; v_participantInit(v_participant(service), name, qos); if(enable) { (void)v_entityEnable(v_entity(service)); } service->state = v_serviceManagerRegister(manager, service, extStateName); service->lease = v_leaseMonotonicNew(kernel, lp); service->newGroups = NULL; if(service->lease) { v_result result; result = v_leaseManagerRegister( kernel->livelinessLM, service->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(service->state), FALSE/*do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT(OS_FATAL, "v_service", result, "A fatal error was detected when trying to register the liveliness lease " "to the liveliness lease manager of the kernel. The result code was %d.", result); } } else { OS_REPORT(OS_FATAL, "v_service", V_RESULT_INTERNAL_ERROR, "Unable to create a liveliness lease! Most likely not enough shared " "memory available to complete the operation."); } if(service->lease)/* aka everything is ok so far */ { v_result result; c_iter participants; v_participant splicedParticipant; participants = v_resolveParticipants(kernel, V_SPLICED_NAME); assert(c_iterLength(participants) == 1 || 0 == strcmp(name, V_SPLICED_NAME)); splicedParticipant = v_participant(c_iterTakeFirst(participants)); if(splicedParticipant) { result = v_leaseManagerRegister( v_participant(service)->leaseManager, v_service(splicedParticipant)->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(v_service(splicedParticipant)->state), FALSE /* only observing, do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT(OS_FATAL, "v_service", result, "A fatal error was detected when trying to register the spliced's liveliness lease " "to the lease manager of participant %p (%s). The result code was %d.", (void*)service, name, result); } c_free(splicedParticipant); } c_iterFree(participants); } if (service->state != NULL) { /* check if state has correct type */ typeName = c_metaScopedName(c_metaObject(c_getType(c_object(service->state)))); if (extStateName == NULL) { extStateName = VSERVICESTATE_NAME; } if (strcmp(typeName, extStateName) == 0) { /* Splicedaemon may not observer itself! */ if (strcmp(name, V_SPLICED_NAME) != 0) { v_serviceState splicedState; splicedState = v_serviceManagerGetServiceState(manager, V_SPLICED_NAME); (void)OSPL_ADD_OBSERVER(splicedState, service, V_EVENT_SERVICESTATE_CHANGED, NULL); } } else { OS_REPORT(OS_ERROR, "v_service", V_RESULT_ILL_PARAM, "Requested state type (%s) differs with existing state type (%s)", extStateName, typeName); c_free(service->state); service->state = NULL; } os_free(typeName); } }
c_ulong v_networkReaderCreateQueue( v_networkReader reader, c_ulong queueSize, c_ulong priority, c_bool reliable, c_bool P2P, c_time resolution, c_bool useAsDefault, const c_char *name) { c_ulong result = 0; v_networkQueue queue; v_networkReaderStatistics s; v_networkQueueStatistics nqs; v_networkingStatistics nws; v_networkChannelStatistics ncs; v_kernel kernel; v_networking n; v_participant p; kernel = v_objectKernel(reader); if (reader->nofQueues < NW_MAX_NOF_QUEUES) { p = v_participant(v_subscriber(v_reader(reader)->subscriber)->participant); if ((v_objectKind(p) == K_NETWORKING) && (v_isEnabledStatistics(kernel, V_STATCAT_NETWORKING))) { nqs = v_networkQueueStatisticsNew(kernel,name); ncs = v_networkChannelStatisticsNew(kernel,name); } else { nqs = NULL; ncs = NULL; } queue = v_networkQueueNew(c_getBase((c_object)reader), queueSize, priority, reliable, P2P, resolution, nqs); if (queue != NULL) { reader->queues[reader->nofQueues] = queue; reader->nofQueues++; result = reader->nofQueues; /* insert statistics */ if (nqs != NULL) { s = v_networkReaderStatistics(v_entityStatistics(v_entity(reader))); if (s != NULL) { s->queues[s->queuesCount]=nqs; s->queuesCount++; } } if ((useAsDefault) || (reader->defaultQueue == NULL)){ c_free(reader->defaultQueue); reader->defaultQueue = c_keep(queue); } if (ncs != NULL) { /* add channel to the networking statistics also */ n = v_networking(p); nws = (v_networkingStatistics)v_entity(n)->statistics; nws->channels[nws->channelsCount]=ncs; nws->channelsCount++; } } } else { OS_REPORT_1(OS_ERROR, "v_networkReaderCreateQueue", 0, "Maximum number of network queues (%d) exceeded, " "new queue not created", NW_MAX_NOF_QUEUES); } return result; }
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_serviceInit( v_service service, v_serviceManager manager, const c_char *name, const c_char *extStateName, v_participantQos qos, v_statistics stats) { c_char *typeName; v_duration lp = {300, 0}; v_kernel kernel; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); assert(C_TYPECHECK(qos, v_participantQos)); assert(name != NULL); kernel = v_objectKernel(service); v_participantInit(v_participant(service), name, qos, stats, TRUE); service->state = v_serviceManagerRegister(manager, service, extStateName); service->lease = v_leaseNew(kernel, lp); if(service->lease) { v_result result; result = v_leaseManagerRegister( kernel->livelinessLM, service->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(service->state), FALSE/*do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT_1(OS_ERROR, "v_service", 0, "A fatal error was detected when trying to register the liveliness lease " "to the liveliness lease manager of the kernel. The result code was %d.", result); } } else { OS_REPORT(OS_ERROR, "v_service", 0, "Unable to create a liveliness lease! Most likely not enough shared " "memory available to complete the operation."); } if(service->lease)/* aka everything is ok so far */ { v_result result; c_iter participants; v_participant splicedParticipant; participants = v_resolveParticipants(kernel, V_SPLICED_NAME); assert(c_iterLength(participants) == 1 || 0 == strcmp(name, V_SPLICED_NAME)); splicedParticipant = v_participant(c_iterTakeFirst(participants)); if(splicedParticipant) { result = v_leaseManagerRegister( v_participant(service)->leaseManager, v_service(splicedParticipant)->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(v_service(splicedParticipant)->state), FALSE /* only observing, do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT_3(OS_ERROR, "v_service", 0, "A fatal error was detected when trying to register the spliced's liveliness lease " "to the lease manager of participant %p (%s). The result code was %d.", service, name, result); } } c_iterFree(participants); } if (service->state != NULL) { /* check if state has correct type */ typeName = c_metaScopedName(c_metaObject(c_getType(c_object(service->state)))); if (extStateName == NULL) { extStateName = VSERVICESTATE_NAME; } if (strcmp(typeName, extStateName) == 0) { if (strcmp(name, V_SPLICED_NAME) != 0) { /* Splicedaemon may not observer itself! */ v_serviceWatchSplicedaemon(service); } } else { OS_REPORT_2(OS_ERROR, "v_service", 0, "Requested state type (%s) differs with existing state type (%s)", extStateName, typeName); c_free(service->state); service->state = NULL; } os_free(typeName); } }