Esempio n. 1
0
/**************************************************************
 * constructor/destructor
 **************************************************************/
u_service
u_serviceNew(
    const c_char *uri,
    c_long timeout,
    const c_char *name,
    const c_char *extendedStateName,
    u_serviceKind kind,
    v_qos qos)
{
    u_domain domain;
    v_kernel kk;
    v_service ks;
    v_serviceManager sm;
    u_service s;
    u_result r;
    os_result osr;
    c_bool serviceTermHandlerRequired = FALSE;

    ks = NULL;
    r = u_domainOpen(&domain, uri, timeout);
    if (r != U_RESULT_OK) {
        OS_REPORT_1(OS_ERROR,"u_serviceNew",0,
                  "Failure to open the kernel - return code %d", r);
        return NULL;
    }

    s = NULL;
    if (domain != NULL) {
        r = u_entityWriteClaim(u_entity(domain),(v_entity*)(&kk));
        if (r == U_RESULT_OK) {
            assert(kk);
            sm = v_getServiceManager(kk);
            if (sm != NULL) {
#ifndef INTEGRITY
                if (lockPages(kk, name)) {
                    osr = os_procMLockAll(OS_MEMLOCK_CURRENT|OS_MEMLOCK_FUTURE);
                } else {
                    osr = os_resultSuccess;
                }
                if (osr == os_resultSuccess) {
#endif
                    switch(kind){
                    case U_SERVICE_DDSI:
                    case U_SERVICE_DDSIE:
                    case U_SERVICE_NETWORKING:
                        ks = v_service(v_networkingNew(sm, name,
                                                       extendedStateName,
                                                       (v_participantQos)qos));
                        serviceTermHandlerRequired = TRUE;
                    break;
                    case U_SERVICE_DURABILITY:
                        ks = v_service(v_durabilityNew(sm, name,
                                                       extendedStateName,
                                                       (v_participantQos)qos));
                        serviceTermHandlerRequired = TRUE;
                    break;
                    case U_SERVICE_CMSOAP:
                        ks = v_service(v_cmsoapNew(sm, name,
                                                   extendedStateName,
                                                   (v_participantQos)qos));
                        serviceTermHandlerRequired = TRUE;
                    break;
                    case U_SERVICE_RNR:
                        ks = v_service(v_rnrNew(sm, name,
                                                extendedStateName,
                                                (v_participantQos)qos));
                        serviceTermHandlerRequired = TRUE;
                    break;
                    case U_SERVICE_DBMSCONNECT:
                    case U_SERVICE_INCOGNITO:
                        ks = v_serviceNew(sm, name,
                                          extendedStateName,
                                          (v_participantQos)qos, NULL);
                        serviceTermHandlerRequired = TRUE;
                    break;
                    case U_SERVICE_SPLICED:
                    break;
                    default:
                        OS_REPORT(OS_WARNING,"u_serviceNew",0,
                                  "Failed to start an unknown service kind");
                    break;
                    }
                } else {
                    OS_REPORT(OS_ERROR,"u_serviceNew",0,
                              "Failed to lock memory pages for current process");
                }

                /* Install the service signal handlers if spliced is not within this
                 * same process.  i.e. only do this if each service is in its own
                 * process so signal handlers won't interfere */
                if (serviceTermHandlerRequired && !u_splicedInProcess()) {
                    os_procSetTerminationHandler(serviceTermHandler);
                }

#ifndef INTEGRITY

            } else {
                OS_REPORT(OS_ERROR,"u_serviceNew",0,
                          "Failed to retrieve the Service Manager");
            }
#endif
            if (ks != NULL) {
                s = u_entityAlloc(NULL,u_service,ks,TRUE);
                r = u_serviceInit(s, kind, domain);
                if (r != U_RESULT_OK) {
                    OS_REPORT_1(OS_ERROR,"u_serviceNew",0,
                                "Failed to initialize service: %s", name);
                    u_serviceFree(s);
                    s = NULL;
                }
                callbackService = s;
                (void) os_signalHandlerSetExceptionCallback(u__serviceExceptionCallbackWrapper);
            } else {
                OS_REPORT(OS_WARNING,"u_serviceNew",0,
                          "Failed to retrieve the Service Manager");
            }
            r = u_entityRelease(u_entity(domain));
        }
    }
    return s;
}
Esempio n. 2
0
u_result
u_userInitialise(
    void)
{
    u_user u;
    u_result rm = U_RESULT_OK;
    os_mutexAttr mutexAttr;
    os_uint32 initCount;
    void* initUser;
    os_result osResult;
    os_signalHandlerExitRequestCallback exitRequestCallback;
    os_signalHandlerExceptionCallback exceptionCallback;

    initCount = pa_increment(&_ospl_userInitCount);
    /* If initCount == 0 then an overflow has occurred.
     * This can only realistically happen when u_userDetach()
     * is called more often than u_userInitialize().
     */
    assert(initCount != 0);

    os_osInit();
    if (initCount == 1) {
        /* Will start allocating the object, so it should currently be empty. */
        assert(user == NULL);

        /* Use indirection, as user != NULL is a precondition for user-layer
         * functions, so make sure it only holds true when the user-layer is
         * initialized. */
        initUser = os_malloc(sizeof(C_STRUCT(u_user)));
        if (initUser == NULL) {
            /* Initialization failed, so decrement the initialization counter. */
            pa_decrement(&_ospl_userInitCount);
            os_osExit();
            OS_REPORT(OS_ERROR, "u_userInitialise", 0,
                      "Allocation of user admin failed: out of memory.");
            rm = U_RESULT_OUT_OF_MEMORY;
        } else {
            u = u_user(initUser);
            os_mutexAttrInit(&mutexAttr);
            mutexAttr.scopeAttr = OS_SCOPE_PRIVATE;
            os_mutexInit(&u->mutex,&mutexAttr);
            osResult = os_signalHandlerNew();
            if(osResult != os_resultSuccess)
            {
                /* Initialization did not succeed, undo increment and return error */
                initCount = pa_decrement(&_ospl_userInitCount);
                OS_REPORT(OS_ERROR, "u_userInitialise", 0,
                      "Failed to create the signal handler. No proper signal handling can be performed.");
                rm = U_RESULT_INTERNAL_ERROR;
            } else
            {
                exitRequestCallback = os_signalHandlerSetExitRequestCallback(u__userExitRequestCallbackWrapper);
                if(exitRequestCallback && exitRequestCallback != u__userExitRequestCallbackWrapper)
                {
                    initCount = pa_decrement(&_ospl_userInitCount);
                    OS_REPORT(OS_ERROR, "u_userInitialise", 0,
                        "Replaced an exit request callback on the signal handler while this was not expected.");
                    rm = U_RESULT_INTERNAL_ERROR;
                }
                if(rm == U_RESULT_OK){
                    exceptionCallback = os_signalHandlerSetExceptionCallback(u__userExceptionCallbackWrapper);
                    if(exceptionCallback && exceptionCallback != u__userExceptionCallbackWrapper)
                    {
                        initCount = pa_decrement(&_ospl_userInitCount);
                        OS_REPORT(OS_ERROR, "u_userInitialise", 0,
                            "Replaced an exception callback on the signal handler while this was not expected.");
                        rm = U_RESULT_INTERNAL_ERROR;
                    }
                }
                if(rm == U_RESULT_OK)
                {
                    u->domainCount = 0;
                    u->protectCount = 0;
                    u->detachThreadId = OS_THREAD_ID_NONE;

                    /* This will mark the user-layer initialized */
                    user = initUser;
                }
            }
        }
    } else {
        if(user == NULL){
            os_time sleep = {0, 100000}; /* 100ms */
            /* Another thread is currently initializing the user-layer. Since
             * user != NULL is a precondition for calls after u_userInitialise(),
             * a sleep is performed, to ensure that (if succeeded) successive
             * user-layer calls will also actually pass.*/
            os_nanoSleep(sleep);
        }

        if(user == NULL){
            /* Initialization did not succeed, undo increment and return error */
            initCount = pa_decrement(&_ospl_userInitCount);
            OS_REPORT_1(OS_ERROR,"u_userInitialise",0,
                        "Internal error: User-layer should be initialized "
                        "(initCount = %d), but user == NULL (waited 100ms).",
                        initCount);
            rm = U_RESULT_INTERNAL_ERROR;
        }
    }
    return rm;
}