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. */ } }
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; }
u_result u_serviceFree( u_service _this) { u_result result; c_bool destroy; result = u_entityLock(u_entity(_this)); if (result == U_RESULT_OK) { destroy = u_entityDereference(u_entity(_this)); /* if refCount becomes zero then this call * returns true and destruction can take place */ if (destroy) { if (u_entityOwner(u_entity(_this))) { result = u_serviceDeinit(_this); } else { /* This user entity is a proxy, meaning that it is not fully * initialized, therefore only the entity part of the object * can be deinitialized. * It would be better to either introduce a separate proxy * entity for clarity or fully initialize entities and make * them robust against missing information. */ result = u_entityDeinit(u_entity(_this)); } if (result == U_RESULT_OK) { u_entityDealloc(u_entity(_this)); } else { OS_REPORT_2(OS_WARNING, "u_serviceFree",0, "Operation u_serviceDeinit failed: " "Service = 0x%x, result = %s.", _this, u_resultImage(result)); u_entityUnlock(u_entity(_this)); } } else { u_entityUnlock(u_entity(_this)); } } else { OS_REPORT_2(OS_WARNING, "u_serviceFree",0, "Operation u_entityLock failed: " "Service = 0x%x, result = %s.", _this, u_resultImage(result)); } return result; }
u_result u_subscriberDeleteContainedEntities ( u_subscriber _this) { u_result result; u_reader reader; c_iter list; if (_this != NULL) { result = u_entityLock(u_entity(_this)); if (result == U_RESULT_OK) { list = _this->readers; _this->readers = NULL; /* Unlock here because following code will take this lock. */ u_entityUnlock(u_entity(_this)); reader = c_iterTakeFirst(list); while (reader) { switch (u_entityKind(u_entity(reader))) { case U_READER: result = u_dataReaderDeleteContainedEntities(u_dataReader(reader)); result = u_dataReaderFree(u_dataReader(reader)); break; case U_GROUPQUEUE: result = u_groupQueueFree(u_groupQueue(reader)); break; case U_DATAVIEW: result = u_dataViewFree(u_dataView(reader)); break; case U_NETWORKREADER: result = u_networkReaderFree(u_networkReader(reader)); break; default: OS_REPORT_2(OS_WARNING, "u_subscriberDeleteContainedEntities",0, "invalid object type: " "For Subscriber = 0x%x, found Reader type = %s.", _this, u_kindImage(u_entityKind(u_entity(reader)))); assert(0); break; } u_entityDereference(u_entity(_this)); reader = c_iterTakeFirst(list); } c_iterFree(list); } else { OS_REPORT_2(OS_WARNING, "u_subscriberDeleteContainedEntities",0, "Operation u_entityLock failed: " "Subscriber = 0x%x, result = %s.", _this, u_resultImage(result)); } } else { OS_REPORT(OS_WARNING, "u_subscriberDeleteContainedEntities",0, "Invalid Subscriber <NULL>."); result = U_RESULT_ILL_PARAM; } return result; }
u_result u_topicFree( u_topic _this) { u_result result; c_bool destroy; result = u_entityLock(u_entity(_this)); if (result == U_RESULT_OK) { destroy = u_entityDereference(u_entity(_this)); /* if refCount becomes zero then this call * returns true and destruction can take place */ if (destroy) { result = u_topicDeinit(_this); if (result == U_RESULT_OK) { u_entityDealloc(u_entity(_this)); } else { OS_REPORT_2(OS_WARNING, "u_topicFree",0, "Operation u_topicDeinit failed: " "Topic = 0x%x, result = %s.", _this, u_resultImage(result)); u_entityUnlock(u_entity(_this)); } } else { u_entityUnlock(u_entity(_this)); } } else { OS_REPORT_2(OS_WARNING, "u_topicFree",0, "Operation u_entityLock failed: " "Topic = 0x%x, result = %s.", _this, u_resultImage(result)); } return result; }
u_result u_waitsetDetachFromDomain( _Inout_ u_waitset _this, _Inout_ u_domain domain) { u_result result; os_result osr; u_waitsetEntry entry; assert(_this != NULL); assert(domain != NULL); osr = os_mutexLock_s(&_this->mutex); if (osr == os_resultSuccess) { entry = c_iterResolve(_this->entries, compare_domain, domain); if (entry != NULL) { _this->notifyDetached = OS_TRUE; result = u_objectClose(entry); if (result == U_RESULT_ALREADY_DELETED) { result = U_RESULT_OK; } if (result == U_RESULT_OK) { /* The entry is already freed but the address value can still * be used to update the administration because it only removes * the address value from the list. */ c_iterTake(_this->entries, entry); } else { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, "u_waitsetDetachFromDomain", result, "Operation u_waitsetEntryFree failed: " "Waitset = 0x%"PA_PRIxADDR", result = %s", (os_address)_this, u_resultImage(result)); assert(FALSE); } } else { result = U_RESULT_PRECONDITION_NOT_MET; } (void)u_domainRemoveWaitset(domain, _this); os_mutexUnlock(&_this->mutex); } else { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_WARNING, "u_waitsetDetachFromDomain", result, "Could not claim waitset."); } return result; }
jni_writer jni_writerNew( jni_publisher pub, jni_topic top, v_writerQos qos) { jni_writer wri; u_result ur; struct jni_writerTypeArg arg; if((pub == NULL) || (top == NULL)){ OS_REPORT_2(OS_ERROR, "jni_writerNew", 0, "Bad parameter; jni_publisher (%p) and jni_topic (%p) may not be NULL.", pub, top); goto err_badParam; } assert(pub->upublisher); assert(top->utopic); if((ur = u_entityAction(u_entity(top->utopic), jni_writerTypeAction, &arg)) != U_RESULT_OK){ OS_REPORT_1(OS_ERROR, "jni_writerNew", ur, "Failed to invoke jni_writerTypeAction(...) on top->utopic; u_entityAction(...) returned %s.", u_resultImage(ur)); goto err_getWriterType; } if(arg.type == NULL){ /* Error reported by jni_writerTypeAction */ goto err_getWriterType; } if((wri = os_malloc(sizeof *wri)) == NULL){ OS_REPORT_1(OS_ERROR, "jni_writerNew", 0, "Memory claim of %" PA_PRIuSIZE " denied.", sizeof *wri); goto err_malloc; } if((wri->deserializer = sd_serializerXMLNewTyped(arg.type)) == NULL){ /* Error reported by sd_serializerXMLNewTyped */ goto err_sd_serializerXMLNewTyped; } if((wri->uwriter = u_writerNew(pub->upublisher, NULL, top->utopic, jni_writerCopy, qos, TRUE)) == NULL){ /* Error reported by u_writerNew */ goto err_uwriterNew; } wri->publisher = pub; wri->topic = top; return wri; /* Error handling */ err_uwriterNew: sd_serializerFree(wri->deserializer); err_sd_serializerXMLNewTyped: os_free(wri); err_malloc: /* No undo for jni_writerTypeAction */ err_getWriterType: err_badParam: return NULL; }
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(); }