Example #1
0
c_syncResult
c_condWait (
    c_cond *cnd,
    c_mutex *mtx)
{
    os_result result;

#ifdef NDEBUG
    result = os_condWait(cnd,mtx);
#else
    mtx->owner = OS_THREAD_ID_NONE;
    result = os_condWait(cnd,&mtx->mtx);
    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_condWait", 0, "os_condWait failed; os_result = %d.", result);
        assert(result == os_resultSuccess);
    }
    return result;
}
Example #2
0
static void*
cms_soapThreadRun(
    void *thr)
{
    cms_soapThread thread;
    struct soap* soap;
    c_char* result;

    thread = cms_soapThread(thr);
    os_mutexLock(&thread->soapMutex);

    while(cms_thread(thread)->terminate == FALSE){

        if(thread->soap != NULL){
            soap = thread->soap;
            thread->soap = NULL;

            cms_thread(thread)->results = NULL;
            soap->user = thr;
            soap_serve(soap);
            soap_destroy(soap);
            soap_end(soap);
            soap_done(soap);
            free(soap);
            u_entityAction( u_entity(thread->client->service->uservice),
                            cms_soapThreadStatisticsRequestHandledAdd,
                            thread->client->service);

            if(cms_thread(thread)->results != NULL){
                result = (c_char*)(c_iterTakeFirst(cms_thread(thread)->results));

                while(result){
                    os_free(result);
                    result = (c_char*)(c_iterTakeFirst(cms_thread(thread)->results));
                }
                c_iterFree(cms_thread(thread)->results);
                cms_thread(thread)->results = NULL;
            }
        }

        if(cms_thread(thread)->terminate == FALSE){
            cms_thread(thread)->ready = TRUE;

            if(thread->client->service->configuration->verbosity >= 7){
                OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0,  "soapThread '%s' ready.", cms_thread(thread)->name);
            }
            os_condWait(&thread->condition, &thread->soapMutex);

            if(thread->client->service->configuration->verbosity >= 7){
                OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0,  "soapThread '%s' condition triggered.", cms_thread(thread)->name);
            }
        }
    }
    os_mutexUnlock(&thread->soapMutex);

    if(thread->client->service->configuration->verbosity >= 6){
        OS_REPORT_1(OS_INFO, CMS_CONTEXT, 0,  "soapThread '%s' ends.", cms_thread(thread)->name);
    }
    return NULL;
}
Example #3
0
static gapi_returnCode_t
gapi_handleClaimNotBusy (
    gapi_handle handle)
{
    gapi_returnCode_t result;
    os_result osr;

    /* this leaky design needs pa_increment. */
    if (handle) {
        if (handle->magic == MAGIC) {
            if ( handle->object != NULL ) {
                osr = os_mutexLock(&handle->mutex);
                if (osr == os_resultSuccess) {
                    if (handle->magic == MAGIC) {
                        while ( handle->busy ) {
                            osr = os_condWait(&handle->cv, &handle->mutex);
                            if (osr == os_resultFail)
                            {
                                OS_REPORT(OS_CRITICAL, "gapi_handleClaimNotBusy", 0,
                                          "os_condWait failed - waiting for busy handle");
                                osr = os_mutexUnlock(&handle->mutex);
                                return GAPI_RETCODE_ERROR;
                            }
                        }
                        result = GAPI_RETCODE_OK;
                    } else {
                        result = GAPI_RETCODE_ALREADY_DELETED;
                    }
                } else {
                    result = GAPI_RETCODE_ALREADY_DELETED;
                }
            } else {
                result = GAPI_RETCODE_ALREADY_DELETED;
            }
        } else {
            if(handle->magic == MAGIC_DELETED)
            {
                result = GAPI_RETCODE_ALREADY_DELETED;
            }
            else
            {
                result = GAPI_RETCODE_BAD_PARAMETER;
            }

        }
    } else {
        result = GAPI_RETCODE_BAD_PARAMETER;
    }
    return result;
}
Example #4
0
static u_result
u__waitsetDeinitW(
    void *_vthis)
{
    u_waitset _this;
    u_waitsetEntry entry;
    u_result result = U_RESULT_OK;

    _this = u_waitset(_vthis);
    os_mutexLock(&_this->mutex);

    _this->alive = FALSE;
    while (_this->waitBusy) {
        waitset_notify(_this, NULL);
        os_condWait(&_this->waitCv, &_this->mutex);
    }
    entry = c_iterTakeFirst(_this->entries);
    while (entry != NULL) {
        u_domain domain = u_observableDomain(u_observable(entry));
        result = u_domainRemoveWaitset(domain, _this);
        if (result != U_RESULT_OK) {
            OS_REPORT(OS_ERROR,
                      "u__waitsetDeinitW", result,
                      "Operation u_domainRemoveWaitset failed: "
                      "Waitset = 0x%"PA_PRIxADDR", result = %s",
                      (os_address)_this, u_resultImage(result));
            assert(FALSE);
        }
        result = u_objectFree_s(entry);
        if (result == U_RESULT_ALREADY_DELETED) {
            result = U_RESULT_OK;
        } else if (result != U_RESULT_OK) {
            OS_REPORT(OS_ERROR,
                      "u__waitsetDeinitW", result,
                      "Operation u_waitsetEntryFree failed: "
                      "Waitset = 0x%"PA_PRIxADDR", result = %s",
                      (os_address)_this, u_resultImage(result));
            result = U_RESULT_OK;
            (void)result;
            assert(FALSE);
        }
        entry = c_iterTakeFirst(_this->entries);
    }
    c_iterFree(_this->entries);
    _this->entries = NULL;

    os_mutexUnlock(&_this->mutex);
    u__objectDeinitW(_this);
    return result;
}
Example #5
0
os_result
_ObjectWait(
    _Object object,
    os_cond *cv)
{
    gapi_handle handle;
    os_result result;

    assert(object);
    assert(object->handle);
    assert(cv != NULL);

    handle = (gapi_handle)object->handle;

    assert(handle->magic == MAGIC);

    result = os_condWait(cv, &handle->mutex);

    return result;
}
Example #6
0
static void
gapi_handleReadClaimNotBusy (
    gapi_handle handle)
{
    os_result osr;
    os_mutexLock(&handle->read);
    handle->count++;
    if (handle->count == 1) {
        os_mutexLock(&handle->mutex);
    }
    while ( handle->busy ) {
        osr = os_condWait(&handle->cv, &handle->mutex);
        if (osr == os_resultFail)
        {
            OS_REPORT(OS_CRITICAL, "gapi_handleReadClaimNotBusy", 0,
                      "os_condWait failed - waiting for busy handle");
            break;
        }
    }
    os_mutexUnlock(&handle->read);
}
Example #7
0
u_result
u_waitsetDetach_s(
    const u_waitset _this,
    const u_observable observable)
{
    u_waitsetEntry entry;
    u_domain domain;
    u_result result;
    os_result osr;

    assert(_this != NULL);
    assert(observable != NULL);

    osr = os_mutexLock_s(&_this->mutex);
    if (osr == os_resultSuccess) {
        domain = u_observableDomain(observable);
        if (domain != NULL) {
            entry = c_iterResolve(_this->entries, compare_domain, domain);
            if (entry != NULL) {
                /* The following detach will wakeup any blocking wait call on this entry. */
                result = u_waitsetEntryDetach(entry, observable);
                if (result == U_RESULT_UNSUPPORTED) {
                    _this->detachCnt++;
                    /* removed last observable for this entry so can detach from domain. */
                    entry = c_iterTake(_this->entries, entry); /* use overwrite entry */
                    result = u_domainRemoveWaitset(domain, _this);
                    if (c_iterLength(_this->entries) == 1) {
                        _this->multi_mode = OS_FALSE;
                    } else {
                        _this->multi_mode = OS_TRUE;
                    }
                    while (_this->waitBusy) {
                        os_condWait(&_this->waitCv, &_this->mutex);
                    }

                    _this->detachCnt--;
                    /* Broadcast the detachCnt update. */
                    os_condBroadcast(&_this->waitCv);

                    os_mutexUnlock(&_this->mutex);
                    u_objectFree(entry);
                } else {
                    os_mutexUnlock(&_this->mutex);
                }
            } else {
                /* Check if the condition is already deleted */
                v_public ko;
                result = u_observableReadClaim(observable, &ko, C_MM_RESERVATION_NO_CHECK);
                if (result == U_RESULT_OK) {
                    u_observableRelease(observable, C_MM_RESERVATION_NO_CHECK);
                    result = U_RESULT_PRECONDITION_NOT_MET;
                    OS_REPORT(OS_ERROR, "u_waitSetDetach_s", result, "Condition is not attached to Waitset");
                }
                os_mutexUnlock(&_this->mutex);
            }
        } else {
            os_mutexUnlock(&_this->mutex);
            result = U_RESULT_INTERNAL_ERROR;
            OS_REPORT(OS_ERROR, "u_waitsetDetach_s", result,
                      "Failed to connect to domain.");
        }
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        OS_REPORT(OS_ERROR, "u_waitSetDetach_s", result, "Could not lock the waitset.");
    }
    return result;
}
Example #8
0
u_result
u_waitsetWaitAction (
    const u_waitset _this,
    u_waitsetAction action,
    void *arg,
    const os_duration timeout)
{
    u_result result = U_RESULT_OK;
    os_result osr;
    c_ulong length;

    assert(_this != NULL);
    assert(action != NULL);
    assert(OS_DURATION_ISPOSITIVE(timeout));

    osr = os_mutexLock_s(&_this->mutex);
    if (osr == os_resultSuccess) {
        if (!_this->alive) {
            result = U_RESULT_ALREADY_DELETED;
        }
        if (result == U_RESULT_OK) {
            if (!_this->waitBusy) {
                /* Wait for possible detach to complete.
                 * If you don't do that, it's possible that this wait call sets
                 * the waitBusy flag before the detach can wake up of its waitBusy
                 * loop, meaning that the detach will block at least until the
                 * waitset is triggered again.
                 */
                while (_this->detachCnt > 0) {
                    os_condWait(&_this->waitCv, &_this->mutex);
                }

                _this->waitBusy = TRUE;
                length = c_iterLength(_this->entries);
                if (length == 1) {
                    /* Single Domain Mode. */
                    u_waitsetEntry entry = c_iterObject(_this->entries,0);
                    os_mutexUnlock(&_this->mutex);
                    result = u_waitsetEntryWait(entry, action, arg, timeout);

                    os_mutexLock(&_this->mutex);
                    _this->waitBusy = FALSE;
                    os_condBroadcast(&_this->waitCv);
                    os_mutexUnlock(&_this->mutex);

                    if ((result == U_RESULT_OK) && (_this->alive == FALSE)) {
                        result = U_RESULT_ALREADY_DELETED;
                    }
                } else {
                    /* Multi Domain Mode (or no Domain). */
                    if (OS_DURATION_ISINFINITE(timeout)) {
                        os_condWait(&_this->cv, &_this->mutex);
                        osr = os_resultSuccess;
                    } else {
                        osr = os_condTimedWait(&_this->cv, &_this->mutex, timeout);
                    }
                    _this->waitBusy = FALSE;
                    os_condBroadcast(&_this->waitCv);
                    switch (osr) {
                    case os_resultSuccess:
                        if (_this->alive == TRUE) {
                            result = U_RESULT_OK;
                        } else {
                            result = U_RESULT_ALREADY_DELETED;
                        }
                    break;
                    case os_resultTimeout:
                        result = U_RESULT_TIMEOUT;
                    break;
                    default:
                        result = U_RESULT_INTERNAL_ERROR;
                        OS_REPORT(OS_ERROR, "u_waitsetWaitAction", result,
                                    "os_condWait failed for waitset 0x" PA_ADDRFMT,
                                    (PA_ADDRCAST)_this);
                    break;
                    }
                    os_mutexUnlock(&_this->mutex);
                }
            } else {
                os_mutexUnlock(&_this->mutex);
                result = U_RESULT_PRECONDITION_NOT_MET;
            }
        } else {
            os_mutexUnlock(&_this->mutex);
        }
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        OS_REPORT(OS_ERROR, "u_waitsetWaitAction", result,
                    "os_mutexLock failed for waitset 0x" PA_ADDRFMT,
                    (PA_ADDRCAST)_this);
    }
    return result;
}
Example #9
0
u_result
u_waitsetWaitAction2 (
    const u_waitset _this,
    u_waitsetAction2 action,
    void *arg,
    const os_duration timeout)
{
    u_result result = U_RESULT_OK;
    os_result osr;
    c_ulong length;
    struct checkArg a;
    a.action = action;
    a.arg = arg;
    a.count = 0;

    assert(_this != NULL);
    assert(OS_DURATION_ISPOSITIVE(timeout));

    osr = os_mutexLock_s(&_this->mutex);
    if (osr == os_resultSuccess) {
        if (!_this->alive) {
            result = U_RESULT_ALREADY_DELETED;
            OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                      "Precondition not met: Waitset is already deleted");
        }
        if (_this->waitBusy) {
            result = U_RESULT_PRECONDITION_NOT_MET;
            OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                      "Precondition not met: A Wait call is already active on this Waitset");
        }
        if (result == U_RESULT_OK) {
            /* Wait for possible detach to complete.
             * If you don't do that, it's possible that this wait call sets
             * the waitBusy flag before the detach can wake up of its waitBusy
             * loop, meaning that the detach will block at least until the
             * waitset is triggered again.
             */
            while (_this->detachCnt > 0) {
                os_condWait(&_this->waitCv, &_this->mutex);
            }

            length = c_iterLength(_this->entries);
            if (length == 1) {
                /* Single Domain Mode. */
                u_waitsetEntry entry = c_iterObject(_this->entries,0);
                _this->waitBusy = TRUE;
                os_mutexUnlock(&_this->mutex);

                result = u_waitsetEntryWait2(entry, action, arg, timeout);

                os_mutexLock(&_this->mutex);
                _this->waitBusy = FALSE;

                if (_this->notifyDetached) {
                    result = U_RESULT_DETACHING;
                    _this->notifyDetached = OS_FALSE;
                }

                os_condBroadcast(&_this->waitCv);
                os_mutexUnlock(&_this->mutex);

                if ((result == U_RESULT_OK) && (_this->alive == FALSE)) {
                    result = U_RESULT_ALREADY_DELETED;
                    OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                              "Precondition not met: Waitset is already deleted");
                }
            } else {
                /* Multi Domain Mode (or no Domain). */
                a.count = 0;
                /* For each Domain test Conditions. */
                (void)c_iterWalkUntil(_this->entries, check_entry_conditions, &a);
                /* Test Guard Conditions */
                if ((a.count == 0) && (!action(NULL,arg))) {
                    a.count++;
                }
                /* If No Conditions are true then wait. */
                if (a.count == 0) {
                    _this->waitBusy = TRUE;
                    if (OS_DURATION_ISINFINITE(timeout)) {
                        os_condWait(&_this->cv, &_this->mutex);
                        osr = os_resultSuccess;
                    } else {
                        osr = os_condTimedWait(&_this->cv, &_this->mutex, timeout);
                    }
                    _this->waitBusy = FALSE;
                    os_condBroadcast(&_this->waitCv);
                    switch (osr) {
                    case os_resultSuccess:
                        if (_this->alive == TRUE) {
                            if (_this->notifyDetached) {
                                result = U_RESULT_DETACHING;
                                _this->notifyDetached = OS_FALSE;
                            } else {
                                result = U_RESULT_OK;
                            }
                        } else {
                            result = U_RESULT_ALREADY_DELETED;
                            OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                                      "Precondition not met: Waitset is already deleted");
                        }
                    break;
                    case os_resultTimeout:
                        result = U_RESULT_TIMEOUT;
                    break;
                    default:
                        result = U_RESULT_INTERNAL_ERROR;
                        OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                                    "os_condWait failed for waitset 0x" PA_ADDRFMT,
                                    (PA_ADDRCAST)_this);
                    break;
                    }
                }
                os_mutexUnlock(&_this->mutex);
            }
        } else {
            os_mutexUnlock(&_this->mutex);
        }
    } else {
        result = U_RESULT_INTERNAL_ERROR;
        OS_REPORT(OS_ERROR, "u_waitsetWaitAction2", result,
                    "os_mutexLock failed for waitset 0x" PA_ADDRFMT,
                    (PA_ADDRCAST)_this);
    }
    return result;
}