Esempio n. 1
0
u_result
u_userAddDomain(
    u_domain domain)
{
    u_domainAdmin ka;
    u_user u;
    u_result result;
    os_sharedHandle shm;
    os_result osr;

    if(domain) {
        u = u__userLock();
        if(u){
            if (u->domainCount + 1 < MAX_DOMAINS) {
                shm = u_domainSharedMemoryHandle(domain);
                u->domainCount++;
                ka = &u->domainList[u->domainCount];
                ka->domain = domain;
                /* The keepList holds all domain references issues by
                 * u_userKeep().
                 * This list will keep the objects alive until the objects
                 * are removed by u_userFree() or when the domain is detached
                 * from the process e.g. when a process terminates.
                 */
                ka->keepList = NULL;
                ka->lowerBound = (c_address)os_sharedAddress(shm);
                osr = os_sharedSize(shm, (os_address*)&ka->upperBound);
                if (osr != os_resultSuccess) {
                    OS_REPORT(OS_ERROR,
                            "u_userAddDomain",0,
                            "shared memory size cannot be determined");
                    result = U_RESULT_INTERNAL_ERROR;
                } else {
                    result = U_RESULT_OK;
                }
                ka->upperBound += ka->lowerBound;
            } else {
                OS_REPORT_1(OS_ERROR,
                        "u_userAddDomain",0,
                        "Max connected Domains (%d) reached!", MAX_DOMAINS - 1);
                result = U_RESULT_OUT_OF_MEMORY;
            }
            u__userUnlock();
        } else {
            OS_REPORT(OS_ERROR,
                    "u_userAddDomain",0,
                    "User layer not initialized");
            result = U_RESULT_PRECONDITION_NOT_MET;
        }
    } else {
        OS_REPORT(OS_ERROR,
                  "u_userAddDomain",0,
                  "Invalid Domain specified: Domain = NULL");
        result = U_RESULT_ILL_PARAM;
    } /* Fail already reported by u_domainNew */

    return result;
}
Esempio n. 2
0
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;
}