Пример #1
0
u_result
u_dispatcherInsertListener(
    u_dispatcher _this,
    u_dispatcherListener listener,
    c_voidp userData)
{
    u_listener ul;
    os_threadAttr attr;
    v_observer ke;
    u_result result = U_RESULT_OK;
    c_char *name;

    if ((_this != NULL) && (listener != NULL)) {
        os_mutexLock(&_this->mutex);
        ul = u_listenerNew(listener,userData);
        _this->listeners = c_iterInsert(_this->listeners,ul);

        if (os_threadIdToInteger(_this->threadId) == 0U) {
            result = u_entityReadClaim(u_entity(_this), (v_entity*)(&ke));
            if(result == U_RESULT_OK) {
                assert(ke);
                name = v_entityName(ke);
                if (name == NULL) {
                    name = "NoName";
                }
                os_threadAttrInit(&attr);
                os_threadCreate(&_this->threadId,
                                name,
                                &attr,dispatch,
                                (void *)_this);
                result = u_entityRelease(u_entity(_this));
                if (result != U_RESULT_OK) {
                    OS_REPORT(OS_ERROR, "u_dispatcherInsertListener", 0,
                              "Release observer failed.");
                }
            } else {
                OS_REPORT(OS_WARNING, "u_dispatcherInsertListener", 0,
                          "Failed to claim Dispatcher.");
            }
        }
        u_entityEnable(u_entity(_this));
        os_mutexUnlock(&_this->mutex);
    } else {
        OS_REPORT(OS_ERROR,"u_dispatcherInsertListener",0,
                  "Illegal parameter.");
        result = U_RESULT_ILL_PARAM;
    }

    return result;
}
Пример #2
0
d_groupCreationQueue
d_groupCreationQueueNew(
    d_admin admin)
{
    d_groupCreationQueue queue;
    os_result osr;
    os_threadAttr attr;

    assert(admin);

    queue = d_groupCreationQueue(os_malloc(C_SIZEOF(d_groupCreationQueue)));

    if(queue) {
        d_lockInit(d_lock(queue), D_GROUP_CREATION_QUEUE, d_groupCreationQueueDeinit);

        if(queue) {
            queue->groups                   = c_iterNew(NULL);
            queue->terminate                = FALSE;
            queue->admin                    = admin;
            queue->groupsToCreateVolatile   = 0;
            queue->groupsToCreateTransient  = 0;
            queue->groupsToCreatePersistent = 0;

            osr                             = os_threadAttrInit(&attr);

            if(osr == os_resultSuccess) {
                osr = os_threadCreate(&queue->actionThread, "groupCreationThread",
                                      &attr, (void*(*)(void*))d_groupCreationQueueRun,
                                      (void*)queue);

                if(osr != os_resultSuccess) {
                    d_groupCreationQueueFree(queue);
                    queue = NULL;
                }
            } else {
                d_groupCreationQueueFree(queue);
                queue = NULL;
            }
        }
    }
    return queue;
}
Пример #3
0
/* See header-file for */
unsigned int
DDS::DataReader_impl::set_ParallelReadThreadCount(
    unsigned int value
    )
{
    DDS::ReturnCode_t exc = DDS::RETCODE_OK;

    if(os_mutexLock(&dr_mutex) != os_resultSuccess) {
        OS_REPORT(OS_FATAL, "CCPP", 0, "Failed to claim mutex");
        exc = DDS::RETCODE_ERROR;
        goto fatal_mtx;
    }

    if(pdc){
       /* Signal eventual current threads to shutdown */
       pdc_terminateWorkers(pdc);
       /* Join threads */
       pdc_joinWorkers(workers, nrofWorkers);
       /* Assert that all threads are actually stopped, so the terminate flag is
       * reset (last one to stop will do this). */
       assert(pdc->terminate == 0);
       delete workers;
       workers = NULL;
       /* If the requested size is 0 or 1, this will both result in a single-threaded
        * copy, so we don't have to start any extra threads. If previously there
        * were threads created, we can now cleanup the context as well. */
       if(value <= 1){
           delete pdc;
           pdc = NULL;
       }
    }

    if(value > 1){
       if(!pdc){
           /* Create a parallelDemarshalling context. */
           try{
               if((pdc = new ccpp_parDemContext()) == NULL) {
                   exc = DDS::RETCODE_OUT_OF_RESOURCES;
                   goto err_out_of_resources;
               }
           } catch (::DDS::ReturnCode_t e){
               exc = e;
               goto err_out_of_resources;
           }
       }

       os_threadAttr thrAttrs;
       os_result result;

       if((result = os_threadAttrInit(&thrAttrs)) != os_resultSuccess){
           exc = DDS::RETCODE_ERROR;
           goto err_thr_attrs;
       }
       if((workers = new os_threadId[value - 1]) == NULL){
           exc = DDS::RETCODE_OUT_OF_RESOURCES;
           goto err_workers_alloc;
       }

       assert(pdcMainFnc);
       assert(nrofWorkers == 0);
       for(nrofWorkers = 0; nrofWorkers < (value - 1); nrofWorkers++){
           result = os_threadCreate(
                       &workers[nrofWorkers],
                       "parDemWorker", /* TODO: pretty name */
                       &thrAttrs,
                       pdcMainFnc,
                       (void*)pdc);
           if(result != os_resultSuccess){
               nrofWorkers--;
               /* If a thread was started (nrofWorkers > 0), then something
                * happened and we warn that not all threads could be started
                * (probably due to out of resources condition).
                * If no threads were started at all, an error occurred. */
               OS_REPORT_2(nrofWorkers ? OS_WARNING : OS_ERROR, "CCPP", result, "Starting a parallel demarshalling worker thread failed; %d out of %d requested threads are available for parallel demarshalling.", nrofWorkers + 1,  value);
               if(nrofWorkers == 0) {
                   exc = DDS::RETCODE_ERROR;
                   goto err_thread_start;
               } else {
                   break;
               }
           }
       }
    }

    os_mutexUnlock(&dr_mutex);
    /* When a ParallelReadThreadCount of x is requested only x - 1 threads are
     * started, since the application thread is performing read actions as well */
    return nrofWorkers + 1;

/* Error handling */
err_thread_start:
err_workers_alloc:
err_thr_attrs:
err_out_of_resources:
    os_mutexUnlock(&dr_mutex);
fatal_mtx:
    assert(exc != DDS::RETCODE_OK);
    throw exc;
}
Пример #4
0
static u_result
startMonitoring(
    const u_participant participant,
    const u_waitset waitset,
    const struct builtin_datareader_set *drset)
{
    c_iter events, topics;
    u_waitsetEvent event;
    c_time timeout;
    os_uint32 reportInterval;
    v_gid participantGid, publicationGid, subscriptionGid, gid;
    u_result result;
    u_dataReader dataReader;
    u_topic topic;
    c_iter vgroups;
    v_group vgroup;
    v_duration duration;
    c_long participantOffset, publicationOffset, subscriptionOffset;
    os_threadAttr attr;
    os_result osr;

    /*Resolve unique identifications of readers*/
    participantGid  = u_entityGid((u_entity)drset->participant_dr);
    publicationGid  = u_entityGid((u_entity)drset->publication_dr);
    subscriptionGid = u_entityGid((u_entity)drset->subscription_dr);

    /*Resolve topics to find offsets in the data. The offsets are used later on*/
    duration.seconds = 0;
    duration.nanoseconds = 0;

    topics = u_participantFindTopic(participant, V_PARTICIPANTINFO_NAME, duration);
    topic  = c_iterTakeFirst(topics);

    if(topic){
        result = u_entityAction(u_entity(topic), resolveOffset, &participantOffset);
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        in_printf(IN_LEVEL_SEVERE, "Could not resolve participant info offset.\n");
    }
    c_iterFree(topics);

    if(result == U_RESULT_OK){
        topics = u_participantFindTopic(participant, V_PUBLICATIONINFO_NAME, duration);
        topic  = c_iterTakeFirst(topics);

        if(topic){
            result = u_entityAction(u_entity(topic), resolveOffset, &publicationOffset);
        } else {
            result = U_RESULT_INTERNAL_ERROR;
            in_printf(IN_LEVEL_SEVERE, "Could not resolve publication info offset.\n");
        }
        c_iterFree(topics);
    }

    if(result == U_RESULT_OK){
        topics = u_participantFindTopic(participant, V_SUBSCRIPTIONINFO_NAME, duration);
        topic  = c_iterTakeFirst(topics);

        if(topic){
            result = u_entityAction(u_entity(topic), resolveOffset, &subscriptionOffset);
        } else {
            result = U_RESULT_INTERNAL_ERROR;
            in_printf(IN_LEVEL_SEVERE, "Could not resolve subscription info offset.\n");
        }
        c_iterFree(topics);
    }

    if(result == U_RESULT_OK){
        timeout.seconds     = 0;
        timeout.nanoseconds = 100 * 1000 * 1000; /*100 ms*/

        in_printf(IN_LEVEL_FINE, "Collecting initial entities...\n");
        result = handleParticipant(drset->participant_dr, participantOffset);

        if(result == U_RESULT_OK){
            result = handlePublication(drset->publication_dr, publicationOffset,
                    drset->participant_dr, participantOffset);

            if(result == U_RESULT_OK){
                result = handleSubscription(drset->subscription_dr, subscriptionOffset,
                        drset->participant_dr, participantOffset);

                if(result == U_RESULT_OK){
                    vgroups = v_serviceTakeNewGroups(service);
                    vgroup = (v_group)c_iterTakeFirst(vgroups);

                    while(vgroup && result == U_RESULT_OK){
                        result = handleGroup(service, vgroup);
                        c_free(vgroup);
                        vgroup = (v_group)c_iterTakeFirst(vgroups);
                    }
                    c_iterFree(vgroups);

                    if(result == U_RESULT_OK){
                        in_printf(IN_LEVEL_FINE, "Waiting for entities to be created/deleted...\n");
                    } else {
                        in_printf(IN_LEVEL_SEVERE, "Could not collect initial groups...\n");
                    }
                } else {
                    in_printf(IN_LEVEL_SEVERE, "Could not collect initial subscriptions...\n");
                }
            } else {
                in_printf(IN_LEVEL_SEVERE, "Could not collect initial publications...\n");
            }
        } else {
            in_printf(IN_LEVEL_SEVERE, "Could not collect initial participants...\n");
        }
    }

    osr = os_threadAttrInit(&attr);

    if(osr == os_resultSuccess){
        osr = os_threadCreate(&clientWriterThread,
                "clientWriterMonitor", &attr,
                in_discoveryClientWriterMonitor, NULL);

        if(osr != os_resultSuccess){
            result = U_RESULT_INTERNAL_ERROR;
        }
    } else {
        result = U_RESULT_INTERNAL_ERROR;
    }
    reportInterval = 0;

    while(result == U_RESULT_OK && !terminate){
        events = NULL;
        /*Wait for events to occur*/
        result = u_waitsetTimedWaitEvents(waitset, timeout, &events);

        if(result == U_RESULT_OK){
            event = (u_waitsetEvent)(c_iterTakeFirst(events));

            while(event){
                if(((event->events) & V_EVENT_DATA_AVAILABLE) ==
                    V_EVENT_DATA_AVAILABLE)
                {
                    if(event->entity){
                        dataReader = (u_dataReader)event->entity;
                        gid        = u_entityGid(event->entity);

                        if(v_gidCompare(gid, participantGid) == C_EQ){
                            result = handleParticipant(
                                    drset->participant_dr, participantOffset);
                        } else if(v_gidCompare(gid, subscriptionGid) == C_EQ){
                            result = handleSubscription(
                                    drset->subscription_dr, subscriptionOffset,
                                    drset->participant_dr, participantOffset);
                        } else if(v_gidCompare(gid, publicationGid) == C_EQ){
                            result = handlePublication(
                                    drset->publication_dr, publicationOffset,
                                    drset->participant_dr, participantOffset);
                        } else {
                            in_printf(IN_LEVEL_SEVERE,
                                    "This is impossible...at least in my understanding of the world.\n");
                            result = U_RESULT_INTERNAL_ERROR;
                        }
                    } else {
                        in_printf(IN_LEVEL_WARNING, "DATA_AVAILABLE (%d) but no entity.\n",
                                event->events);
                    }
                } else if(((event->events) & V_EVENT_NEW_GROUP) ==
                    V_EVENT_NEW_GROUP)
                {
                    vgroups = v_serviceTakeNewGroups(service);
                    vgroup = (v_group)c_iterTakeFirst(vgroups);

                    while(vgroup && result == U_RESULT_OK){
                        result = handleGroup(service, vgroup);
                        c_free(vgroup);
                        vgroup = (v_group)c_iterTakeFirst(vgroups);
                    }
                    c_iterFree(vgroups);
                } else {
                    in_printf(IN_LEVEL_SEVERE, "Received unexpected event %d.\n", event->events);
                    result = U_RESULT_INTERNAL_ERROR;
                }
                u_waitsetEventFree(event);
                event = (u_waitsetEvent)(c_iterTakeFirst(events));
            }
        } else if(result == U_RESULT_DETACHING){
            in_printf(IN_LEVEL_INFO, "Starting termination now...\n");
        } else if(result == U_RESULT_TIMEOUT){
            result = U_RESULT_OK;
        } else {
            in_printf(IN_LEVEL_SEVERE, "Waitset wait failed.\n");
        }
        if(events){/* events may be null if waitset was deleted */
            c_iterFree(events);
        }
        reportInterval++;

        if(reportInterval >= 5){
            /*reportEntities();*/
            reportInterval = 0;
        }
    }
    return result;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
0
/**************************************************************
 * 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;
}
Пример #9
0
static os_result
os_signalHandlerInit(
    os_signalHandler _this)
{
    os_result result = os_resultSuccess;
    os_sigaction action;
    os_sigset block_all_sigset, old_sigset;
    int i, r;

    if (_this == NULL) {
        result = os_resultFail;
    }
    _this->exitRequestCallback = (os_signalHandlerExitRequestCallback)0;
    _this->exceptionCallback = (os_signalHandlerExceptionCallback)0;


    if(isSignallingSafe(1)) {
        /* 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 < lengthof(quits); i++) {
            sigaddset(&quitsMask, quits[i]);
        }

        /* create signal handling pipes */
        if (result == os_resultSuccess) {
            r = pipe(_this->pipeIn);
            if (r<0) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "pipe(_this->pipeIn) failed, result = %d",
                            r);
                result = os_resultFail;
            } else {
                r = fcntl(_this->pipeIn[0], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeIn[0]) failed, result = %d", r);
                    assert(OS_FALSE);
                }
                r = fcntl(_this->pipeIn[1], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeIn[1]) failed, result = %d", r);
                    assert(OS_FALSE);
                }
            }
        }
        if (result == os_resultSuccess) {
            r = pipe(_this->pipeOut);
            if (r<0) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 1,
                            "pipe(_this->pipeOut) failed, result = %d",
                            r);
                result = os_resultFail;
            } else {
                r = fcntl(_this->pipeOut[0], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeOut[0]) failed, result = %d",
                                r);
                    assert(OS_FALSE);
                }
                r = fcntl(_this->pipeOut[1], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeOut[1]) failed, result = %d",
                                r);
                    assert(OS_FALSE);
                }
            }
        }
        /* Block all signals */
        if (result == os_resultSuccess) {
            result = os_sigsetFill(&block_all_sigset);
            if (result != os_resultSuccess) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigsetFill(&block_all_sigset) failed, result = %d",
                            r);
                assert(OS_FALSE);
            } else {
                result = os_sigThreadSetMask(&block_all_sigset, &old_sigset);
                if (result != os_resultSuccess) {
                    OS_REPORT_3(OS_ERROR,
                                "os_signalHandlerInit", 0,
                                "os_sigThreadSetMask(0x%x, 0x%x) failed, result = %d",
                                &block_all_sigset, &old_sigset, r);
                    assert(OS_FALSE);
                }
            }
        }
        /* Setup signal handler thread. */
        if (result == os_resultSuccess) {
            os_threadAttr thrAttr;

            result = os_threadAttrInit(&thrAttr);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "pthread_attr_init(0x%x) failed, result = %d",
                            &thrAttr, r);
                assert(OS_FALSE);
            } else {
                thrAttr.stackSize = 4*1024*1024; /* 4 MB */
                result = os_threadCreate(&_this->threadId,
                                         "signalHandler",
                                         &thrAttr,
                                         signalHandlerThread,
                                         (void*)_this);

                if (result != os_resultSuccess) {
                    OS_REPORT_4(OS_ERROR,
                                "os_signalHandlerInit", 0,
                                "os_threadCreate(0x%x, 0x%x,0x%x,0) failed, result = %d",
                                &_this->threadId,
                                &thrAttr,
                                signalHandlerThread,
                                result);
                    assert(OS_FALSE);
                }
            }
        }
        /* Reset signal mask to original value. */
        if (result == os_resultSuccess) {
            result = os_sigThreadSetMask(&old_sigset, NULL);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigThreadSetMask(0x%x, NULL) failed, result = %d",
                            &old_sigset, r);
                result = os_resultFail;
                assert(OS_FALSE);
            }
        }
        /* install signal handlers */
        if (result == os_resultSuccess) {
            os_sigset mask;
            /* block all signals during handling of a signal */
            result = os_sigsetFill(&mask);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigsetFill(0x%x) failed, result = %d",
                            &action.sa_mask, result);
            } else {
                action = os_sigactionNew(signalHandler, &mask, SA_SIGINFO);
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(exceptions); i++) {
                    const int sig = exceptions[i];
                    r = os_sigsetDel(&action.sa_mask, sig);
                    if (r<0) {
                        OS_REPORT_3(OS_ERROR,
                                    "os_signalHandlerInit", 0,
                                    "os_sigsetDel(0x%x, %d) failed, result = %d",
                                    &action, sig, r);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(exceptions); i++) {
                    const int sig = exceptions[i];
                    /* For exceptions we always set our own signal handler, since
                     * applications that cause an exception are not in a position
                     * to ignore it. However, we will chain the old handler to our
                     * own.
                     */
                    r = os_sigactionSet(sig, &action, &old_signalHandler[sig]);
                    if (r < 0) {
                        OS_REPORT_4(OS_ERROR,
                                    "os_signalHandlerInit", 0,
                                    "os_sigactionSet(%d, 0x%x, 0x%x) failed, result = %d",
                                    sig, &action, &old_signalHandler[sig], r);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(quits); i++) {
                    const int sig = quits[i];
                    /* By passing NULL we only retrieve the currently set handler. If
                     * the signal should be ignored, we don't do anything. Otherwise we
                     * chain the old handler to our own.
                     * man-page of sigaction only states behaviour when new
                     * action is non-NULL, but all known implementations act as
                     * expected. That is: return the currently set signal-hand-
                     * ler (and not the previous, as the man-pages state).
                     * NOTE: Not MT-safe */
                    r = os_sigactionSet(sig, NULL, &old_signalHandler[sig]);
                    if (r == 0) {
                        if(old_signalHandler[sig].sa_handler != SIG_IGN) {
                            /* We don't know if the oldHandler has been modified in the mean
                             * time, since there is no way to make the signal handler reentrant.
                             * It doesn't make sense to look for modifications now, since a
                             * new modification could be on its way while we are processing
                             * the current modification.
                             * For that reason we will ignore any intermediate modifications
                             * and continue setting our own handler. Processes should therefore
                             * refrain from modifying the signal handler in multiple threads.
                             */
                            r = os_sigactionSet(sig, &action, NULL);
                            if (r != 0) {
                                OS_REPORT_4(OS_ERROR,
                                            "os_signalHandlerInit", 0,
                                            "os_sigactionSet(%d, 0x%x, 0x%x) failed, result = %d",
                                            sig, &action, &old_signalHandler[sig], r);
                                result = os_resultFail;
                                assert(OS_FALSE);
                            }
                        } else {
                            OS_REPORT_1(OS_INFO,
                                        "os_signalHandlerThread", 0,
                                        "Not installing a signal handler for the already ignored signal %d.",
                                        sig);
                        }
                    } else {
                        OS_REPORT_1(OS_ERROR, "os_signalHandlerInit", 0, "Could not retrieve currently set signal-handler for signal %d", sig);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
        }
    } else {
        result = os_resultSuccess;
    }
    return result;
}