/************************************************************** * Protected functions **************************************************************/ s_kernelManager s_kernelManagerNew( spliced daemon) { s_kernelManager km; s_configuration config; os_mutexAttr mtxAttr; os_condAttr cvAttr; int status; os_result osr; status = 0; km = os_malloc((os_uint32)C_SIZEOF(s_kernelManager)); if (km) { km->spliced = splicedGetService(daemon); km->active = 0; osr = os_mutexAttrInit(&mtxAttr); if (osr == os_resultSuccess) { mtxAttr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_mutexInit(&km->mtx, &mtxAttr); } else { status++; } if (osr == os_resultSuccess) { osr = os_condAttrInit(&cvAttr); if (osr == os_resultSuccess) { cvAttr.scopeAttr = OS_SCOPE_PRIVATE; osr = os_condInit(&km->cv, &km->mtx, &cvAttr); } else { os_mutexDestroy(&km->mtx); /* don't care if this succeeds, already in error situation */ status++; } if (osr == os_resultSuccess) { config = splicedGetConfiguration(daemon); osr = os_threadCreate(&km->id, S_THREAD_KERNELMANAGER, &config->kernelManagerScheduling, kernelManager, km); if (osr != os_resultSuccess) { /* don't care if the following statements succeeds, already in error situation */ os_mutexDestroy(&km->mtx); os_condDestroy(&km->cv); status++; } } if (osr == os_resultSuccess) { config = splicedGetConfiguration(daemon); osr = os_threadCreate(&km->resendManager, S_THREAD_RESENDMANAGER, &config->resendManagerScheduling, resendManager, km); if (osr != os_resultSuccess) { /* don't care if the following statements succeeds, already in error situation */ os_mutexDestroy(&km->mtx); os_condDestroy(&km->cv); status++; } } if (osr == os_resultSuccess ) { config = splicedGetConfiguration(daemon); if (config->enableCandMCommandThread ) { osr = os_threadCreate(&km->cAndMCommandManager, S_THREAD_C_AND_M_COMMANDMANAGER, &config->cAndMCommandScheduling, cAndMCommandManager, km); if (osr != os_resultSuccess) { /* don't care if the following statements succeeds, already in error situation */ os_mutexDestroy(&km->mtx); os_condDestroy(&km->cv); status++; } } } } else { status++; } } if (status && km) { os_free(km); km = NULL; } return km; }
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; }