/************************************************************** * private functions **************************************************************/ static void v_serviceWatchSplicedaemon( v_service service) { v_kernel k; v_serviceManager m; v_serviceState splicedState; k = v_objectKernel(service); m = v_getServiceManager(k); splicedState = v_serviceManagerGetServiceState(m, V_SPLICED_NAME); v_observableAddObserver(v_observable(splicedState), v_observer(service), NULL); }
static void cmx_participantInitDetach( v_public entity, c_voidp args) { v_kernel k; v_serviceManager m; v_serviceState splicedState; OS_UNUSED_ARG(args); k = v_objectKernel(entity); m = v_getServiceManager(k); splicedState = v_serviceManagerGetServiceState(m, V_SPLICED_NAME); v_observableAddObserver(v_observable(splicedState), v_observer(entity), V_EVENTMASK_ALL, NULL); }
/************************************************************** * 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; }
void v_serviceInit( v_service service, const c_char *name, const c_char *extStateName, v_serviceType serviceType, v_participantQos qos, c_bool enable) { c_char *typeName; os_duration lp = 300*OS_DURATION_SECOND; v_kernel kernel; v_serviceManager manager; assert(service != NULL); assert(serviceType != V_SERVICETYPE_NONE); assert(C_TYPECHECK(service, v_service)); assert(C_TYPECHECK(qos, v_participantQos)); assert(name != NULL); kernel = v_objectKernel(service); manager = v_getServiceManager(kernel); /* v_participantInit writes the DCPSParticipant and CMParticipant topics, but * it downcasts to v_service to extract serviceType, and hence needs it available. */ service->serviceType = serviceType; v_participantInit(v_participant(service), name, qos); if(enable) { (void)v_entityEnable(v_entity(service)); } service->state = v_serviceManagerRegister(manager, service, extStateName); service->lease = v_leaseMonotonicNew(kernel, lp); service->newGroups = NULL; if(service->lease) { v_result result; result = v_leaseManagerRegister( kernel->livelinessLM, service->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(service->state), FALSE/*do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT(OS_FATAL, "v_service", result, "A fatal error was detected when trying to register the liveliness lease " "to the liveliness lease manager of the kernel. The result code was %d.", result); } } else { OS_REPORT(OS_FATAL, "v_service", V_RESULT_INTERNAL_ERROR, "Unable to create a liveliness lease! Most likely not enough shared " "memory available to complete the operation."); } if(service->lease)/* aka everything is ok so far */ { v_result result; c_iter participants; v_participant splicedParticipant; participants = v_resolveParticipants(kernel, V_SPLICED_NAME); assert(c_iterLength(participants) == 1 || 0 == strcmp(name, V_SPLICED_NAME)); splicedParticipant = v_participant(c_iterTakeFirst(participants)); if(splicedParticipant) { result = v_leaseManagerRegister( v_participant(service)->leaseManager, v_service(splicedParticipant)->lease, V_LEASEACTION_SERVICESTATE_EXPIRED, v_public(v_service(splicedParticipant)->state), FALSE /* only observing, do not repeat */); if(result != V_RESULT_OK) { c_free(service->lease); service->lease = NULL; OS_REPORT(OS_FATAL, "v_service", result, "A fatal error was detected when trying to register the spliced's liveliness lease " "to the lease manager of participant %p (%s). The result code was %d.", (void*)service, name, result); } c_free(splicedParticipant); } c_iterFree(participants); } if (service->state != NULL) { /* check if state has correct type */ typeName = c_metaScopedName(c_metaObject(c_getType(c_object(service->state)))); if (extStateName == NULL) { extStateName = VSERVICESTATE_NAME; } if (strcmp(typeName, extStateName) == 0) { /* Splicedaemon may not observer itself! */ if (strcmp(name, V_SPLICED_NAME) != 0) { v_serviceState splicedState; splicedState = v_serviceManagerGetServiceState(manager, V_SPLICED_NAME); (void)OSPL_ADD_OBSERVER(splicedState, service, V_EVENT_SERVICESTATE_CHANGED, NULL); } } else { OS_REPORT(OS_ERROR, "v_service", V_RESULT_ILL_PARAM, "Requested state type (%s) differs with existing state type (%s)", extStateName, typeName); c_free(service->state); service->state = NULL; } os_free(typeName); } }