c_bool d_waitsetAttach( d_waitset waitset, d_waitsetEntity we) { c_bool result = FALSE; u_result ur; os_result osr; d_waitsetHelper helper; c_ulong mask; d_admin admin; d_durability durability; assert(d_objectIsValid(d_object(waitset), D_WAITSET) == TRUE); assert(d_objectIsValid(d_object(we), D_WAITSET_ENTITY) == TRUE); if(waitset && we){ d_lockLock(d_lock(waitset)); if(!we->waitset) { if(c_iterContains(waitset->entities, we) == FALSE) { waitset->entities = c_iterInsert(waitset->entities, we); if(waitset->runToCompletion == TRUE){ ur = u_waitsetAttach(waitset->uwaitset, u_entity(we->dispatcher), (c_voidp)we->dispatcher); if(ur == U_RESULT_OK) { we->waitset = waitset; result = TRUE; } } else { admin = d_subscriberGetAdmin(waitset->subscriber); durability = d_adminGetDurability(admin); helper = os_malloc(C_SIZEOF(d_waitsetHelper)); helper->waitset = waitset; helper->entity = we; helper->terminate = FALSE; helper->tid = OS_THREAD_ID_NONE; helper->userWaitset = u_waitsetNew(u_participant(d_durabilityGetService(durability))); mask = V_EVENT_DATA_AVAILABLE; mask |= V_EVENT_NEW_GROUP; mask |= V_EVENT_HISTORY_DELETE; mask |= V_EVENT_HISTORY_REQUEST; mask |= V_EVENT_PERSISTENT_SNAPSHOT; mask |= V_EVENT_TRIGGER; u_waitsetSetEventMask(helper->userWaitset, mask); ur = u_waitsetAttach(helper->userWaitset, u_entity(we->dispatcher), (c_voidp)we->dispatcher); if(ur != U_RESULT_OK) { assert(FALSE); } else { result = TRUE; } if(result){ waitset->threads = c_iterInsert(waitset->threads, helper); osr = os_threadCreate(&(helper->tid), we->name, &(we->attr), d_waitsetEventHandler, helper); if(osr != os_resultSuccess){ c_iterTake(waitset->threads, helper); u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); result = FALSE; } } else { u_waitsetFree(helper->userWaitset); os_free(helper); } } } } d_lockUnlock(d_lock(waitset)); } return result; }
d_waitset d_waitsetNew( d_subscriber subscriber, c_bool runToCompletion, c_bool timedWait) { d_durability durability; d_admin admin; u_participant uparticipant; os_threadAttr attr; os_result osr; c_ulong mask; d_waitset waitset = NULL; assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); if(subscriber){ waitset = d_waitset(os_malloc(C_SIZEOF(d_waitset))); if(waitset) { d_lockInit(d_lock(waitset), D_WAITSET, d_waitsetDeinit); admin = d_subscriberGetAdmin(subscriber); durability = d_adminGetDurability(admin); uparticipant = u_participant(d_durabilityGetService(durability)); waitset->terminate = FALSE; waitset->subscriber = subscriber; waitset->entities = c_iterNew(NULL); waitset->runToCompletion = runToCompletion; waitset->timedWait = timedWait; if(runToCompletion == TRUE){ waitset->uwaitset = u_waitsetNew(uparticipant); mask = V_EVENT_DATA_AVAILABLE; mask |= V_EVENT_NEW_GROUP; mask |= V_EVENT_HISTORY_DELETE; mask |= V_EVENT_HISTORY_REQUEST; mask |= V_EVENT_PERSISTENT_SNAPSHOT; mask |= V_EVENT_TRIGGER; u_waitsetSetEventMask(waitset->uwaitset, mask); osr = os_threadAttrInit(&attr); if(osr == os_resultSuccess) { osr = os_threadCreate(&waitset->thread, "waitsetThread", &attr, d_waitsetEventHandlerRunToCompletion, waitset); } if(osr != os_resultSuccess) { d_waitsetFree(waitset); } waitset->threads = NULL; } else { waitset->threads = c_iterNew(NULL); waitset->uwaitset = NULL; waitset->thread = OS_THREAD_ID_NONE; } } } return waitset; }
d_publisher d_publisherNew( d_admin admin) { d_publisher publisher; d_durability durability; d_configuration config; v_publisherQos publisherQos; v_writerQos writerQos; publisher = NULL; if(admin){ publisher = d_publisher(os_malloc(C_SIZEOF(d_publisher))); d_objectInit(d_object(publisher), D_PUBLISHER, d_publisherDeinit); publisher->enabled = TRUE; publisher->admin = admin; durability = d_adminGetDurability(admin); config = d_durabilityGetConfiguration(durability); publisherQos = d_publisherQosNew(config->partitionName); publisher->publisher = u_publisherNew( u_participant(d_durabilityGetService(durability)), config->publisherName, publisherQos, TRUE); d_publisherQosFree(publisherQos); if(publisher->publisher){ publisher->statusWriter = NULL; publisher->newGroupWriter = NULL; publisher->groupsRequestWriter = NULL; publisher->statusRequestWriter = NULL; publisher->sampleRequestWriter = NULL; publisher->sampleChainWriter = NULL; publisher->nameSpacesWriter = NULL; publisher->nameSpacesRequestWriter = NULL; publisher->deleteDataWriter = NULL; writerQos = d_writerQosNew( V_DURABILITY_VOLATILE, V_RELIABILITY_RELIABLE, config->heartbeatLatencyBudget, config->heartbeatTransportPriority); publisher->statusNumber = 0; publisher->statusWriter = u_writerNew (publisher->publisher, "statusWriter", d_adminGetStatusTopic(admin), d_publisherStatusWriterCopy, writerQos, TRUE); assert(publisher->statusWriter); d_writerQosFree(writerQos); writerQos = d_writerQosNew (V_DURABILITY_VOLATILE, V_RELIABILITY_RELIABLE, config->latencyBudget, config->transportPriority); u_entityAction(u_entity(publisher->statusWriter), d_publisherEnsureServicesAttached, durability); publisher->newGroupNumber = 0; publisher->newGroupWriter = u_writerNew (publisher->publisher, "newGroupWriter", d_adminGetNewGroupTopic(admin), d_publisherNewGroupWriterCopy, writerQos, TRUE); assert(publisher->newGroupWriter); u_entityAction(u_entity(publisher->newGroupWriter), d_publisherEnsureServicesAttached, durability); publisher->groupsRequestNumber = 0; publisher->groupsRequestWriter = u_writerNew (publisher->publisher, "groupsRequestWriter", d_adminGetGroupsRequestTopic(admin), d_publisherGroupsRequestWriterCopy, writerQos, TRUE); assert(publisher->groupsRequestWriter); u_entityAction(u_entity(publisher->groupsRequestWriter), d_publisherEnsureServicesAttached, durability); publisher->statusRequestNumber = 0; publisher->statusRequestWriter = u_writerNew (publisher->publisher, "statusRequestWriter", d_adminGetStatusRequestTopic(admin), d_publisherStatusRequestWriterCopy, writerQos, TRUE); assert(publisher->statusRequestWriter); u_entityAction(u_entity(publisher->statusRequestWriter), d_publisherEnsureServicesAttached, durability); publisher->sampleRequestNumber = 0; publisher->sampleRequestWriter = u_writerNew (publisher->publisher, "sampleRequestWriter", d_adminGetSampleRequestTopic(admin), d_publisherSampleRequestWriterCopy, writerQos, TRUE); assert(publisher->sampleRequestWriter); u_entityAction(u_entity(publisher->sampleRequestWriter), d_publisherEnsureServicesAttached, durability); publisher->nameSpacesNumber = 0; publisher->nameSpacesWriter = u_writerNew (publisher->publisher, "nameSpacesWriter", d_adminGetNameSpacesTopic(admin), d_publisherNameSpacesWriterCopy, writerQos, TRUE); assert(publisher->nameSpacesWriter); u_entityAction(u_entity(publisher->nameSpacesWriter), d_publisherEnsureServicesAttached, durability); publisher->nameSpacesRequestNumber = 0; publisher->nameSpacesRequestWriter = u_writerNew (publisher->publisher, "nameSpacesRequestWriter", d_adminGetNameSpacesRequestTopic(admin), d_publisherNameSpacesRequestWriterCopy, writerQos, TRUE); assert(publisher->nameSpacesRequestWriter); u_entityAction(u_entity(publisher->nameSpacesRequestWriter), d_publisherEnsureServicesAttached, durability); publisher->deleteDataNumber = 0; publisher->deleteDataWriter = u_writerNew (publisher->publisher, "deleteDataWriter", d_adminGetDeleteDataTopic(admin), d_publisherDeleteDataWriterCopy, writerQos, TRUE); assert(publisher->deleteDataWriter); u_entityAction(u_entity(publisher->deleteDataWriter), d_publisherEnsureServicesAttached, durability); d_writerQosFree(writerQos); writerQos = d_writerQosNew (V_DURABILITY_VOLATILE, V_RELIABILITY_RELIABLE, config->alignerLatencyBudget, config->alignerTransportPriority); publisher->sampleChainNumber = 0; publisher->sampleChainWriter = u_writerNew (publisher->publisher, "sampleChainWriter", d_adminGetSampleChainTopic(admin), d_publisherSampleChainWriterCopy, writerQos, TRUE); assert(publisher->sampleChainWriter); u_entityAction(u_entity(publisher->sampleChainWriter), d_publisherEnsureServicesAttached, durability); d_writerQosFree(writerQos); } else { d_publisherFree(publisher); publisher = NULL; } } return publisher; }
static void* d_groupCreationQueueRun( void* userData) { d_groupCreationQueue queue; c_iter groupsToCreate, reinsert; d_group group, localGroup; d_durability durability; d_durabilityKind kind; u_participant uservice; c_char *partition, *topic; v_duration duration; u_group ugroup; c_long creationCountVolatile, creationCountTransient, creationCountPersistent; c_ulong maxBurst; os_time sleepTime, maxBurstSleepTime; c_bool update; sleepTime.tv_sec = 1; sleepTime.tv_nsec = 0; duration.seconds = 0; duration.nanoseconds = 5000000; /*5ms*/ creationCountVolatile = 0; creationCountTransient = 0; creationCountPersistent = 0; maxBurstSleepTime.tv_sec = 0; maxBurstSleepTime.tv_nsec = 10000000; /*10ms*/ queue = d_groupCreationQueue(userData); groupsToCreate = c_iterNew(NULL); reinsert = c_iterNew(NULL); durability = d_adminGetDurability(queue->admin); uservice = u_participant(d_durabilityGetService(durability)); d_waitForCompletenessDCPSTopic(queue); while(queue->terminate == FALSE) { d_lockLock(d_lock(queue)); queue->groupsToCreateVolatile -= creationCountVolatile; assert(queue->groupsToCreateVolatile >= 0); queue->groupsToCreateTransient -= creationCountTransient; assert(queue->groupsToCreateTransient >= 0); queue->groupsToCreatePersistent -= creationCountPersistent; assert(queue->groupsToCreatePersistent >= 0); group = d_group(c_iterTakeFirst(queue->groups)); while(group){ groupsToCreate = c_iterInsert(groupsToCreate, group); group = d_group(c_iterTakeFirst(queue->groups)); } assert((queue->groupsToCreateVolatile + queue->groupsToCreateTransient + queue->groupsToCreatePersistent) == c_iterLength(groupsToCreate)); durability = d_adminGetDurability(queue->admin); d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue); d_lockUnlock(d_lock(queue)); creationCountVolatile = 0; creationCountTransient = 0; creationCountPersistent = 0; maxBurst = 10; group = c_iterTakeFirst(groupsToCreate); while(group && (queue->terminate == FALSE)){ partition = d_groupGetPartition(group); topic = d_groupGetTopic(group); kind = d_groupGetKind(group); localGroup = d_adminGetLocalGroup(queue->admin, partition, topic, kind); update = FALSE; if(localGroup) { d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s has already been created locally.\n", partition, topic); update = TRUE; } else { ugroup = u_groupNew(uservice, partition, topic, duration); if(ugroup){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s created locally.\n", partition, topic); update = TRUE; u_entityFree(u_entity(ugroup)); maxBurst--; if(maxBurst == 0){ os_nanoSleep(maxBurstSleepTime); maxBurst = 10; } } else { maxBurst++; d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "Remote group %s.%s could not be created locally.\n", partition, topic); if(d_durabilityGetState(durability) == D_STATE_COMPLETE){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_CREATION, "I am complete so it will not be available anymore.\n"); update = TRUE; } else if(d_adminGetFellowCount(queue->admin) == 0){ d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_CREATION, "No fellows available to provide me with group information. " \ "Ignoring group.\n", partition, topic); update = TRUE; } else { reinsert = c_iterInsert(reinsert, group); } } } if(update){ switch(d_groupGetKind(group)){ case D_DURABILITY_VOLATILE: creationCountVolatile++; break; case D_DURABILITY_TRANSIENT: case D_DURABILITY_TRANSIENT_LOCAL: creationCountTransient++; break; case D_DURABILITY_PERSISTENT: creationCountPersistent++; break; default: assert(FALSE); break; } d_groupFree(group); } os_free(partition); os_free(topic); group = c_iterTakeFirst(groupsToCreate); } group = d_group(c_iterTakeFirst(reinsert)); while(group){ groupsToCreate = c_iterInsert(groupsToCreate, group); group = d_group(c_iterTakeFirst(reinsert)); } if(queue->terminate == FALSE){ os_nanoSleep(sleepTime); } } group = d_group(c_iterTakeFirst(groupsToCreate)); while(group) { d_groupFree(group); group = d_group(c_iterTakeFirst(groupsToCreate)); } c_iterFree(groupsToCreate); c_iterFree(reinsert); d_lockLock(d_lock(queue)); group = d_group(c_iterTakeFirst(queue->groups)); while(group) { d_groupFree(group); group = d_group(c_iterTakeFirst(queue->groups)); } d_lockUnlock(d_lock(queue)); return NULL; }
d_subscriber d_subscriberNew( d_admin admin) { d_subscriber subscriber; d_durability durability; d_configuration config; v_subscriberQos subscriberQos, psubscriberQos; c_char* partitionExpr; struct initialQualityWalkData walkData; d_storeResult result; d_nameSpace nameSpace; c_iter nameSpaces; c_bool nsComplete; d_durabilityKind dkind; subscriber = NULL; if(admin){ subscriber = d_subscriber(os_malloc(C_SIZEOF(d_subscriber))); d_objectInit(d_object(subscriber), D_SUBSCRIBER, d_subscriberDeinit); subscriber->admin = admin; durability = d_adminGetDurability(admin); config = d_durabilityGetConfiguration(durability); subscriberQos = d_subscriberQosNew(config->partitionName); partitionExpr = getPersistentPartitionExpression(admin, durability); psubscriberQos = d_subscriberQosNew(partitionExpr); os_free(partitionExpr); subscriber->subscriber = u_subscriberNew (u_participant(d_durabilityGetService(durability)), config->subscriberName, subscriberQos, TRUE); subscriber->waitset = d_waitsetNew(subscriber, FALSE, FALSE); subscriber->persistentStore = d_storeOpen(durability, config->persistentStoreMode); if(subscriber->persistentStore) { if(psubscriberQos->partition){ /* Collect nameSpaces from admin. */ nameSpaces = d_adminNameSpaceCollect(admin); /* Loop nameSpaces */ while((nameSpace = c_iterTakeFirst(nameSpaces))) { dkind = d_nameSpaceGetDurabilityKind(nameSpace); /* Walk only over persistent nameSpaces */ if((dkind == D_DURABILITY_PERSISTENT) || (dkind == D_DURABILITY_ALL)){ /* If persistent nameSpace is not complete, restore backup */ result = d_storeNsIsComplete (subscriber->persistentStore, nameSpace, &nsComplete); if ( (result == D_STORE_RESULT_OK) && !nsComplete) { /* Incomplete namespace, restore backup. */ d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_LOCAL_LISTENER, "Namespace '%s' is incomplete, trying to restore backup.\n", d_nameSpaceGetName(nameSpace)); if (d_storeRestoreBackup (subscriber->persistentStore, nameSpace) != D_STORE_RESULT_OK) { d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_LOCAL_LISTENER, "Backup for namespace '%s' could not be restored as no complete backup did exist on disk. Marking namespace as incomplete and continuing.\n", d_nameSpaceGetName(nameSpace)); OS_REPORT_1(OS_WARNING, D_CONTEXT_DURABILITY, 0, "Backup for namespace '%s' could not be restored as no complete backup did exist on disk. Marking namespace as incomplete and continuing.\n", d_nameSpaceGetName (nameSpace)); /* If backup fails, mark master state for nameSpace !D_STATE_COMPLETE */ d_nameSpaceSetMasterState (nameSpace, D_STATE_INIT); } } } d_nameSpaceFree(nameSpace); } /* Free nameSpaces iterator */ assert(c_iterLength(nameSpaces) == 0); c_iterFree(nameSpaces); subscriber->persistentSubscriber = u_subscriberNew(u_participant(d_durabilityGetService(durability)), config->subscriberName, psubscriberQos, TRUE); assert(subscriber->persistentSubscriber); } else { subscriber->persistentSubscriber = NULL; } walkData.subscriber = subscriber; walkData.i = 0; d_adminNameSpaceWalk(admin, nsInitialQualityWalk, &walkData); } else { subscriber->persistentSubscriber = NULL; } assert(subscriber->subscriber); if(subscriber->subscriber){ subscriber->statusListener = NULL; subscriber->groupLocalListener = NULL; subscriber->groupRemoteListener = NULL; subscriber->groupsRequestListener = NULL; subscriber->sampleRequestListener = NULL; subscriber->sampleChainListener = NULL; subscriber->nameSpacesRequestListener = NULL; subscriber->nameSpacesListener = NULL; subscriber->persistentDataListener = NULL; subscriber->deleteDataListener = NULL; } else { d_subscriberFree(subscriber); subscriber = NULL; } d_subscriberQosFree(subscriberQos); d_subscriberQosFree(psubscriberQos); } return subscriber; }
void d_groupRemoteListenerAction( d_listener listener, d_message message) { d_newGroup remote; d_configuration config; d_durability durability; d_admin admin; d_group group, group2; d_fellow fellow; c_bool createLocally, added; v_duration duration; u_group ugroup; d_networkAddress addr; c_bool result; d_subscriber subscriber; d_sampleChainListener sampleChainListener; d_completeness localCompleteness; assert(d_listenerIsValid(d_listener(listener), D_GROUP_REMOTE_LISTENER)); remote = d_newGroup(message); admin = d_listenerGetAdmin(listener); durability = d_adminGetDurability(admin); config = d_durabilityGetConfiguration(durability); addr = d_networkAddressNew(message->senderAddress.systemId, message->senderAddress.localId, message->senderAddress.lifecycleId); fellow = d_adminGetFellow(admin, addr); if(remote->partition && remote->topic){ d_printTimedEvent(durability, D_LEVEL_FINEST, D_THREAD_GROUP_REMOTE_LISTENER, "Received remote group '%s.%s'.\n", remote->partition, remote->topic); } if(fellow){ if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){ if(!(remote->partition) && !(remote->topic)){ d_fellowSetExpectedGroupCount(fellow, remote->alignerCount); } else { group = d_adminGetLocalGroup(admin, remote->partition, remote->topic, remote->durabilityKind); if(!group){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_REMOTE_LISTENER, "Received remote group %s.%s which is locally unknown.\n", remote->partition, remote->topic); /* Group unknown locally, check if it is in the alignee namespace. */ createLocally = d_adminGroupInAligneeNS( admin, remote->partition, remote->topic, remote->durabilityKind); if(createLocally == TRUE){ group = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, remote->completeness, remote->quality); added = d_fellowAddGroup(fellow, group); d_fellowSetExpectedGroupCount(fellow, remote->alignerCount); if(added == FALSE){ d_groupFree(group); group = d_fellowGetGroup(fellow, remote->partition, remote->topic, remote->durabilityKind); if(group){ d_groupUpdate(group, remote->completeness, remote->quality); d_groupFree(group); } } /* Group unknown locally, check if it should be aligned * initially. */ createLocally = d_adminGroupInInitialAligneeNS( admin, remote->partition, remote->topic, remote->durabilityKind); if(createLocally == TRUE){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group %s.%s in initial alignee namespace.\n", remote->partition, remote->topic); duration.seconds = 0; duration.nanoseconds = 10000000; ugroup = u_groupNew( u_participant(d_durabilityGetService(durability)), remote->partition, remote->topic, duration); if(ugroup){ d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group %s.%s with quality %d created locally.\n", remote->partition, remote->topic, remote->quality.seconds); u_entityFree(u_entity(ugroup)); } else { d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group %s.%s with quality %d could NOT be created locally.\n", remote->partition, remote->topic, remote->quality.seconds); /** * TODO: quality must not be taken over * from remote. */ group2 = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, D_GROUP_INCOMPLETE, remote->quality); result = d_groupCreationQueueAdd( d_groupRemoteListener(listener)->groupCreationQueue, group2); if(result == FALSE){ d_printTimedEvent(durability, D_LEVEL_FINER, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group %s.%s already in creation queue. Skipping this one.\n", remote->partition, remote->topic); d_groupFree(group2); } } } else { d_printTimedEvent(durability, D_LEVEL_FINE, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group %s.%s in alignee namespace, but not initial.\n", remote->partition, remote->topic); } } else { d_printTimedEvent(durability, D_LEVEL_INFO, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group '%s.%s' is not in alignee namespace.\n", remote->partition, remote->topic); } } else { localCompleteness = d_groupGetCompleteness(group); group = d_fellowGetGroup(fellow, remote->partition, remote->topic, remote->durabilityKind); if(group){ d_groupUpdate(group, remote->completeness, remote->quality); d_printTimedEvent(durability, D_LEVEL_FINEST, D_THREAD_GROUP_REMOTE_LISTENER, "Updating remote group '%s.%s' completeness: '%d'.\n", remote->partition, remote->topic, remote->completeness); d_groupFree(group); } else if(localCompleteness != D_GROUP_COMPLETE){ group = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, remote->completeness, remote->quality); added = d_fellowAddGroup(fellow, group); if(added == FALSE){ d_groupFree(group); group = d_fellowGetGroup(fellow, remote->partition, remote->topic, remote->durabilityKind); if(group){ d_groupUpdate(group, remote->completeness, remote->quality); d_groupFree(group); } } else { d_printTimedEvent(durability, D_LEVEL_FINEST, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group '%s.%s' with completeness: '%d' registered for fellow.\n", remote->partition, remote->topic, remote->completeness); } } /* A complete group might be interesting in case there are * still unfullfilled chain requests. */ if(remote->completeness == D_GROUP_COMPLETE){ d_printTimedEvent(durability, D_LEVEL_FINEST, D_THREAD_GROUP_REMOTE_LISTENER, "Remote group '%s.%s' complete, check for unfullfilled chains.\n", remote->partition, remote->topic); subscriber = d_adminGetSubscriber(admin); sampleChainListener = d_subscriberGetSampleChainListener(subscriber); group = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, remote->completeness, remote->quality); d_sampleChainListenerTryFulfillChains(sampleChainListener, group); d_groupFree(group); } } } } else { d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_REMOTE_LISTENER, "Fellow not approved, so ignore the message.\n"); } d_fellowFree(fellow); } else { d_printTimedEvent(durability, D_LEVEL_WARNING, D_THREAD_GROUP_REMOTE_LISTENER, "Fellow unknown so far, so ignore the message.\n"); } d_networkAddressFree(addr); return; }