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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }