static MME_ERROR createExecutionLoop(MMEManager_t *manager, int id) { const struct { MME_UINT priority; const char *name; } lookup[MME_NUM_EXECUTION_LOOPS] = { { MME_TUNEABLE_EXECUTION_LOOP_LOWEST_PRIORITY, "ExecutionLoopLowest" }, { MME_TUNEABLE_EXECUTION_LOOP_BELOW_NORMAL_PRIORITY, "ExecutionLoopBelowNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_NORMAL_PRIORITY, "ExecutionLoopNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_ABOVE_NORMAL_PRIORITY, "ExecutionLoopAboveNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_HIGHEST_PRIORITY, "ExecutionLoopHighest" }, }; MME_Assert(manager); MME_Assert(id < MME_NUM_EXECUTION_LOOPS); if (manager->loopTasksRunning[id]) { return MME_SUCCESS; } MME_Assert(0 == manager->loopTasks[id]); MME_Assert(0 == manager->receiverLists[id]); /* this code can only be called from the manager thread and therefore needs * no thread protection. */ if (!EMBX_OS_MUTEX_INIT(&(manager->receiverListMutexes[id]))) { return MME_NOMEM; } if (!EMBX_OS_EVENT_INIT(&(manager->commandEvents[id]))) { goto cleanup_mutex; } /* spawn the worker thread */ manager->loopTasks[id] = EMBX_OS_ThreadCreate((void(*)()) executionLoopTask, (void *) id, MME_GetTuneable(lookup[id].priority), lookup[id].name); if (0 == manager->loopTasks[id]) { goto cleanup_event; } /* mark the task as running */ manager->loopTasksRunning[id] = 1; return MME_SUCCESS; cleanup_event: EMBX_OS_EVENT_DESTROY(&(manager->commandEvents[id])); cleanup_mutex: EMBX_OS_MUTEX_DESTROY(&(manager->receiverListMutexes[id])); return MME_NOMEM; }
MME_ERROR MME_HostInit(void) #endif { if (NULL != manager) { return MME_DRIVER_ALREADY_INITIALIZED; } manager = EMBX_OS_MemAlloc(sizeof(HostManager_t)); if (!manager) { return MME_NOMEM; } memset(manager, 0, sizeof(HostManager_t)); manager->transformerInstances = MME_LookupTable_Create(MAX_TRANSFORMER_INSTANCES, 1); if (!manager->transformerInstances) { goto error_path; } if (EMBX_FALSE == EMBX_OS_MUTEX_INIT(&manager->monitorMutex)) { goto error_path; } if (EMBX_FALSE == EMBX_OS_MUTEX_INIT(&manager->eventLock)) { goto error_path; } if (EMBX_FALSE == EMBX_OS_EVENT_INIT(&manager->waitorDone)) { goto error_path; } return MME_SUCCESS; error_path: if (manager->transformerInstances) { MME_LookupTable_Delete(manager->transformerInstances); } EMBX_OS_MemFree(manager); manager = NULL; return MME_NOMEM; }
Transformer_t* MME_RemoteTransformer_Create(HostManager_t *manager, TransportInfo_t* info, EMBX_PORT adminPort) { static const TransformerVTable_t vtable = { RemoteTransformer_Destroy, RemoteTransformer_Init, RemoteTransformer_Term, RemoteTransformer_Kill, RemoteTransformer_AbortCommand, RemoteTransformer_KillCommand, RemoteTransformer_SendCommand, RemoteTransformer_IsStillAlive, RemoteTransformer_GetTransformerCapability, RemoteTransformer_WaitForMessage, RemoteTransformer_LookupCommand, RemoteTransformer_ReleaseCommandSlot }; RemoteTransformer_t* remoteTransformer; int i; remoteTransformer = EMBX_OS_MemAlloc(sizeof(RemoteTransformer_t)); if (!remoteTransformer) { return NULL; } /* zero the structure */ memset(remoteTransformer, 0, sizeof(RemoteTransformer_t)); /* initialize the non-zero elements */ remoteTransformer->super.vtable = &vtable; remoteTransformer->super.manager = manager; remoteTransformer->super.info = info; remoteTransformer->adminPort = adminPort; remoteTransformer->maxCommandSlots = MAX_TRANSFORMER_SEND_OPS; /* allocate the command slots (used to keep track of in-flight commands) */ remoteTransformer->commandSlots = EMBX_OS_MemAlloc(sizeof(CommandSlot_t) * remoteTransformer->maxCommandSlots); if (0 == remoteTransformer->commandSlots) { goto error_recovery; } for (i=0; i<remoteTransformer->maxCommandSlots; i++) { remoteTransformer->commandSlots[i].command = 0; remoteTransformer->commandSlots[i].status = MME_COMMAND_COMPLETED_EVT; } if (!EMBX_OS_EVENT_INIT(&remoteTransformer->terminateWasReplied)) { goto error_recovery; } if (!EMBX_OS_MUTEX_INIT(&remoteTransformer->commandSlotLock)) { EMBX_OS_EVENT_DESTROY(&remoteTransformer->terminateWasReplied); goto error_recovery; } /* reference the transport info structure (so it can't be deregistered) */ info->referenceCount++; return &remoteTransformer->super; error_recovery: /* EMBX_OS_MemFree() will ignore NULL pointers */ EMBX_OS_MemFree(remoteTransformer->commandSlots); EMBX_OS_MemFree(remoteTransformer); return NULL; }