static void RemoteTransformer_Destroy(Transformer_t* transformer) { RemoteTransformer_t *remoteTransformer = (RemoteTransformer_t *) transformer; EMBX_ERROR err; remoteTransformer->super.info->referenceCount--; /* clean up the buffer cache (allocated during execution) */ while (remoteTransformer->bufferCache) { void *buf = allocBuffer(remoteTransformer, 1); if (buf) { EMBX_ERROR err; err = EMBX_Free(buf); MME_Assert(EMBX_SUCCESS == err); } } if (remoteTransformer->adminPort) { err = EMBX_ClosePort(remoteTransformer->adminPort); MME_Assert(EMBX_SUCCESS == err); /* no recovery possible */ } EMBX_OS_EVENT_DESTROY(&remoteTransformer->terminateWasReplied); EMBX_OS_MUTEX_DESTROY(&remoteTransformer->commandSlotLock); EMBX_OS_MemFree(remoteTransformer->commandSlots); EMBX_OS_MemFree(remoteTransformer); }
MME_ERROR MME_HostTerm(void) #endif { TransportInfo_t *tpInfo, *next; #ifndef MME_LEAN_AND_MEAN if (manager == NULL) { MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Failed to find transformer instance\n")); return MME_DRIVER_NOT_INITIALIZED; } #endif if (!MME_LookupTable_IsEmpty(manager->transformerInstances)) { /* Need to close all transformers first */ MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Handles still open\n")); return MME_HANDLES_STILL_OPEN; } /* Deregister all the transports (so that the companions receive terminate messages) */ for (tpInfo = manager->transportList; tpInfo && (next = tpInfo->next, 1); tpInfo = next) { destroyTransportInfo(tpInfo); } EMBX_OS_MUTEX_DESTROY(&manager->monitorMutex); EMBX_OS_MUTEX_DESTROY(&manager->eventLock); EMBX_OS_EVENT_DESTROY(&manager->waitorDone); MME_LookupTable_Delete(manager->transformerInstances); EMBX_OS_MemFree(manager); manager = NULL; return MME_SUCCESS; }
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; }
static void terminateExecutionLoops(MMEManager_t *mgr) { int i; for (i=0; i<MME_NUM_EXECUTION_LOOPS; i++) { if (mgr->loopTasksRunning[i]) { mgr->loopTasksRunning[i] = 0; EMBX_OS_EVENT_POST(&(mgr->commandEvents[i])); EMBX_OS_ThreadDelete(mgr->loopTasks[i]); EMBX_OS_EVENT_DESTROY(&(mgr->commandEvents[i])); EMBX_OS_MUTEX_DESTROY(&(mgr->receiverListMutexes[i])); mgr->loopTasks[i] = NULL; mgr->receiverLists[i] = NULL; } } }
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; }