Beispiel #1
0
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;
}