void d_waitsetDeinit( d_object object) { d_waitset waitset; d_waitsetEntity we; d_waitsetHelper helper; assert(d_objectIsValid(object, D_WAITSET) == TRUE); if(object){ waitset = d_waitset(object); waitset->terminate = TRUE; if(waitset->runToCompletion == TRUE){ if(os_threadIdToInteger(waitset->thread)) { u_waitsetNotify(waitset->uwaitset, NULL); os_threadWaitExit(waitset->thread, NULL); } } else { if(waitset->threads){ helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); while(helper){ helper->terminate = TRUE; u_waitsetNotify(helper->userWaitset, NULL); os_threadWaitExit(helper->tid, NULL); u_waitsetDetach(helper->userWaitset, u_entity(helper->entity->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); } c_iterFree(waitset->threads); waitset->threads = NULL; } } d_lockLock(d_lock(waitset)); if(waitset->entities) { we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); while(we) { if(waitset->runToCompletion == TRUE){ u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher)); } d_waitsetEntityFree(we); we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); } c_iterFree(waitset->entities); } if(waitset->runToCompletion == TRUE){ if(waitset->uwaitset) { u_waitsetFree(waitset->uwaitset); } } d_lockUnlock(d_lock(waitset)); } }
u_result u_dispatcherDeinit( u_dispatcher _this) { v_observer ko; u_listener listener; os_threadId tid; u_result result = U_RESULT_OK; if (_this != NULL) { os_mutexLock(&_this->mutex); listener = u_listener(c_iterTakeFirst(_this->listeners)); while (listener != NULL) { u_listenerFree(listener); listener = u_listener(c_iterTakeFirst(_this->listeners)); } c_iterFree(_this->listeners); _this->listeners = NULL; /* Flags the dispatch thread to stop */ if (os_threadIdToInteger(_this->threadId) != 0U) { tid = _this->threadId; result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ko)); if(result != U_RESULT_OK) { /* This is a valid situation when a participant has been * freed prior to the freeing of a dispatcher within the * participant. */ os_mutexUnlock(&_this->mutex); os_threadWaitExit(tid, NULL); os_mutexDestroy(&_this->mutex); /*return U_RESULT_INTERNAL_ERROR;*/ } else { /* Wakeup the dispatch thread */ v_observerLock(ko); v_observerNotify(ko, NULL, NULL); v_observerUnlock(ko); u_entityRelease(u_entity(_this)); os_mutexUnlock(&_this->mutex); os_threadWaitExit(tid, NULL); os_mutexDestroy(&_this->mutex); } } else { os_mutexUnlock(&_this->mutex); os_mutexDestroy(&_this->mutex); } result = u_entityDeinit(u_entity(_this)); } else { OS_REPORT(OS_ERROR,"u_dispatcherDeinit",0, "Illegal parameter."); result = U_RESULT_ILL_PARAM; } return result; }
void s_kernelManagerFree( s_kernelManager km) { u_result r; v_spliced s; if (km) { /* km might be NULL, when spliced has detected other spliced */ os_threadWaitExit(km->id, NULL); os_threadWaitExit(km->resendManager, NULL); u_splicedCAndMCommandDispatcherQuit(km->spliced); os_threadWaitExit(km->cAndMCommandManager, NULL); os_condDestroy(&km->cv); os_mutexDestroy(&km->mtx); os_free(km); } }
/** * Joins the worker-threads and only returns if all threads are stopped or returned * an error. * @param[in] workers the array of threads to join * @param[in/out] nrofWorkers the number of elements in workers, decremented to 0. * @pre dr_mutex locked * @post nrofWorkers == 0 */ static void pdc_joinWorkers( os_threadId * workers, unsigned int &nrofWorkers) { while(nrofWorkers != 0){ os_result osresult; if((osresult = os_threadWaitExit(workers[--nrofWorkers], NULL)) != os_resultSuccess){ OS_REPORT_1(OS_WARNING, "CCPP", osresult, "Failed to join worker thread; os_threadWaitExit returned %s", os_resultImage(osresult)); } } }
u_result u_dispatcherRemoveListener( u_dispatcher _this, u_dispatcherListener listener) { u_listener ul; v_observer ko; os_threadId tid; u_result result = U_RESULT_OK; struct compareArg arg; if ((_this != NULL) && (listener != NULL)) { os_mutexLock(&_this->mutex); arg.listener = listener; ul = (u_listener) c_iterResolve(_this->listeners, compare, &arg); tid = _this->threadId; if (ul != NULL) { c_iterTake(_this->listeners, ul); if (c_iterLength(_this->listeners) == 0) { result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ko)); if(result == U_RESULT_OK) { assert(ko); /* Wakeup the dispatch thread */ v_observerLock(ko); v_observerNotify(ko, NULL, NULL); v_observerUnlock(ko); result = u_entityRelease(u_entity(_this)); if (result != U_RESULT_OK) { OS_REPORT(OS_ERROR, "u_dispatcherRemoveListener", 0, "Release observer failed."); } } else { OS_REPORT(OS_WARNING, "u_dispatcherRemoveListener", 0, "Failed to claim Dispatcher."); } } u_listenerFree(ul); } os_mutexUnlock(&_this->mutex); if ((c_iterLength(_this->listeners) == 0) && (os_threadIdToInteger(tid) != 0U)) { os_threadWaitExit(tid, NULL); } } else { OS_REPORT(OS_ERROR,"u_dispatcherInsertListener",0, "Illegal parameter."); result = U_RESULT_ILL_PARAM; } return result; }
c_bool d_waitsetDetach( d_waitset waitset, d_waitsetEntity we) { u_result ur; c_bool result = FALSE; int i; d_waitsetHelper helper; helper = NULL; 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(c_iterContains(waitset->entities, we) == TRUE) { if(waitset->runToCompletion == TRUE){ ur = u_waitsetDetach(waitset->uwaitset, u_entity(we->dispatcher)); } else { for(i=0; i<c_iterLength(waitset->threads) && !helper; i++){ helper = d_waitsetHelper(c_iterObject(waitset->threads, i)); if(helper->entity != we){ helper = NULL; } } assert(helper); c_iterTake(waitset->threads, helper); helper->terminate = TRUE; u_waitsetNotify(helper->userWaitset, NULL); os_threadWaitExit(helper->tid, NULL); ur = u_waitsetDetach(helper->userWaitset, u_entity(we->dispatcher)); u_waitsetFree(helper->userWaitset); os_free(helper); } if(ur == U_RESULT_OK) { c_iterTake(waitset->entities, we); we->waitset = NULL; result = TRUE; } } d_lockUnlock(d_lock(waitset)); } return result; }
void d_groupCreationQueueDeinit( d_object object) { d_groupCreationQueue queue; assert(d_objectIsValid(object, D_GROUP_CREATION_QUEUE) == TRUE); if(object) { queue = d_groupCreationQueue(object); if(os_threadIdToInteger(queue->actionThread)) { queue->terminate = TRUE; os_threadWaitExit(queue->actionThread, NULL); } if(queue->groups){ c_iterFree(queue->groups); } } }
static void os__signalHandlerThreadStop( os_signalHandler _this) { struct sig_context info; void *thread_result; assert(_this); memset (&info, 0, sizeof(info)); info.info.si_signo = SIGNAL_THREAD_STOP; if (write(_this->pipeIn[1], &info, sizeof(info)) < 0) { /* ignore result */ } /* When the signalHandlerThread itself is the exiting thread (this can happen * when an exit call is done in a signalHandler installed by a customer for * example), we should not invoke os_threadWaitExit but just let this call * return immediately. */ if (os_threadIdSelf() != _this->threadId ) { (void) os_threadWaitExit(_this->threadId, &thread_result); } }
void os_signalHandlerFree( void) { #if !defined INTEGRITY && !defined VXWORKS_RTP void *thread_result; int i, r; os_signalHandler _this = signalHandlerObj; struct sig_context info; if (isSignallingSafe(0) && _this) { for (i=0; i<lengthof(exceptions); i++) { const int sig = exceptions[i]; r = os_sigactionSet(sig, &old_signalHandler[sig], NULL); if (r<0) { OS_REPORT_3(OS_ERROR, "os_signalHandlerFree", 0, "os_sigactionSet(%d, 0x%x, NULL) failed, result = %d", sig, &old_signalHandler[sig], r); assert(OS_FALSE); } } memset (&info, 0, sizeof(info)); info.info.si_signo = SIGNAL_THREAD_STOP; r = write(_this->pipeIn[1], &info, sizeof(info)); /* when signalhandler is the exiting thread itself, this can happen when an exit call is done in the signalhandler of the customer * do not call os_threadWaitExit but just let this thread run out of its main function */ if (os_threadIdSelf() != _this->threadId ) { os_threadWaitExit(_this->threadId, &thread_result); } close(_this->pipeIn[0]); close(_this->pipeIn[1]); close(_this->pipeOut[0]); close(_this->pipeOut[1]); os_free(_this); signalHandlerObj = NULL; } #endif }
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; }