Пример #1
0
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;
}
Пример #2
0
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;
    }
}
Пример #3
0
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;
}
Пример #4
0
/**
 * 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));
        }
    }
}
Пример #5
0
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;
}