Exemple #1
0
os_result
os_procUnregisterThread()
{
    os_result rv = os_resultSuccess;
    os_threadSetValidity(os_threadIdSelf(), thread_ValExit);
    return (rv);
}
Exemple #2
0
c_syncResult
c_condTimedWait (
    c_cond *cnd,
    c_mutex *mtx,
    const c_time time)
{
    os_result result;
    os_time t;

    t.tv_sec = time.seconds;
    t.tv_nsec = time.nanoseconds;
#ifdef NDEBUG
    result = os_condTimedWait(cnd,mtx,&t);
#else
    mtx->owner = OS_THREAD_ID_NONE;
    result = os_condTimedWait(cnd,&mtx->mtx,&t);
    mtx->owner = os_threadIdSelf();
#endif
#if 1
    /* TODO: Remove temporary workaround to prevent spinning
     * applications and come up with an actual fix.
     */
    wait_on_error(result);
#endif
    if((result != os_resultSuccess) && (result != os_resultTimeout)){
        OS_REPORT_1(OS_ERROR, "c_condWait", 0, "os_condWait failed; os_result = %d.", result);
        assert((result == os_resultSuccess) || (result == os_resultTimeout));
    }
    return result;
}
Exemple #3
0
/* This method will lock the user-layer and return the reference to the user-layer object if successful.
 * If this method returns NULL then the user-layer is either not initialized or
 * the process is detaching (process termination).
 */
static u_user
u__userLock(void)
{
    u_user u;
    os_result r = os_resultFail;

    u = u_user(user);
    if (u) {
        r = os_mutexLock(&u->mutex);
        if (r != os_resultSuccess) {
            /* The mutex is not valid so apparently the user-layer is either
             * destroyed or in process of destruction. */
            u = NULL;
        } else if ((os_threadIdToInteger(u->detachThreadId) != 0) &&
                   (os_threadIdToInteger(u->detachThreadId) !=
                    os_threadIdToInteger(os_threadIdSelf())))
        {
            /* Another thread is busy destroying the user-layer or the user-
             * layer is already destroyed. No access is allowed (anymore).
             * The user-layer object will be unlocked and will return null.
             */
            os_mutexUnlock(&u->mutex);
            u = NULL;
        }
    } else {
        /* The user-layer is not created or destroyed i.e. non existent, therefore return null. */
        OS_REPORT(OS_ERROR, "User Layer", 0, "User layer not initialized");
    }
    return u;
}
Exemple #4
0
c_syncResult
c_mutexLock (
    c_mutex *mtx)
{
    os_result result;

#ifdef NDEBUG
    result = os_mutexLock(mtx);
#else
    result = os_mutexLock(&mtx->mtx);
    if ( result == os_resultSuccess )
    {
       mtx->owner = os_threadIdSelf();
    }
#endif
#if 1
    /* TODO: Remove temporary workaround to prevent spinning
     * applications and come up with an actual fix.
     */
    wait_on_error(result);
#endif
    if(result != os_resultSuccess) {
        OS_REPORT_1(OS_ERROR, "c_mutexLock", 0, "os_mutexLock failed; os_result = %d.", result);
        assert(result == os_resultSuccess);
    }

    return result;
}
Exemple #5
0
/** \brief Terminate the process and return the status
 *         the the parent process
 *
 * \b os_procExit terminates the process by calling \b exit.
 */
void
os_procExit(
    os_exitStatus status)
{
    os_procContextData currentProcContext = (os_procContextData)readTLSVarSelf(procContextData);
    os_procLocalExit(status);
    os_threadDeleteTaskVar(taskIdSelf(), os_threadIdSelf());
    os_procDeleteTaskVar(taskIdSelf(), "task", currentProcContext);
    exit(status);
}
Exemple #6
0
static void
u__userDetach(
    void)
{
    u_user u;
    u_domain domain;
    u_result r;
    c_long i;

    u = u__userLock();
    if (u) {
        /* Disable access to user-layer for all other threads except for this thread.
         * Any following user access from other threads is gracefully
         * aborted.
         */
        u->detachThreadId = os_threadIdSelf();
        /* Unlock the user-layer
         * Part of following code requires to unlock the user object
         * This is allowed now all other threads will abort when
         * trying to claim the lock
         */
        u__userUnlock();

        for (i = 1; (i <= u->domainCount); i++) {
            domain = u->domainList[i].domain;
            if (domain) {
                r = u_domainDetachParticipants(domain);
                if (r != U_RESULT_OK) {
                    OS_REPORT_2(OS_ERROR,
                                "user::u_user::u_userDetach", 0,
                                "Operation u_domainDetachParticipants(0x%x) failed."
                                OS_REPORT_NL "result = %s",
                                domain, u_resultImage(r));
                } else {
                    r = u_domainFree(domain);
                    if (r != U_RESULT_OK) {
                        OS_REPORT_2(OS_ERROR,
                                    "user::u_user::u_userDetach", 0,
                                    "Operation u_domainFree(0x%x) failed."
                                    OS_REPORT_NL "result = %s",
                                    domain, u_resultImage(r));
                    }
                }
            }
        }
        /*        user = NULL;
         * ES: This was set to NULL here by RP, but this causes  errors later on
         * when u_userExit is performed. So commented this out here. As I can
         * not explain why we would need to set it to NULL here.
         */

    }
}
Exemple #7
0
os_result
os_procRegisterThread(
    os_procContextData process_procContextData)
{
    os_result rv;

    if (os_iterInsert(process_procContextData->procThreadList, (void *)os_threadIdSelf()) != NULL) {
        rv = os_resultSuccess;
    } else {
        rv = os_resultFail;
    }
    return (rv);
}
Exemple #8
0
/* This method will unlock the user-layer.
 */
static void
u__userUnlock(void)
{
    u_user u;

    u = u_user(user);
    if (u) {
        if ((os_threadIdToInteger(u->detachThreadId) == 0) ||
            (os_threadIdToInteger(u->detachThreadId) ==
             os_threadIdToInteger(os_threadIdSelf()))) {
            os_mutexUnlock(&u->mutex);
        }
    }
}
Exemple #9
0
c_syncResult
c_lockTryWrite (
    c_lock *lck)
{
    os_result result;
#ifdef NDEBUG
    result = os_rwlockTryWrite(lck);
#else
    result = os_rwlockTryWrite(&lck->lck);
    lck->owner = os_threadIdSelf();
#endif
    if ((result != os_resultSuccess) && (result != os_resultBusy)) {
        OS_REPORT_1(OS_ERROR, "c_lockTryWrite", 0, "os_rwlockTryWrite failed; os_result = %d.", result);
        assert((result == os_resultSuccess) || (result == os_resultBusy));
    }
    return result;
}
Exemple #10
0
c_syncResult
c_mutexUnlock (
    c_mutex *mtx)
{
    os_result result;

#ifdef NDEBUG
    result = os_mutexUnlock(mtx);
#else
    assert( os_threadIdToInteger(mtx->owner) ==
            os_threadIdToInteger(os_threadIdSelf()) );
    mtx->owner = OS_THREAD_ID_NONE;
    result = os_mutexUnlock(&mtx->mtx);
#endif
    if(result != os_resultSuccess){
        OS_REPORT_1(OS_ERROR, "c_mutexUnlock", 0, "os_mutexUnlock failed; os_result = %d.", result);
        assert(result == os_resultSuccess);
    }
    return result;
}
Exemple #11
0
c_syncResult
c_mutexTryLock (
    c_mutex *mtx)
{
    os_result result;

#ifdef NDEBUG
    result = os_mutexTryLock(mtx);
#else
    result = os_mutexTryLock(&mtx->mtx);
    if ( result == os_resultSuccess )
    {
       mtx->owner = os_threadIdSelf();
    }
#endif
    if ((result != os_resultSuccess) && (result != os_resultBusy)) {
        OS_REPORT_1(OS_ERROR, "c_mutexTryLock", 0, "os_mutexTryLock failed; os_result = %d.", result);
        assert((result == os_resultSuccess) || (result == os_resultBusy));
    }
    return result;
}
Exemple #12
0
/**
 * Returns if the current thread is the signalHandlerThread.
 *
 * @remarks Do not perform any signal-handling context unsafe operations in this
 * function.
 *
 * @return OS_TRUE if the current thread is the signalHandlerThread, or
 *         OS_FALSE if it's not.
 */
static os_boolean
inSignalHandlerThread (void)
{
    os_int match;
    os_signalHandler _this = signalHandlerObj;

#ifndef NDEBUG
    /* Assert preconditions (regular assert may trigger this action, so it
     * is not used here). */
    if (_this == NULL) {
        const char panicmsg[] = "Assertion failed: _this != NULL in " __FILE__ ":inSignalHandlerThread\n";
        panic(panicmsg, sizeof(panicmsg) - 1);
        /* This line will not be reached anymore */
    }
#endif

    match = os_threadIdToInteger (_this->threadId) ==
        os_threadIdToInteger (os_threadIdSelf ());

    return match ? OS_TRUE : OS_FALSE;
}
Exemple #13
0
static os_result
os_procWrapper(
    os_procContextData process_procContextData,
    char *executable_file,
    os_int32 *startRoutine,
    const char *arguments,
    TASK_ID parent,
    os_sem_t *blockParent)
{
    int taskid;
    os_int32 status = os_resultSuccess;
    os_int32 routine_status = -1;
    os_int32 (*this_startRoutine)(const char *);

#if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR > 8 )
      envPrivateCreate(taskIdSelf(), parent);
      os_sem_post(blockParent);
#endif

    taskid = taskIdSelf();
    os_procSetTaskId(process_procContextData, taskid);
    /* create & set context variable for the task */
    status = os_procAddTaskVar(taskid, executable_file, process_procContextData, 0);
    if (status == os_resultSuccess) {
        status = os_threadNew(process_procContextData->procName);
    }
    if (status == os_resultSuccess) {
        this_startRoutine = (os_int32 *)startRoutine;
        routine_status = this_startRoutine(arguments);
        os_procLocalExit(OS_EXIT_SUCCESS);
        os_threadDeleteTaskVar(taskid, os_threadIdSelf());
        os_procDeleteTaskVar(taskid, executable_file, process_procContextData);
        os_procSetExitValue(process_procContextData, routine_status);
    }

#if ( _WRS_VXWORKS_MAJOR > 6 ) || ( _WRS_VXWORKS_MAJOR > 6 && _WRS_VXWORKS_MINOR > 8 )
      envPrivateDestroy(taskIdSelf());
#endif
    return (status);
}
Exemple #14
0
static void
os__signalHandlerThreadStop(
        os_signalHandler _this)
{
    struct sig_context info;
    void *thread_result;

    assert(_this);

    memset (&info, 0, sizeof(info));
    info.info.si_signo = SIGNAL_THREAD_STOP;
    if (write(_this->pipeIn[1], &info, sizeof(info)) < 0) {
        /* ignore result */
    }
    /* When the signalHandlerThread itself is the exiting thread (this can happen
     * when an exit call is done in a signalHandler installed by a customer for
     * example), we should not invoke os_threadWaitExit but just let this call
     * return immediately. */
    if (os_threadIdSelf() != _this->threadId ) {
        (void) os_threadWaitExit(_this->threadId, &thread_result);
    }
}
void
os_signalHandlerFree(
    void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    void *thread_result;
    int i, r;
    os_signalHandler _this = signalHandlerObj;
    struct sig_context info;

    if (isSignallingSafe(0) && _this) {
        for (i=0; i<lengthof(exceptions); i++) {
            const int sig = exceptions[i];
            r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
            if (r<0) {
                OS_REPORT_3(OS_ERROR,
                            "os_signalHandlerFree", 0,
                            "os_sigactionSet(%d, 0x%x, NULL) failed, result = %d",
                            sig, &old_signalHandler[sig], r);
                assert(OS_FALSE);
            }
        }
        memset (&info, 0, sizeof(info));
        info.info.si_signo = SIGNAL_THREAD_STOP;
        r = write(_this->pipeIn[1], &info, sizeof(info));
        /* when signalhandler is the exiting thread itself, this can happen when an exit call is done in the signalhandler of the customer
         * do not call os_threadWaitExit but just let this thread run out of its main function */
        if (os_threadIdSelf() != _this->threadId ) {
            os_threadWaitExit(_this->threadId, &thread_result);
        }
        close(_this->pipeIn[0]);
        close(_this->pipeIn[1]);
        close(_this->pipeOut[0]);
        close(_this->pipeOut[1]);
        os_free(_this);
        signalHandlerObj = NULL;
    }
#endif
}
Exemple #16
0
c_syncResult
c_lockWrite (
    c_lock *lck)
{
    os_result result;
#ifdef NDEBUG
    result = os_rwlockWrite(lck);
#else
    result = os_rwlockWrite(&lck->lck);
    lck->owner = os_threadIdSelf();
#endif
#if 1
    /* TODO: Remove temporary workaround to prevent spinning
     * applications and come up with an actual fix.
     */
    wait_on_error(result);
#endif
    if(result != os_resultSuccess){
        OS_REPORT_1(OS_ERROR, "c_lockWrite", 0, "os_rwlockWrite failed; os_result = %d.", result);
        assert(result == os_resultSuccess);
    }
    return result;
}
Exemple #17
0
/**
 * This is the signal-handler routine that is performed in case of a signal. It
 * distinguishes:
 * - synchronous:
 *     - exceptions
 * - asynchronous:
 *     - exceptions
 *     - quits (termination requests).
 *
 * @remarks Do not perform any signal-handling context unsafe operations in this
 * function.
 */
static void
signalHandler(
    int sig,
    siginfo_t *info,
    void* uap)
{
    struct sig_context sync;
    struct sig_context sigInfo;
    os_signalHandlerCallbackInfo *cbInfo = os__signalHandlerGetCallbackInfo();

    /* info can be NULL on Solaris */
    if (info == NULL) {
        /* Pretend that it was an SI_USER signal. */
        memset(&sigInfo.info, 0, sizeof(siginfo_t));
        sigInfo.info.si_signo = sig;
        sigInfo.info.si_code = SI_USER;
        sigInfo.info.si_pid = getpid();
        sigInfo.info.si_uid = getuid();
    } else {
        sigInfo.info = *info;
    }
    sigInfo.ThreadIdSignalRaised = os_threadIdToInteger(os_threadIdSelf());
    sigInfo.domainId = os_reportGetDomain();
#ifdef OS_HAS_UCONTEXT_T
    sigInfo.uc = *(ucontext_t *)uap;
#endif

    /* WARNING: Don't do any async/signalling-unsafe calls here (so refrain from
     * using OS_REPORT_X and the like). */
    if (sigismember(&exceptionsMask, sig) == 1 && sigInfo.info.si_code != SI_USER){
        os_sigaction *xo;

        if (inSignalHandlerThread()) {
            /* The signalHandlerThread caught an exception (synchronous)
             * itself. The fact that the signalHandlerThread caught an
             * exception means there is a bug in the error handling code. */
            const char panicmsg[] = "FATAL ERROR: Synchronously trapped signal in signalHandlerThread\n";
            panic(panicmsg, sizeof(panicmsg) - 1);
            /* This line will not be reached anymore */
        }

        /* Grab the Mutex for the ExceptionHandler stack and hold it during
         * the processing of the exception. This way you avoid handlers
         * being added or removed right in between writing the exception
         * context into the pipe and the signal handler thread reading it
         * and handling it from the pipe. Also you avoid another signal from
         * another thread overwriting our context.
         * To visualize the the duration for this mutex claim, the resulting
         * handler code has been placed in its own (indented) scope.
         */
        {
            os_mutexLock(&cbInfo->exceptionMtx);

            /* Obtain the context of the thread that called the signalHandler.
             * This information will be needed by the callback invoked by the
             * signalHandlerThread, to decide what kind of action needs to
             * be taken.
             */
            os__signalHandlerExceptionGetThreadContextCallbackInvoke(cbInfo);

            /* We have an exception (synchronous) here. The assumption is
             * that exception don't occur in middleware-code, so we can
             * synchronously call the signalHandlerThread in order to detach user-
             * layer from all Domains (kernels). */
            signalHandlerThreadNotify(sigInfo, &sync);

            os_mutexUnlock(&cbInfo->exceptionMtx);
        }

        /* BEWARE: This may be an interleaved handling of an exception, so use
         * sync from now on instead of sigInfo.*/

        /* Reset the original signal-handler. If the exception was synchronous,
         * running out of this handler will regenerate the signal, which will
         * then be handled by the original signal-handler. Otherwise it needs
         * to be re-raised. */
        xo = &old_signalHandler[sync.info.si_signo];
        os_sigactionSet(sync.info.si_signo, xo, NULL);

        /* Positive values are reserved for kernel-generated signals, i.e.,
         * actual synchronous hard errors. The rest are 'soft' errors and thus
         * need to be re-raised. */
        if(sigInfo.info.si_code <= 0){
            raise(sig);
        }
    } else {
        /* Pass signal to signal-handler thread for asynchronous handling */
        os_uint32 index = pa_inc32_nv(&cbInfo->exitRequestInsertionIndex) % EXIT_REQUEST_BUFFER_SIZE;
        os__signalHandlerExitRequestGetThreadContextCallbackInvoke(cbInfo, index);
        signalHandlerThreadNotify(sigInfo, NULL);
    }
}
Exemple #18
0
void
u_userExit(
    void)
{
    u_user u;
    u_domain domain;
    os_result mr = os_resultFail;
    u_result r;
    c_long i;

    u = u__userLock();
    if (u) {
        /* Disable access to user-layer for all other threads except for this thread.
         * Any following user access from other threads is gracefully
         * aborted.
         */
        u->detachThreadId = os_threadIdSelf();
        /* Unlock the user-layer
         * Part of following code requires to unlock the user object
         * This is allowed now all other threads will abort when
         * trying to claim the lock
         */
        u__userUnlock();

        for (i = 1; (i <= u->domainCount); i++) {
            domain = u->domainList[i].domain;
            if (domain) {
                r = u_domainDetachParticipants(domain);
                if (r != U_RESULT_OK) {
                    OS_REPORT_2(OS_ERROR,
                                "user::u_user::u_userExit", 0,
                                "Operation u_domainDetachParticipants(0x%x) failed."
                                OS_REPORT_NL "result = %s",
                                domain, u_resultImage(r));
                } else {
                    r = u_domainFree(domain);
                    if (r != U_RESULT_OK) {
                        OS_REPORT_2(OS_ERROR,
                                    "user::u_user::u_userExit", 0,
                                    "Operation u_domainFree(0x%x) failed."
                                    OS_REPORT_NL "result = %s",
                                    domain, u_resultImage(r));
                    }
                }
            }
        }
        user = NULL;

        /* Destroy the user-layer mutex */
        mr = os_mutexDestroy(&u->mutex);
        if(mr != os_resultSuccess){
            OS_REPORT_1(OS_ERROR,
                        "user::u_user::u_userExit",0,
                        "Operation os_mutexDestroy(0x%x) failed:"
                        OS_REPORT_NL "os_result == %d.",
                        mr);
        }
        /* Free the user-object */
        os_free(u);
    }

    /* Even if access to the user layer is denied, we still need to cleanup
     * the signal handler, which includes waiting for the threads to exit
     * the DDS database */
    os_signalHandlerFree();

    /* De-init the OS-abstraction layer */
    os_osExit();
}