v_partition v_partitionNew( v_kernel kernel, const c_char *name, v_partitionQos qos) { v_partition partition, found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); assert(name != NULL); assert(v_partitionExpressionIsAbsolute(name)); partition = v_partition(v_objectNew(kernel,K_DOMAIN)); v_entityInit(v_entity(partition),name, NULL, TRUE); found = v_addPartition(kernel,partition); if (found != partition) { v_partitionFree(partition); c_free(partition); /* v_partitionFree has removed all dependancies, now delete local reference */ partition = c_keep(found); /* this one will be returned, so a keep is required */ } return partition; }
v_topicAdapter v_topicAdapterWrap( v_participant p, v_topic topic) { v_topicAdapter adapter = NULL; v_kernel kernel; assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); assert(topic != NULL); assert(C_TYPECHECK(topic,v_topic)); kernel = v_objectKernel(p); adapter = v_topicAdapter(v_objectNew(kernel,K_TOPIC_ADAPTER)); if (adapter != NULL) { v_topicAdapterInit(adapter, topic, p, v_topicName(topic)); } else { OS_REPORT(OS_ERROR, "v_topicAdapterWrap", V_RESULT_INTERNAL_ERROR, "Failed to allocate TopicAdapter for topic '%s'.", v_topicName(topic)); } return adapter; }
v_listener v_listenerNew( v_participant p, c_bool combine) { v_listener _this; v_kernel kernel; assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); _this = v_listener(v_objectNew(kernel,K_LISTENER)); if (_this != NULL) { v_publicInit(v_public(_this)); (void)c_mutexInit(c_getBase(_this), &_this->mutex); c_condInit(c_getBase(_this), &_this->cv, &_this->mutex); _this->participant = p; _this->eventList = NULL; _this->lastEvent = NULL; v_participantAdd(p, v_object(_this)); _this->terminate = FALSE; _this->waitCount = 0; _this->combine = combine; } return _this; }
v_service v_serviceNew( v_kernel kernel, const c_char *name, const c_char *extStateName, v_serviceType serviceType, v_participantQos qos, c_bool enable) { v_service s = NULL; v_participantQos q; assert(C_TYPECHECK(kernel, v_kernel)); /* Do not C_TYPECHECK qos parameter, since it might be allocated on heap! */ assert(name != NULL); if (v_participantQosCheck(qos) == V_RESULT_OK) { q = v_participantQosNew(kernel, (v_participantQos)qos); if (q == NULL) { OS_REPORT(OS_ERROR, "v_serviceNew", V_RESULT_INTERNAL_ERROR, "Creation of service <%s> failed. Cannot create participant QoS.", name); } else { s = v_service(v_objectNew(kernel, K_SERVICE)); v_serviceInit(s, name, extStateName, serviceType, q, enable); c_free(q); if (s->state == NULL) { v_serviceFree(s); s = NULL; } } } return s; }
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; }
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; }
v_networkReader v_networkReaderNew( v_subscriber subscriber, const c_char *name, v_readerQos qos, c_bool ignoreReliabilityQoS) { /* Note: currently, no qos-es are supported. Everything is redirected * to the defaultQueue */ v_kernel kernel; v_networkReader reader; v_readerQos q; v_statistics s; c_type queueType; c_long i; assert(C_TYPECHECK(subscriber,v_subscriber)); /* Creation */ kernel = v_objectKernel(subscriber); q = v_readerQosNew(kernel,qos); if (q != NULL) { reader = v_networkReader(v_objectNew(kernel,K_NETWORKREADER)); s = v_statistics(v_networkReaderStatisticsNew(kernel)); /* Initialization of parent */ v_readerInit(v_reader(reader), name, subscriber, q, s, TRUE); c_free(q); /* ref now in v_reader(queue)->qos */ /* This function only ever called once per network instance so no * need to store queueType as static variable. Look up as needed (once) */ queueType = c_resolve(c_getBase(subscriber),"kernelModule::v_networkQueue"); /* Initialization of self */ reader->queues = NULL; reader->queues = c_arrayNew(queueType, NW_MAX_NOF_QUEUES); reader->nofQueues = 0; reader->defaultQueue = NULL; reader->remoteActivity = FALSE; reader->ignoreReliabilityQoS = ignoreReliabilityQoS; reader->queueCache = c_arrayNew(queueType, 2*NW_MAX_QUEUE_CACHE_PRIO); for( i= 0; i < 2*NW_MAX_QUEUE_CACHE_PRIO; i++) { reader->queueCache[i] = NULL; } c_free(queueType); /* Add to subscriber */ v_subscriberAddReader(subscriber,v_reader(reader)); } else { OS_REPORT(OS_ERROR, "v_networkReaderNew", 0, "NetworkReader not created: inconsistent qos"); reader = NULL; } return reader; }
/************************************************************** * constructor/destructor **************************************************************/ v_lease v_leaseNew( v_kernel k, v_duration leaseDuration) { v_lease _this; _this = v_lease(v_objectNew(k, K_LEASE)); if(_this) { v_leaseInit(_this, k, leaseDuration); } return _this; }
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; }
v_deliveryServiceEntry v_deliveryServiceEntryNew( v_deliveryService deliveryService, v_topic topic) { v_kernel kernel; v_deliveryServiceEntry e; assert(C_TYPECHECK(deliveryService,v_deliveryService)); assert(C_TYPECHECK(topic,v_topic)); kernel = v_objectKernel(deliveryService); e = v_deliveryServiceEntry(v_objectNew(kernel,K_DELIVERYSERVICEENTRY)); v_entryInit(v_entry(e), v_reader(deliveryService)); e->topic = c_keep(topic); return e; }
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; }
/************************************************************** * Protected functions **************************************************************/ v_partitionAdmin v_partitionAdminNew( v_kernel kernel) { v_partitionAdmin da; assert(C_TYPECHECK(kernel,v_kernel)); da = v_partitionAdmin(v_objectNew(kernel, K_DOMAINADMIN)); if (da != NULL) { da->partitions = c_tableNew(v_kernelType(kernel, K_DOMAIN),"name"); da->partitionInterests = c_tableNew(v_kernelType(kernel, K_DOMAININTEREST), "expression"); c_mutexInit(&da->mutex,SHARED_MUTEX); if ((da->partitions == NULL) || (da->partitionInterests == NULL)) { c_free(da); da = NULL; } } return da; }
/************************************************************** * constructor/destructor **************************************************************/ v_leaseManager v_leaseManagerNew( v_kernel k) { v_leaseManager _this; assert(C_TYPECHECK(k, v_kernel)); _this = v_leaseManager(v_objectNew(k, K_LEASEMANAGER)); if(_this) { v_leaseManagerInit(_this); } else { 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."); } return _this; }
v_networkReaderEntry v_networkReaderEntryNew( v_networkReader reader, v_group group, v_networkId networkId, c_ulong channelsToConnect, v_networkPartitionId networkPartitionId, c_bool isRouting) { v_kernel kernel; v_networkReaderEntry result; assert(C_TYPECHECK(reader, v_networkReader)); assert(C_TYPECHECK(group, v_group)); kernel = v_objectKernel(reader); result = v_networkReaderEntry(v_objectNew(kernel,K_NETWORKREADERENTRY)); v_networkReaderEntryInit(result, reader, group, networkId, channelsToConnect, networkPartitionId, isRouting); return result; }
/************************************************************** * 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; }
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; }
v_networkReader v_networkReaderNew( v_subscriber subscriber, const c_char *name, v_readerQos qos, c_bool ignoreReliabilityQoS) { /* Note: currently, no qos-es are supported. Everything is redirected * to the defaultQueue */ v_kernel kernel; v_networkReader reader = NULL; v_result r; v_readerQos q; c_type queueType; c_long i; assert(C_TYPECHECK(subscriber,v_subscriber)); /* Creation */ kernel = v_objectKernel(subscriber); if (v_readerQosCheck(qos) == V_RESULT_OK) { q = v_readerQosNew(kernel,qos); if (q != NULL) { reader = v_networkReader(v_objectNew(kernel,K_NETWORKREADER)); reader->statistics = v_networkReaderStatisticsNew(kernel); /* Initialization of parent */ v_readerInit(v_reader(reader), name, subscriber, q); (void)v_entityEnable(v_entity(reader)); c_free(q); /* ref now in v_reader(queue)->qos */ /* This function only ever called once per network instance so no * need to store queueType as static variable. Look up as needed (once) */ queueType = c_resolve(c_getBase(subscriber),"kernelModuleI::v_networkQueue"); /* Initialization of self */ reader->queues = NULL; reader->queues = c_arrayNew_s(queueType, NW_MAX_NOF_QUEUES); if (!reader->queues) { OS_REPORT(OS_ERROR, "v_networkReaderNew", V_RESULT_OUT_OF_MEMORY, "Creation of NetworkReader <%s> failed: cannot create queues", name); goto err_alloc_queues; } reader->nofQueues = 0; reader->defaultQueue = NULL; reader->remoteActivity = FALSE; reader->ignoreReliabilityQoS = ignoreReliabilityQoS; reader->queueCache = c_arrayNew_s(queueType, 2*NW_MAX_QUEUE_CACHE_PRIO); if (!reader->queueCache) { OS_REPORT(OS_ERROR, "v_networkReaderNew", V_RESULT_OUT_OF_MEMORY, "Creation of NetworkReader <%s> failed: cannot create queue cache", name); goto err_alloc_cache; } for( i= 0; i < 2*NW_MAX_QUEUE_CACHE_PRIO; i++) { reader->queueCache[i] = NULL; } c_free(queueType); /* Add to subscriber */ r = v_subscriberAddReader(subscriber,v_reader(reader)); if (r != V_RESULT_OK) { OS_REPORT(OS_ERROR, "v_networkReaderNew", r, "Creation of NetworkReader <%s> failed: cannot add reader to subscriber", name); goto err_add_reader; } } else { OS_REPORT(OS_ERROR, "v_networkReaderNew", V_RESULT_OUT_OF_MEMORY, "Creation of NetworkReader <%s> failed: cannot create reader QoS", name); reader = NULL; } } return reader; err_add_reader: err_alloc_cache: err_alloc_queues: c_free(queueType); c_free(reader); return NULL; }
/************************************************************** * constructor/destructor **************************************************************/ v_serviceState v_serviceStateNew( v_kernel k, const c_char *name, const c_char *extStateName) { v_serviceState s; c_type type; assert(C_TYPECHECK(k, v_kernel)); if (extStateName == NULL) { s = v_serviceState(v_objectNew(k, K_SERVICESTATE)); } else { type = c_resolve(c_getBase(c_object(k)), extStateName); if (type != NULL) { #if !defined NDEBUG c_type t = type; c_bool correctType; correctType = FALSE; while ((correctType == FALSE) && (t != NULL) && (c_baseObject(t)->kind == M_CLASS)) { if (strcmp(c_metaObject(t)->name, "v_serviceState") == 0) { correctType = TRUE; } else { t = c_type(c_class(t)->extends); } } if ((correctType == FALSE) && (t != NULL)) { OS_REPORT(OS_FATAL, "v_serviceState", 0, "Given type not a class"); assert(0); } else { if (correctType == FALSE) { OS_REPORT(OS_FATAL, "v_serviceState", 0, "Given type does not extend v_serviceState"); assert(0); } } #endif s = v_serviceState(c_new(type)); if (s) { v_objectKind(s) = K_SERVICESTATE; v_object(s)->kernel = k; } else { OS_REPORT(OS_ERROR, "v_serviceStateNew",0, "Failed to allocate v_serviceState object."); assert(FALSE); } } else { s = NULL; } } if (s != NULL) { v_serviceStateInit(s, name); } return s; }
v_index v__indexNew( v_dataReader reader, q_expr _from, c_iter indexList, v_indexNewAction action, c_voidp arg) { v_kernel kernel; v_index index; v_topic topic; c_type instanceType; c_iter list; c_char *keyExpr; c_array keyList; c_ulong nrOfTopics; assert(C_TYPECHECK(reader,v_dataReader)); kernel = v_objectKernel(reader); if (q_isId(_from)) { list = v_resolveTopics(kernel,q_getId(_from)); nrOfTopics = c_iterLength(list); if (nrOfTopics == 0) { OS_REPORT(OS_ERROR, "v__indexNew", V_RESULT_ILL_PARAM, "Unknown topic %s", q_getId(_from)); c_iterFree(list); return NULL; } if (nrOfTopics > 1) { OS_REPORT(OS_ERROR, "v__indexNew", V_RESULT_ILL_PARAM, "Multiple topic definitions of: %s", q_getId(_from)); topic = v_topic(c_iterTakeFirst(list)); while (topic != NULL) { c_free(topic); topic = v_topic(c_iterTakeFirst(list)); } c_iterFree(list); return NULL; } topic = c_iterTakeFirst(list); c_iterFree(list); index = v_index(c_iterReadAction(indexList, indexCompare, topic)); if (index == NULL) { /* If the userKey is enabled then the instance type key field type * will be determined from the user key expression and topic. * Otherwise when no user key is specified the default Topic key * type will be used. */ if (v_reader(reader)->qos->userKey.v.enable) { keyExpr = v_reader(reader)->qos->userKey.v.expression; } else { keyExpr = NULL; } instanceType = createInstanceType(topic,keyExpr,&keyList); if (instanceType) { index = v_index(v_objectNew(kernel,K_INDEX)); v_indexInit(index, instanceType, keyList, v_reader(reader)); } c_free(keyList); c_free(instanceType); if (index != NULL) { if (action != NULL && !action(index, topic, arg)) { OS_REPORT(OS_ERROR, "v_indexNew", V_RESULT_INTERNAL_ERROR, "v_indexNewAction failed!"); c_free(index); index = NULL; } else { (void)c_iterAppend(indexList, index); } } } } else { OS_REPORT(OS_ERROR, "v_indexNew failed",V_RESULT_ILL_PARAM, "illegal from clause specified"); assert(FALSE); index = NULL; } return index; }
v_deliveryService v_deliveryServiceNew ( v_subscriber subscriber, const c_char *name) { v_kernel kernel; v_deliveryService _this; v_readerQos q; v_topic topic; c_base base; c_type type; v_entry entry, found; assert(C_TYPECHECK(subscriber,v_subscriber)); base = c_getBase(subscriber); kernel = v_objectKernel(subscriber); topic = v_lookupTopic (kernel, V_DELIVERYINFO_NAME); /* ES, dds1576: Before creating the ackreader we have to verify that read * access to the topic is allowed. We can accomplish this by checking the * access mode of the topic. */ if(!topic) { OS_REPORT(OS_ERROR, "v_deliveryServiceNew",0, "DeliveryService not created: " "Could not locate topic with name DCPS_Delivery."); return NULL; } if(v_topicAccessMode(topic) == V_ACCESS_MODE_READ || v_topicAccessMode(topic) == V_ACCESS_MODE_READ_WRITE) { q = v_readerQosNew(kernel,NULL); if (q == NULL) { OS_REPORT(OS_ERROR, "v_deliveryServiceNew", 0, "DeliveryService not created: inconsistent qos"); return NULL; } _this = v_deliveryService(v_objectNew(kernel,K_DELIVERYSERVICE)); type = c_resolve(base, "kernelModule::v_deliveryGuard"); _this->guards = c_tableNew(type, "writerGID.localId"); c_free(type); type = c_resolve(base, "kernelModule::v_subscriptionInfoTemplate"); _this->subscriptions = c_tableNew(type, "userData.key.systemId,userData.key.localId"); c_free(type); q->userKey.enable = TRUE; q->userKey.expression = NULL; v_readerInit(v_reader(_this),name, subscriber,q, NULL, TRUE); c_free(q); entry = v_entry(v_deliveryServiceEntryNew(_this,topic)); found = v_readerAddEntry(v_reader(_this),v_entry(entry)); c_free(entry); c_free(found); v_deliveryServiceEnable(_this); } else { OS_REPORT_1(OS_ERROR, "v_deliveryServiceNew", 0, "Creation of DeliveryService <%s> failed. Topic DCPS_Delivery." "does not have read access rights.", name); _this = NULL; } return _this; }
/************************************************************** * 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; }
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; }