u_result u_serviceDeinit( u_service service) { u_result r; watchSplicedAdmin admin; if (service != NULL) { u_dispatcherRemoveListener(u_dispatcher(service), u_serviceSpliceListener); admin = watchSplicedAdmin(service->privateData); if (admin) { admin->callback = NULL; admin->usrData = NULL; if (admin->serviceManager != NULL) { u_serviceManagerFree(admin->serviceManager); } os_free(admin); } service->privateData = NULL; r = u_participantDeinit(u_participant(service)); } else { OS_REPORT(OS_ERROR,"u_serviceDeinit",0, "Illegal parameter."); r = U_RESULT_ILL_PARAM; } return r; }
c_char* cmx_participantDomainId( const c_char* participant) { cmx_entity ce; u_participant up; c_char* result; u_domainId_t did; int written; ce = cmx_entityClaim(participant); if (ce == NULL) { did = U_DOMAIN_ID_INVALID; } else { up = u_participant(ce->uentity); did = u_participantGetDomainId(up); cmx_entityRelease(ce); } /* worst-case DOMAIN_ID_ANY: 2147483647 */ result = os_malloc(sizeof(char) * 10 + 1); written = os_sprintf(result, "%d", did); assert(written > 0 && written <= 11); OS_UNUSED_ARG(written); return result; }
c_char* cmx_publisherNew( const c_char* participant, const c_char* name, const c_char* qos) { u_participant par; u_publisher pub; c_char* result; cmx_entityArg arg; u_result ur; v_publisherQos pqos; cmx_entityKernelArg kernelArg; result = NULL; par = u_participant(cmx_entityUserEntity(participant)); if(par != NULL){ kernelArg = cmx_entityKernelArg(os_malloc(C_SIZEOF(cmx_entityKernelArg))); u_entityAction(u_entity(par), cmx_entityKernelAction, (c_voidp)kernelArg); if(qos != NULL){ pqos = v_publisherQos(cmx_qosKernelQosFromKind(qos, K_PUBLISHER, c_getBase(c_object(kernelArg->kernel)))); if(pqos == NULL){ pqos = v_publisherQosNew(kernelArg->kernel, NULL); } } else { pqos = v_publisherQosNew(kernelArg->kernel, NULL); } pub = u_publisherNew(par, name, pqos, TRUE); os_free(kernelArg); c_free(pqos); if(pub != NULL){ cmx_registerEntity(u_entity(pub)); arg = cmx_entityArg(os_malloc(C_SIZEOF(cmx_entityArg))); arg->entity = u_entity(pub); arg->create = FALSE; arg->participant = NULL; arg->result = NULL; ur = u_entityAction(u_entity(pub), cmx_entityNewFromAction, (c_voidp)(arg)); if(ur == U_RESULT_OK){ result = arg->result; os_free(arg); } } } return result; }
u_result u_serviceInit( u_service service, u_serviceKind kind, u_domain domain) { u_result r; watchSplicedAdmin admin; if ((service != NULL) && (domain != NULL)) { admin = watchSplicedAdmin(os_malloc((os_uint32)C_SIZEOF(watchSplicedAdmin))); service->stt = NULL; if (admin != NULL) { service->serviceKind = kind; r = u_participantInit(u_participant(service), domain); if (r == U_RESULT_OK) { admin->serviceManager = u_serviceManagerNew(u_participant(service)); admin->callback = NULL; admin->usrData = NULL; service->privateData = (c_voidp)admin; u_entity(service)->flags |= U_ECREATE_INITIALISED; } else { OS_REPORT(OS_ERROR,"u_serviceInit",0, "Initialization of the Participant failed."); } } else { service->privateData = NULL; OS_REPORT(OS_ERROR,"u_serviceInit",0, "Failed to allocate resources."); r = U_RESULT_OUT_OF_MEMORY; } } else { OS_REPORT(OS_ERROR,"u_serviceInit",0, "Illegal parameter."); r = U_RESULT_ILL_PARAM; } return r; }
const c_char* cmx_participantAutoDetach( const c_char* participant, c_bool enable) { u_participant up; u_result result; cmx_entity ce; ce = cmx_entityClaim(participant); if (ce == NULL) { goto errorGetEntity; } up = u_participant(ce->uentity); if (enable == FALSE) { result = u_observableRemoveListener(u_observable(up), cmx_participantDetach); if (result != U_RESULT_OK) { goto errorRemoveListener; } } else { result = u_observableAction(u_observable(up), cmx_participantInitDetach, NULL); if (result != U_RESULT_OK) { goto errorEntityAction; } result = u_observableAddListener(u_observable(up), V_EVENT_SERVICESTATE_CHANGED, cmx_participantDetach, u_serviceManagerNew(up)); if (result != U_RESULT_OK) { goto errorInsertListener; } } cmx_entityRelease(ce); return CMX_RESULT_OK; errorInsertListener: errorEntityAction: errorRemoveListener: errorGetEntity: return CMX_RESULT_FAILED; }
SubscriberDelegate::SubscriberDelegate( const dds::domain::DomainParticipant& dp, const dds::sub::qos::SubscriberQos& qos, dds::sub::SubscriberListener* listener, const dds::core::status::StatusMask& event_mask) : dp_(dp), qos_(qos) { ISOCPP_REPORT_STACK_DDS_BEGIN(dp); u_subscriber uSub; u_participant uPar; u_subscriberQos uQos; uPar = u_participant(this->dp_.delegate()->get_user_handle()); if (!uPar) { ISOCPP_THROW_EXCEPTION(ISOCPP_ERROR, "Could not get subscriber participant."); } qos.delegate().check(); uQos = qos.delegate().u_qos(); if (!uQos) { ISOCPP_THROW_EXCEPTION(ISOCPP_ERROR, "Could not convert subscriber QoS."); } std::string name = this->dp_.delegate()->create_child_name("subscriber"); uSub = u_subscriberNew(uPar, name.c_str(), uQos); u_subscriberQosFree (uQos); if (!uSub) { ISOCPP_THROW_EXCEPTION(ISOCPP_ERROR, "Could not create subscriber."); } /* ObjectDelegate class will free the userlayer object in its destructor. */ this->userHandle = u_object(uSub); this->listener_set((void*)listener, event_mask); set_domain_id(dp.delegate()->get_domain_id()); }
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; }
int main( int argc, char* argv[]) { int result = 0; v_participantQos participantQos; u_result uresult; os_boolean success; v_subscriberQos subscriberQos; c_time resolution; c_base base; v_kernel kernel; /* Necessary to initialize the user layer. Do this just once per process.*/ mlv_init (); uresult = u_userInitialise(); mlv_setforreal (1); if(uresult == U_RESULT_OK){ /* Allocate default participant qos*/ participantQos = u_participantQosNew(NULL); { os_mutexAttr mattr; os_mutexAttrInit (&mattr); mattr.scopeAttr = OS_SCOPE_PRIVATE; os_mutexInit (&gluelock, &mattr); } if(participantQos){ if(argc > 1){ SERVICE_NAME = argv[1]; } if(argc > 2){ SERVICE_URI = argv[2]; } /*create participant*/ participant = u_participant(u_serviceNew( SERVICE_URI, 0, SERVICE_NAME, NULL, U_SERVICE_NETWORKING, (v_qos)participantQos)); if(participant){ struct cfgst *cfgst; ddsi2_participant_gid = u_entityGid (u_entity (participant)); /*Notify kernel that I am initializing. */ u_serviceChangeState(u_service(participant),STATE_INITIALISING); /*Start monitoring the splicedaemon state. I need to terminate if he says so*/ u_serviceWatchSpliceDaemon( u_service(participant), in_discoveryWatchSpliced, &terminate); if ((cfgst = config_init (participant, SERVICE_NAME)) != NULL) { unsigned rtps_flags = 0; struct nn_servicelease *servicelease; open_tracing_file (); /* Dependencies between default values is not handled automatically by the config processing (yet) */ if (config.many_sockets_mode) { if (config.max_participants == 0) config.max_participants = 100; } if (NN_STRICT_P) { /* Should not be sending invalid messages when strict */ config.respond_to_rti_init_zero_ack_with_invalid_heartbeat = 0; config.acknack_numbits_emptyset = 1; } config_print_and_free_cfgst (cfgst); servicelease = nn_servicelease_new (participant); nn_servicelease_start_renewing (servicelease); myNetworkId = getNetworkId (); u_entityAction(u_entity(participant), resolveKernelService, NULL); base = c_getBase(service); kernel = v_object(service)->kernel; rtps_init (base, kernel, config.domainId, config.participantIndex, rtps_flags, config.networkAddressString, config.peers); /* Initialize entity administration. */ success = in_entityAdminInit(participant); if(success){ /*Create subscriber to receive client writers' messages.*/ subscriberQos = u_subscriberQosNew(NULL); os_free(subscriberQos->partition); subscriberQos->partition = NULL; clientSubscriber = u_subscriberNew( participant, "clientSubscriber", subscriberQos, TRUE); if(clientSubscriber){ /*Create networkReader to be able to receive client writers' messages.*/ clientReader = u_networkReaderNew( clientSubscriber, "clientReader", NULL, TRUE); if(clientReader){ resolution.seconds = 0; resolution.nanoseconds = 10 * 1000 * 1000; /*10 ms*/ /*Create network queue*/ uresult = u_networkReaderCreateQueue( clientReader, 1000, 0, FALSE, FALSE, resolution, TRUE, &queueId, "DDSi"); if(uresult == U_RESULT_OK){ struct builtin_datareader_set drset; u_entityAction(u_entity(clientReader), resolveKernelReader, NULL); uresult = create_builtin_readers (&drset, participant); if (uresult == U_RESULT_OK) { u_serviceChangeState(u_service(participant),STATE_OPERATIONAL); uresult = attachAndMonitor(participant, &drset); if((uresult != U_RESULT_OK) && (uresult != U_RESULT_DETACHING)) { nn_log (LC_ERROR, "Abnormal termination...\n"); result = -1; } else { nn_log (LC_INFO, "Deleting entities...\n"); } destroy_builtin_readers (&drset); } else { nn_log (LC_FATAL, "Could not create subscription + readers for builtin topics.\n"); result = -1; } terminate = TRUE; v_networkReaderTrigger(vclientReader, queueId); os_threadWaitExit(clientWriterThread, NULL); } else { nn_log (LC_FATAL, "Could not create networkQueue.\n"); result = -1; } /*Clean up networkReader*/ os_mutexLock (&gluelock); u_networkReaderFree(clientReader); clientReader = NULL; vclientReader = NULL; os_mutexUnlock (&gluelock); } else { nn_log (LC_FATAL, "Could not create networkReader.\n"); result = -1; } /*Clean up subscriber*/ u_subscriberFree(clientSubscriber); } else { nn_log (LC_FATAL, "Could not create subscriber.\n"); result = -1; } /*Clean up entity administration*/ in_entityAdminDestroy(); } else { nn_log (LC_FATAL, "Could not initialize entity adminstration.\n"); result = -1; } /* RTPS layer now defines types, cleanup before detaching */ rtps_term(); /*Notify kernel that I've terminated*/ u_serviceChangeState(u_service(participant),STATE_TERMINATED); nn_servicelease_free (servicelease); /*Delete participant*/ uresult = u_serviceFree(u_service(participant)); if(uresult != U_RESULT_OK){ nn_log (LC_FATAL, "Deletion of participant failed.\n"); result = -1; } } else { nn_log (LC_FATAL, "Initialization of configuration failed.\n"); result = -1; } } else { nn_log (LC_FATAL, "Could not create participant.\n"); result = -1; } u_participantQosFree (participantQos); } else { nn_log (LC_FATAL, "Could not allocate participantQos.\n"); result = -1; } os_mutexDestroy (&gluelock); /* Detach user layer */ mlv_setforreal (0); uresult = u_userDetach(); mlv_fini (); if(uresult != U_RESULT_OK){ nn_log (LC_FATAL, "Detachment of user layer failed.\n"); result = -1; } } else { nn_log (LC_FATAL, "Initialization of user layer failed.\n"); result = -1; } nn_log (LC_INFO, "Finis.\n"); /* Must be really late, or nn_log becomes unhappy -- but it should be before os_osExit (which appears to be called from u_userExit(), which is not called by u_userDetach but by an exit handler, it appears.) */ config_fini (); return result; }
static void nw_serviceMain( const char *serviceName, const char *URI) { u_serviceManager serviceManager; os_time sleepTime; os_result waitResult; nw_termination terminate; os_mutexAttr termMtxAttr; os_condAttr termCvAttr; c_bool fatal = FALSE; v_duration leasePeriod; terminate.terminate = FALSE; os_mutexAttrInit( & termMtxAttr ); os_condAttrInit( & termCvAttr ); termMtxAttr.scopeAttr = OS_SCOPE_PRIVATE; termCvAttr.scopeAttr = OS_SCOPE_PRIVATE; os_mutexInit( &terminate.mtx, &termMtxAttr ); os_condInit( &terminate.cv, &terminate.mtx, &termCvAttr ); /* Create networking service with kernel */ service = u_serviceNew(URI, NW_ATTACH_TIMEOUT, serviceName, NULL, U_SERVICE_NETWORKING, NULL); /* Initialize configuration */ nw_configurationInitialize(service, serviceName, URI); /* Ask service manager for splicedaemon state */ serviceManager = u_serviceManagerNew(u_participant(service)); /* Create the controller which starts the updating */ /* and calls the listener on a fatal error */ controller = nw_controllerNew(service,controller_onfatal,&fatal); if (controller) { os_procAtExit(on_exit_handler); /* Start the actual engine */ NW_REPORT_INFO(1, "Networking started"); NW_TRACE(Mainloop, 1, "Networking started"); nw_controllerStart(controller); /* Change state for spliced */ u_serviceChangeState(service, STATE_INITIALISING); u_serviceChangeState(service, STATE_OPERATIONAL); /* Get sleeptime from configuration */ nw_retrieveLeaseSettings(&leasePeriod, &sleepTime); /*sleepTime.tv_sec = 1; */ /* Loop until termination is requested */ u_serviceWatchSpliceDaemon(service, nw_splicedaemonListener, &terminate); os_mutexLock( &terminate.mtx ); while ((!(int)terminate.terminate) && (!(int)fatal) && (!(int)f_exit)) { /* Assert my liveliness and the Splicedaemon's liveliness*/ u_serviceRenewLease(service, leasePeriod); /* Check if anybody is still remotely interested */ nw_controllerUpdateHeartbeats(controller); /* Wait before renewing again */ waitResult = os_condTimedWait( &terminate.cv, &terminate.mtx, &sleepTime ); if (waitResult == os_resultFail) { OS_REPORT(OS_CRITICAL, "nw_serviceMain", 0, "os_condTimedWait failed - thread will terminate"); fatal = TRUE; } /* QAC EXPECT 2467; Control variable, terminate, not modified inside loop. That is correct, it is modified by another thread */ } os_mutexUnlock( &terminate.mtx ); /* keep process here waiting for the exit processing */ while ((int)f_exit){os_nanoSleep(sleepTime);} if (!(int)fatal ) { leasePeriod.seconds = 20; leasePeriod.nanoseconds = 0; u_serviceRenewLease(service, leasePeriod); u_serviceChangeState(service, STATE_TERMINATING); nw_controllerStop(controller); nw_controllerFree(controller); controller = NULL; NW_REPORT_INFO(1, "Networking stopped"); NW_TRACE(Mainloop, 1, "Networking stopped"); } } if (!(int)fatal ) { nw_configurationFinalize(); /* Clean up */ u_serviceChangeState(service, STATE_TERMINATED); u_serviceManagerFree(serviceManager); u_serviceFree(service); } }
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; }
static void* shmMonitorMain( void* arg) { os_sharedHandle shmHandle; u_result cleanupResult; os_result result; os_duration blockingTime = 10*OS_DURATION_MILLISECOND; os_shmClient clients, client; s_shmMonitor _this = (s_shmMonitor)arg; os_procId ownPID; ownPID = os_procIdSelf(); shmHandle = u_domainSharedMemoryHandle( u_participantDomain( u_participant( splicedGetService(_this->spliceDaemon)))); os_mutexLock(&_this->mutex); while(_this->terminate == OS_FALSE){ clients = NULL; os_mutexUnlock(&_this->mutex); ut_threadAsleep(_this->thr, 1); result = os_sharedMemoryWaitForClientChanges(shmHandle, blockingTime, &clients); os_mutexLock(&_this->mutex); if(result == os_resultSuccess){ client = clients; _this->shmState = SHM_STATE_UNKNOWN; while(client){ if(client->state == OS_SHM_PROC_TERMINATED){ if(client->procId != ownPID){ OS_REPORT(OS_WARNING, OSRPT_CNTXT_SPLICED, 0, "Detected termination of process %d, that failed " "to clean up its resources before terminating. " "Attempting to clean up its resources now..." , client->procId); os_mutexUnlock(&_this->mutex); /* Allow the u_splicedCleanupProcessInfo() to take as * long as MAX(leasePeriod, serviceTerminatePeriod). * This is set in the threadsMonitor as the threads * interval. * By indicating that it'll sleep for 1 second, it * is allowed to stay dormant for that 1 second plus * the threads interval. */ ut_threadAsleep(_this->thr, 1); cleanupResult = u_splicedCleanupProcessInfo(splicedGetService(_this->spliceDaemon), client->procId); os_mutexLock(&_this->mutex); if(cleanupResult != U_RESULT_OK){ OS_REPORT(OS_FATAL, OSRPT_CNTXT_SPLICED, 0, "Cleaning up resources of terminated process " "%d failed, because process was modifying " "shared resources when it terminated, " "stopping domain now...", client->procId); _this->shmState = SHM_STATE_UNCLEAN; os_condSignal(&_this->cleanCondition); splicedSignalTerminate(_this->spliceDaemon, SPLICED_EXIT_CODE_RECOVERABLE_ERROR, SPLICED_SHM_NOK); } else { OS_REPORT(OS_INFO, OSRPT_CNTXT_SPLICED, 0, "Successfully cleaned up resources of " "terminated process %d.", client->procId); } } else { OS_REPORT(OS_FATAL, OSRPT_CNTXT_SPLICED, 0, "Detected unexpected detach of kernel by my own " "process, stopping domain now..."); _this->shmState = SHM_STATE_UNCLEAN; os_condSignal(&_this->cleanCondition); splicedSignalTerminate(_this->spliceDaemon, SPLICED_EXIT_CODE_RECOVERABLE_ERROR, SPLICED_SHM_NOK); } ut_threadAwake(_this->thr); } client = client->next; } os_shmClientFree(clients); if (_this->shmState == SHM_STATE_UNKNOWN) { _this->shmState = SHM_STATE_CLEAN; os_condSignal(&_this->cleanCondition); } } else if (result == os_resultUnavailable) { /* client list is empty so we need to give up some cpu time * in order that it can be initialised on non timesliced systems * e.g. vxworks kernel builds */ ut_sleep(_this->thr, 100*OS_DURATION_MICROSECOND); } } os_mutexUnlock(&_this->mutex); return NULL; }
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; }
void in_serviceMain( const os_char* serviceName, const os_char* uri) { u_service service; in_config config; in_result result; u_serviceManager serviceManager; in_controller controller; v_duration leasePeriod; os_time sleepTime; os_boolean terminate = OS_FALSE; in_connectivityAdmin admin; assert(serviceName); assert(uri); /* Create networking service with kernel */ service = u_serviceNew( uri, IN_ATTACH_TIMEOUT, serviceName, NULL, U_SERVICE_NETWORKING, NULL); assert(service); /* Initialize configuration */ config = in_configGetInstance(); result = in_configConvertDomTree(config, uri, service); if(result == IN_RESULT_OK) { /* Ask service manager for splicedaemon state */ serviceManager = u_serviceManagerNew(u_participant(service)); admin = in_connectivityAdminGetInstance(); /* Create the controller which starts the updating */ controller = in_controllerNew(service); if (controller) { /* Start the actual engine */ IN_REPORT_INFO(1, "DDSI networking started"); IN_TRACE(Mainloop, 1, "DDSI networking started"); in_controllerStart(controller); /* Change state for spliced */ u_serviceChangeState(service, STATE_INITIALISING); u_serviceChangeState(service, STATE_OPERATIONAL); /* Get sleeptime from configuration */ in_retrieveLeaseSettings(&leasePeriod, &sleepTime); u_serviceRenewLease(service, leasePeriod); /* Loop until termination is requested */ u_serviceWatchSpliceDaemon( service, in_splicedaemonListener, &terminate); /* terminate flag is modified by the splice deamon listener thread*/ while (!terminate) { /* Assert my liveliness and the Splicedaemon's liveliness */ u_serviceRenewLease(service, leasePeriod); /* Wait before renewing again */ os_nanoSleep(sleepTime); } leasePeriod.seconds = 20; u_serviceRenewLease(service, leasePeriod); u_serviceChangeState(service, STATE_TERMINATING); in_controllerStop(controller); in_controllerFree(controller); IN_REPORT_INFO(1, "DDSI networking stopped"); IN_TRACE(Mainloop, 1, "DDSI networking stopped"); } u_serviceChangeState(service, STATE_TERMINATED); u_serviceManagerFree(serviceManager); in_objectFree(in_object(admin)); } /* Clean up */ in_configFree(config); u_serviceFree(service); }