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; } } }
static MME_ERROR RemoteTransformer_TermOrKill(Transformer_t* transformer, int doKill) { RemoteTransformer_t *remoteTransformer = (RemoteTransformer_t *) transformer; EMBX_ERROR err; EMBX_VOID *buffer; TransformerTerminateMessage *message; MME_ERROR result, res; result = MME_NOMEM; if (!remoteTransformer->sendPort.valid) { DP("MME port does not exist\n"); return MME_INVALID_ARGUMENT; } /* No command must be pending on the companion side */ if (remoteTransformer->numCommandSlots > 0) { DP("RemoteTransformer::Terminate() failed, commands pending\n"); return MME_COMMAND_STILL_EXECUTING; } res = createTerminateMessage(remoteTransformer, 0, &buffer); if (res != MME_SUCCESS) { DP("CreateTerminateMsg() failed, error=%d\n", res); return res; } /* Send the message */ message = (TransformerTerminateMessage *) buffer; DP("Sending %s message @$%08x...\n", message, (doKill ? "kill" : "terminate")); if (doKill) { EMBX_PORT replyPort; /* connect to our own reply port */ err = EMBX_Connect(remoteTransformer->super.info->handle, remoteTransformer->replyPort.name, &replyPort); if (EMBX_SUCCESS != err) { DP("RemoteTransformer_Term(): failed to connect to self\n"); cleanupTerminateMessage(remoteTransformer, message); return MME_EMBX_ERROR; } err = EMBX_SendMessage(replyPort, message, message->messageSize); if (EMBX_SUCCESS != err) { DP("RemoteTransformer_Term(): failed to send message to self\n"); cleanupTerminateMessage(remoteTransformer, message); return MME_EMBX_ERROR; } EMBX_ClosePort(replyPort); } else { err = EMBX_SendMessage(remoteTransformer->adminPort, message, message->messageSize); if (EMBX_SUCCESS != err) { DP("RemoteTransformer_Term(): failed to send message to coprocessor\n"); cleanupTerminateMessage(remoteTransformer, message); return MME_EMBX_ERROR; } } /* lost ownership */ message = NULL; /* Wait for ReceiverThread to terminate itself after receiving the reply message */ DP("Waiting for ReceiverThread to terminate itself...\n"); DP("terminateWasReplied 0x%08x\n", remoteTransformer->terminateWasReplied); EMBX_OS_EVENT_WAIT(&remoteTransformer->terminateWasReplied); if (remoteTransformer->terminationResult != MME_SUCCESS) { DP("Failed to terminate receiver thread properly\n"); return MME_INTERNAL_ERROR; } err = EMBX_OS_ThreadDelete(remoteTransformer->receiverThread); if (err != EMBX_SUCCESS) { DP("EMBX_OS_ThreadDelete() failed, error=d\n", err); } remoteTransformer->receiverThread = NULL; /* Close the MME port */ DP("Close mmePort...\n"); err = EMBX_ClosePort(remoteTransformer->sendPort.port); if (err != EMBX_SUCCESS) { DP("EMBX_ClosePort(mmePort) failed, error=d\n", err); } /* Close the reply port */ DP("Invalidate replyPort...\n"); err = EMBX_InvalidatePort(remoteTransformer->replyPort.port); if (err != EMBX_SUCCESS) { DP("EMBX_InvalidatePort(replyPort) failed, error=%d\n", err); } DP("Close replyPort...\n"); err = EMBX_ClosePort(remoteTransformer->replyPort.port); if (err != EMBX_SUCCESS) { DP("EMBX_ClosePort(replyPort) failed, error=%d\n", err); } remoteTransformer->replyPort.valid = EMBX_FALSE; return MME_SUCCESS; }
/* * Helper function to kill off any worker threads started * by the transport. This is used in closedown and to tidy * up initialization if it fails. */ EMBX_ERROR EMBXSHM_killThread (EMBXSHM_Transport_t *tpshm, EMBX_UINT threadName) { EMBX_ERROR res = EMBX_SUCCESS; EMBX_Info (EMBX_INFO_TRANSPORT, (">>>EMBXSHM_killThread()\n")); switch (threadName) { case EMBXSHM_NEWPORT_WORKER: { if(tpshm->locksValid && tpshm->secondHalfDieFlag == 0) { tpshm->secondHalfDieFlag = 1; EMBX_OS_EVENT_POST (&tpshm->secondHalfEvent); } if (tpshm->secondHalfThread != EMBX_INVALID_THREAD) { res = EMBX_OS_ThreadDelete(tpshm->secondHalfThread); if (res == EMBX_SUCCESS) { tpshm->secondHalfThread = EMBX_INVALID_THREAD; } } tpshm->secondHalfDieFlag = 0; break; } /* EMBXSHM_NEWPORT_WORKER */ case EMBXSHM_CLOSEPORT_WORKER: { if(tpshm->locksValid && tpshm->closedPortDieFlag == 0) { tpshm->closedPortDieFlag = 1; EMBX_OS_EVENT_POST (&tpshm->closedPortEvent); } if (tpshm->closedPortThread != EMBX_INVALID_THREAD) { res = EMBX_OS_ThreadDelete(tpshm->closedPortThread); if (res == EMBX_SUCCESS) { tpshm->closedPortThread = EMBX_INVALID_THREAD; } } tpshm->closedPortDieFlag = 0; break; } /* EMBXSHM_CLOSEPORT_WORKER */ default: { EMBX_Assert(0); res = EMBX_INVALID_ARGUMENT; } /* default */ } EMBX_Info (EMBX_INFO_TRANSPORT, ("<<<EMBXSHM_killThread\n")); return res; }