static os_uint32 os__signalHandlerExitRequestCallbackInvoke( os_signalHandlerCallbackInfo *_this, os_callbackArg arg) { os_result osr; os_signalHandlerExitRequestCallbackInfo *cbExit; os_uint32 nrCallbacks = 0; assert(_this); os_mutexLock(&_this->exitRequestMtx); cbExit = _this->exitRequestCallbackInfo; /* Don't process handlers that have just been added, since we did not obtain * the proper context. */ while(cbExit){ os_signalHandlerThreadContextBuffer *contextBuffer = &(cbExit->contextBuffer[_this->exitRequestConsumptionIndex]); if (!cbExit->deregistered && cbExit->callbackExitRequest && (contextBuffer->contextAssigned || !cbExit->callbackGetThreadContext)) { osr = cbExit->callbackExitRequest(arg, contextBuffer->threadContext, cbExit->arg); nrCallbacks++; if(osr != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerThread", 0, "Exit request-callback returned: %s", os_resultImage(osr)); } } contextBuffer->contextAssigned = FALSE; cbExit = cbExit->next; } _this->exitRequestConsumptionIndex++; os_mutexUnlock(&_this->exitRequestMtx); return nrCallbacks; }
static void os__signalHandlerExceptionCallbackInvoke( os_signalHandlerCallbackInfo *_this) { os_result osr; os_signalHandlerExceptionCallbackInfo *cbException; assert(_this); /* Do not obtain _this->exceptionMtx here: the raising thread * blocks until we are done, and makes sure the Mutex is still * occupied so that nobody else can fiddle with the callback stack. */ cbException = _this->exceptionCallbackInfo; while(cbException){ if (cbException->callbackException){ osr = cbException->callbackException(cbException->threadContext, cbException->arg); if(osr != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerThread", 0, "Exception-callback returned: %s", os_resultImage(osr)); } } cbException = cbException->next; } }
os_boolean s_shmMonitorFree( s_shmMonitor _this) { os_boolean result = OS_TRUE; s_configuration config; os_result osr; if (_this != NULL) { config = splicedGetConfiguration(_this->spliceDaemon); os_mutexLock(&_this->mutex); _this->terminate = OS_TRUE; os_mutexUnlock(&_this->mutex); if (_this->thr != NULL) { osr = ut_threadTimedWaitExit(_this->thr, config->serviceTerminatePeriod, NULL); if (osr != os_resultSuccess) { OS_REPORT(OS_ERROR, OS_FUNCTION, osr, "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", ut_threadGetName(_this->thr), (os_address)os_threadIdToInteger(ut_threadGetId(_this->thr)), os_resultImage(osr)); result = OS_FALSE; } } if (result) { os_mutexDestroy(&_this->mutex); os_condDestroy(&_this->cleanCondition); os_free(_this); } } return result; }
/** * 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)); } } }
static os_result os_signalHandlerInit( os_signalHandler _this) { os_result result = os_resultSuccess; os_sigset block_all_sigset, old_sigset; unsigned i; int r; os_threadAttr thrAttr; assert(_this); _this->handleExceptions = OS_FALSE; if(os__signalHandlerCallbackInit(&_this->callbackInfo) != os_resultSuccess) { goto err_callbackInfoInit; } if(!isSignallingSafe(1)){ return os_resultSuccess; } /* Initialise the exceptionsMask */ sigemptyset(&exceptionsMask); for(i = 0; i < lengthof(exceptions); i++){ sigaddset(&exceptionsMask, exceptions[i]); } /* Initialise the quitsMask */ sigemptyset(&quitsMask); for(i = 0; i < quits_len; i++){ sigaddset(&quitsMask, quits[i]); } /* create signal handling pipes */ r = pipe(_this->pipeIn); if (r < 0) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "pipe(_this->pipeIn) failed, result = %d", r); goto err_pipeIn; } r = fcntl(_this->pipeIn[0], F_SETFD, 1); if (r < 0) { OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeIn[0]) failed, result = %d", r); goto err_pipeInFcntl; } r = fcntl(_this->pipeIn[1], F_SETFD, 1); if (r < 0) { OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeIn[1]) failed, result = %d", r); goto err_pipeInFcntl; } r = pipe(_this->pipeOut); if (r < 0) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 1, "pipe(_this->pipeOut) failed, result = %d", r); goto err_pipeOut; } r = fcntl(_this->pipeOut[0], F_SETFD, 1); if (r < 0) { OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeOut[0]) failed, result = %d", r); goto err_pipeOutFcntl; } r = fcntl(_this->pipeOut[1], F_SETFD, 1); if (r < 0) { OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeOut[1]) failed, result = %d", r); goto err_pipeOutFcntl; } /* Block all signals in order to start the signalHandlerThread with all * signals blocked. */ result = os_sigsetFill(&block_all_sigset); if (result != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigsetFill(&block_all_sigset) failed: %s", os_resultImage(result)); goto err_sigsetMask; } /* Remove signals that cannot be blocked. */ for (i = 0; i < lengthof(excludes); i++) { const int sig = excludes[i]; if (os_sigsetDel(&block_all_sigset, sig) != 0) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigsetDel(0x%"PA_PRIxADDR", %d) failed, result = %d", (os_address)&_this->action, sig, r); goto err_sigsetMask; } } result = os_sigThreadSetMask(&block_all_sigset, &old_sigset); if (result != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigThreadSetMask(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed: %s", (os_address)&block_all_sigset, (os_address)&old_sigset, os_resultImage(result)); goto err_sigsetMask; } /* Setup signal handler thread. */ os_threadAttrInit(&thrAttr); thrAttr.stackSize = 4*1024*1024; /* 4 MB */ result = os_threadCreate(&_this->threadId, "signalHandler", &thrAttr, signalHandlerThread, (void*)_this); if (result != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_threadCreate(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR",0x%"PA_PRIxADDR",0) failed: %s", (os_address)&_this->threadId, (os_address)&thrAttr, (os_address)signalHandlerThread, os_resultImage(result)); goto err_threadCreate; } /* Reset signal mask to original value. */ result = os_sigThreadSetMask(&old_sigset, NULL); if (result != os_resultSuccess) { OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigThreadSetMask(0x%"PA_PRIxADDR", NULL) failed: %s", (os_address)&old_sigset, os_resultImage(result)); goto err_sigResetMask; } /* install signal handlers */ _this->action = os_sigactionNew(signalHandler, &block_all_sigset, SA_SIGINFO); if (os_signalHandlerEnableExitSignals() != os_resultSuccess) { goto err_enableExitHandling; } return os_resultSuccess; /* Error handling */ err_enableExitHandling: err_sigResetMask: os__signalHandlerThreadStop(_this); err_threadCreate: (void) os_sigThreadSetMask(&old_sigset, NULL); err_sigsetMask: /* No undo needed for fcntl's/sigsetFill */ err_pipeOutFcntl: (void) close(_this->pipeOut[0]); (void) close(_this->pipeOut[1]); err_pipeOut: /* No undo needed for fcntl's */ err_pipeInFcntl: (void) close(_this->pipeIn[0]); (void) close(_this->pipeIn[1]); err_pipeIn: os__signalHandlerCallbackDeinit(&_this->callbackInfo); err_callbackInfoInit: return os_resultFail; }