OMX_ERRORTYPE COMXCoreComponent::DisableAllPorts()
{
  if(!m_handle)
    return OMX_ErrorUndefined;

  Lock();

  OMX_ERRORTYPE omx_err = OMX_ErrorNone;

  OMX_INDEXTYPE idxTypes[] = {
    OMX_IndexParamAudioInit,
    OMX_IndexParamImageInit,
    OMX_IndexParamVideoInit, 
    OMX_IndexParamOtherInit
  };

  OMX_PORT_PARAM_TYPE ports;
  OMX_INIT_STRUCTURE(ports);

  int i;
  for(i=0; i < 4; i++)
  {
    omx_err = OMX_GetParameter(m_handle, idxTypes[i], &ports);
    if(omx_err == OMX_ErrorNone) {

      uint32_t j;
      for(j=0; j<ports.nPorts; j++)
      {
        OMX_PARAM_PORTDEFINITIONTYPE portFormat;
        OMX_INIT_STRUCTURE(portFormat);
        portFormat.nPortIndex = ports.nStartPortNumber+j;

        omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
        if(omx_err != OMX_ErrorNone)
        {
          if(portFormat.bEnabled == OMX_FALSE)
            continue;
        }

        omx_err = OMX_SendCommand(m_handle, OMX_CommandPortDisable, ports.nStartPortNumber+j, NULL);
        if(omx_err != OMX_ErrorNone)
        {
          CLog::Log(LOGERROR, "COMXCoreComponent::DisableAllPorts - Error disable port %d on component %s omx_err(0x%08x)", 
            (int)(ports.nStartPortNumber) + j, m_componentName.c_str(), (int)omx_err);
        }
        omx_err = WaitForCommand(OMX_CommandPortDisable, ports.nStartPortNumber+j);
        if(omx_err != OMX_ErrorNone && omx_err != OMX_ErrorSameState)
        {
          UnLock();
          return omx_err;
        }
      }
    }
  }

  UnLock();

  return OMX_ErrorNone;
}
Example #2
0
/*----------------------------------------------------------------------------+
 | Main Routine                                                                |
 +----------------------------------------------------------------------------*/
void main (void)
{
   
	uint16_t ret = 0;
	uint8_t retbuf[BUFFER_SIZE];
    	struct CommandStruct receive;
	struct CommandStruct transmit;
	char strbuf[256];
	char wrbuf[16] = "write";
	char wrbuf2[16] = "defau";
	TILEAF_BoardInit(24000000);

/*	while(1)
	{
		ret = ReceiveBuffer(strbuf);
		if (ret > 0)
		{
			SendBuffer(wrbuf,5);
		}
	}*/
  	  	
       
	while (1)
	{	
		receive.command = 0x00;
		ret = 0;
		ret = WaitForCommand(&receive);	
	        if (ret > 0)
		{
			switch(receive.command)
			{
				case READ:
					//transmit.command = READ;
					//transmit.address = receive.address;
					//bufCopy((uint16_t*)receive.address, transmit.data,receive.length);
					///transmit.data[0] = 0xFF;
					//transmit.length = receive.length;
					break;

				case WRITE:
					SendBuffer(wrbuf,5);
					//transmit.command = WRITE;
					//transmit.address = receive.address;
					//bufCopy(receive.data,(uint16_t*)receive.address,receive.length);
					//transmit.data[0] = 0;
					break;
				default:
					SendBuffer(wrbuf2,5);
					break;
			}
			
			//TransmitCommand(&transmit);
		}

	}  
}
Example #3
0
OMX_ERRORTYPE COMXCoreComponent::SetStateForComponent(OMX_STATETYPE state)
{
  Lock();
  
  OMX_ERRORTYPE omx_err = OMX_ErrorNone;
  OMX_STATETYPE state_actual = OMX_StateMax;

  if(!m_handle)
  {
    UnLock();
    return OMX_ErrorUndefined;
  }

  OMX_GetState(m_handle, &state_actual);
  if(state == state_actual)
  {
    UnLock();
    return OMX_ErrorNone;
  }

  omx_err = OMX_SendCommand(m_handle, OMX_CommandStateSet, state, 0);
  if (omx_err != OMX_ErrorNone)
  {
    if(omx_err == OMX_ErrorSameState)
    {
      omx_err = OMX_ErrorNone;
    }
    else
    {
      CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s failed with omx_err(0x%x)\n", 
        m_componentName.c_str(), omx_err);
    }
  }
  else 
  {
    omx_err = WaitForCommand(OMX_CommandStateSet, state);
    if(omx_err == OMX_ErrorSameState)
    {
      CLog::Log(LOGERROR, "COMXCoreComponent::SetStateForComponent - %s ignore OMX_ErrorSameState\n", 
        m_componentName.c_str());
      UnLock();
      return OMX_ErrorNone;
    }
  }

  UnLock();

  return omx_err;
}
Example #4
0
OMX_ERRORTYPE COMXCoreComponent::FreeOutputBuffers(bool wait)
{
  OMX_ERRORTYPE omx_err = OMX_ErrorNone;

  if(!m_handle)
    return OMX_ErrorUndefined;

  if(m_omx_output_buffers.empty())
    return OMX_ErrorNone;

  m_flush_output = true;

  pthread_mutex_lock(&m_omx_output_mutex);
  pthread_cond_broadcast(&m_output_buffer_cond);

  omx_err = DisablePort(m_output_port, false);

  for (size_t i = 0; i < m_omx_output_buffers.size(); i++)
  {
    uint8_t *buf = m_omx_output_buffers[i]->pBuffer;

    omx_err = OMX_FreeBuffer(m_handle, m_output_port, m_omx_output_buffers[i]);

    if(m_omx_output_use_buffers && buf)
      _aligned_free(buf);

    if(omx_err != OMX_ErrorNone)
    {
      CLog::Log(LOGERROR, "COMXCoreComponent::FreeOutputBuffers error deallocate omx output buffer on component %s omx_err(0x%08x)\n", m_componentName.c_str(), omx_err);
    }
  }

  WaitForCommand(OMX_CommandPortDisable, m_output_port);
  assert(m_omx_output_buffers.size() == m_omx_output_available.size());

  m_omx_output_buffers.clear();

  while (!m_omx_output_available.empty())
    m_omx_output_available.pop();

  m_output_alignment    = 0;
  m_output_buffer_size  = 0;
  m_output_buffer_count = 0;

  pthread_mutex_unlock(&m_omx_output_mutex);

  return omx_err;
}
Example #5
0
int main(void)
{

    uint8_t buffer[512];
    uint16_t length = 0;
    uint8_t ret = 0;
    DeviceConfig devState;
    InitSystem(&devState);
    
    //HAL_Delay(1000);
    while (1)
    {
        WaitForCommand(&devState);
    }

}
Example #6
0
void COMXCoreComponent::FlushOutput()
{
  Lock();

  OMX_ERRORTYPE omx_err = OMX_ErrorNone;

  omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_output_port, NULL);

  if(omx_err != OMX_ErrorNone)
  {
    CLog::Log(LOGERROR, "COMXCoreComponent::FlushOutput - Error on component %s omx_err(0x%08x)", 
              m_componentName.c_str(), (int)omx_err);
  }
  WaitForCommand(OMX_CommandFlush, m_output_port);

  UnLock();
}
Example #7
0
OMX_ERRORTYPE COMXCoreComponent::EnablePort(unsigned int port,  bool wait)
{

    if(!m_handle)
        return OMX_ErrorUndefined;

    Lock();

    OMX_ERRORTYPE omx_err = OMX_ErrorNone;

    OMX_PARAM_PORTDEFINITIONTYPE portFormat;
    OMX_INIT_STRUCTURE(portFormat);
    portFormat.nPortIndex = port;

    omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
    if(omx_err != OMX_ErrorNone)
    {
        Logger::LogOut(LOG_LEVEL_ERROR, "COMXCoreComponent::EnablePort - Error get port %d status on component %s omx_err(0x%08x)",
                port, m_componentName.c_str(), (int)omx_err);
    }

    if(portFormat.bEnabled == OMX_FALSE)
    {
        omx_err = OMX_SendCommand(m_handle, OMX_CommandPortEnable, port, NULL);
        if(omx_err != OMX_ErrorNone)
        {
            Logger::LogOut(LOG_LEVEL_ERROR, "COMXCoreComponent::EnablePort - Error enable port %d on component %s omx_err(0x%08x)",
                    port, m_componentName.c_str(), (int)omx_err);
            {
                UnLock();
                return omx_err;
            }
        }
        else
        {
            if(wait)
                omx_err = WaitForCommand(OMX_CommandPortEnable, port);
        }
    }

    UnLock();

    return omx_err;
}
Example #8
0
void COMXCoreComponent::FlushInput()
{
    if(!m_handle)
        return;

    Lock();

    OMX_ERRORTYPE omx_err = OMX_ErrorNone;

    omx_err = OMX_SendCommand(m_handle, OMX_CommandFlush, m_input_port, NULL);

    if(omx_err != OMX_ErrorNone) {
        Logger::LogOut(LOG_LEVEL_ERROR, "COMXCoreComponent::FlushInput - Error on component %s omx_err(0x%08x)",
                m_componentName.c_str(), (int)omx_err);
    }
    WaitForCommand(OMX_CommandFlush, m_input_port);

    UnLock();
}
Example #9
0
OMX_ERRORTYPE COMXCoreComponent::AllocOutputBuffers(bool use_buffers /* = false */)
{
  OMX_ERRORTYPE omx_err = OMX_ErrorNone;

  if(!m_handle)
    return OMX_ErrorUndefined;

  m_omx_output_use_buffers = use_buffers; 

  OMX_PARAM_PORTDEFINITIONTYPE portFormat;
  OMX_INIT_STRUCTURE(portFormat);
  portFormat.nPortIndex = m_output_port;

  omx_err = OMX_GetParameter(m_handle, OMX_IndexParamPortDefinition, &portFormat);
  if(omx_err != OMX_ErrorNone)
    return omx_err;

  if(GetState() != OMX_StateIdle)
  {
    if(GetState() != OMX_StateLoaded)
      SetStateForComponent(OMX_StateLoaded);

    SetStateForComponent(OMX_StateIdle);
  }

  omx_err = EnablePort(m_output_port, false);
  if(omx_err != OMX_ErrorNone)
    return omx_err;

  m_output_alignment     = portFormat.nBufferAlignment;
  m_output_buffer_count  = portFormat.nBufferCountActual;
  m_output_buffer_size   = portFormat.nBufferSize;

  CLog::Log(LOGDEBUG, "COMXCoreComponent::AllocOutputBuffers component(%s) - port(%d), nBufferCountMin(%lu), nBufferCountActual(%lu), nBufferSize(%lu) nBufferAlignmen(%lu)\n",
            m_componentName.c_str(), m_output_port, portFormat.nBufferCountMin,
            portFormat.nBufferCountActual, portFormat.nBufferSize, portFormat.nBufferAlignment);

  for (size_t i = 0; i < portFormat.nBufferCountActual; i++)
  {
    OMX_BUFFERHEADERTYPE *buffer = NULL;
    OMX_U8* data = NULL;

    if(m_omx_output_use_buffers)
    {
      data = (OMX_U8*)_aligned_malloc(portFormat.nBufferSize, m_output_alignment);
      omx_err = OMX_UseBuffer(m_handle, &buffer, m_output_port, NULL, portFormat.nBufferSize, data);
    }
    else
    {
      omx_err = OMX_AllocateBuffer(m_handle, &buffer, m_output_port, NULL, portFormat.nBufferSize);
    }
    if(omx_err != OMX_ErrorNone)
    {
      CLog::Log(LOGERROR, "COMXCoreComponent::AllocOutputBuffers component(%s) - OMX_UseBuffer failed with omx_err(0x%x)\n",
        m_componentName.c_str(), omx_err);

      if(m_omx_output_use_buffers && data)
       _aligned_free(data);

      return omx_err;
    }
    buffer->nOutputPortIndex = m_output_port;
    buffer->nFilledLen       = 0;
    buffer->nOffset          = 0;
    buffer->pAppPrivate      = (void*)i;
    m_omx_output_buffers.push_back(buffer);
    m_omx_output_available.push(buffer);
  }

  omx_err = WaitForCommand(OMX_CommandPortEnable, m_output_port);

  m_flush_output = false;

  return omx_err;
}
Example #10
0
// Function name	: LaunchMPDProcess
// Description	    : 
// Return type		: void 
// Argument         : LaunchMPDProcessArg *pArg
void LaunchMPDProcess(LaunchMPDProcessArg *pArg)
{
	char pBuffer[4096];
	char pszEnv[1024] = "";
	char pszDir[MAX_PATH] = ".";
	char pszCmd[1024] = "";
	char pszArg[1024] = "";
	char pszCmdLine[4096] = "";
	char pszStdinHost[100] = "";
	char pszStdoutHost[100] = "";
	char pszStderrHost[100] = "";
	int nStdinPort = 0, nStdoutPort = 0, nStderrPort = 0;
	int nGroupID = -1, nGroupRank = -1;
	char *token;
	HANDLE hStdin, hStdout, hStderr;
	HANDLE hStdoutPipeW=NULL, hStderrPipeW = NULL, hStdinPipeR=NULL;
	HANDLE hStdoutPipeR=NULL,                      hStdinPipeW=NULL;
	HANDLE hTempPipe=NULL;
	STARTUPINFO saInfo;
	PROCESS_INFORMATION psInfo;
	void *pEnv=NULL;
	char pszSavedPath[MAX_PATH] = ".";
	bool bSuccess = false;
	int nError;
	unsigned long nSrcIP;
	int nSrcPort;
	LaunchNode *pLaunchNode;

	//printf("cmd before: %s\n", pArg->pszCommand);fflush(stdout);
	GetStringOpt(pArg->pszCommand, 'e', pszEnv);
	GetStringOpt(pArg->pszCommand, 'd', pszDir);
	GetStringOpt(pArg->pszCommand, 'c', pszCmd);
	GetStringOpt(pArg->pszCommand, 'a', pszArg);
	//printf("cmd after : %s\n", pArg->pszCommand);fflush(stdout);
	//printf("pszArg: %s\n", pszArg);fflush(stdout);

	if (GetStringOpt(pArg->pszCommand, '0', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStdinHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStdinPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, '1', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStdoutHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStdoutPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, '2', pBuffer) == 0)
	{
		token = strtok(pBuffer, ":");
		if (token != NULL)
		{
			strcpy(pszStderrHost, token);
			token = strtok(NULL, "");
			if (token != NULL)
			{
				nStderrPort = atoi(token);
			}
		}
	}

	if (GetStringOpt(pArg->pszCommand, 'g', pBuffer) == 0)
		nGroupID = atoi(pBuffer);

	if (GetStringOpt(pArg->pszCommand, 'r', pBuffer) == 0)
		nGroupRank = atoi(pBuffer);

	pLaunchNode = pArg->pNode;
	nSrcIP = pArg->nSrcIP;
	nSrcPort = pArg->nSrcPort;

	delete pArg->pszCommand;
	delete pArg;
	pArg = NULL;

	// Create the command line
	HMODULE hModule = GetModuleHandle(NULL);
	if (!GetModuleFileName(hModule, pszCmdLine, 4096))
		strcpy(pszCmdLine, "mpd.exe");
	if (pszCmd[0] == '\"')
	{
		if (strlen(pszArg))
			sprintf(pBuffer, " -cmd %s -args \"%s\"", pszCmd, pszArg);
		else
			sprintf(pBuffer, " -cmd %s", pszCmd);
	}
	else
	{
		if (strlen(pszArg))
			sprintf(pBuffer, " -cmd \"%s\" -args \"%s\"", pszCmd, pszArg);
		else
			sprintf(pBuffer, " -cmd \"%s\"", pszCmd);
	}
	strcat(pszCmdLine, pBuffer);
	if (strlen(pszEnv) > 0)
	{
		sprintf(pBuffer, " -env \"%s\"", pszEnv);
		strcat(pszCmdLine, pBuffer);
	}
	if (strlen(pszDir) > 0)
	{
		sprintf(pBuffer, " -dir \"%s\"", pszDir);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStdinPort != 0)
	{
		sprintf(pBuffer, " -0 %s:%d", pszStdinHost, nStdinPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStdoutPort != 0)
	{
		sprintf(pBuffer, " -1 %s:%d", pszStdoutHost, nStdoutPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nStderrPort != 0)
	{
		sprintf(pBuffer, " -2 %s:%d", pszStderrHost, nStderrPort);
		strcat(pszCmdLine, pBuffer);
	}
	if (nGroupID != -1)
	{
		sprintf(pBuffer, " -group %d", nGroupID);
		strcat(pszCmdLine, pBuffer);
	}
	if (nGroupRank != -1)
	{
		sprintf(pBuffer, " -rank %d", nGroupRank);
		strcat(pszCmdLine, pBuffer);
	}

	//printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout);

	WaitForSingleObject(g_hLaunchMutex, INFINITE);

	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);

	// Get and save the current standard handles
	hStdin = GetStdHandle(STD_INPUT_HANDLE);
	if (hStdin == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stdin, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}
	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hStdout == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stdout, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}
	hStderr = GetStdHandle(STD_ERROR_HANDLE);
	if (hStderr == INVALID_HANDLE_VALUE)
	{
		nError = GetLastError();
		printf("0 GetStdHandle failed for stderr, error %d\n", nError);fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
		return;
	}

	// Set the security attributes to allow handles to be inherited
	SECURITY_ATTRIBUTES saAttr;
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.lpSecurityDescriptor = NULL;
	saAttr.bInheritHandle = TRUE;

	// Create an event to be signalled to abort the mpd child process
	HANDLE hAbortEvent = CreateEvent(&saAttr, TRUE, FALSE, NULL);
	sprintf(pBuffer, " -hAbortEvent %u", (int)hAbortEvent);
	strcat(pszCmdLine, pBuffer);
	//printf("hAbortEvent: %d\n", (int)hAbortEvent);fflush(stdout);

	//printf("launching:\n'%s'\n", pszCmdLine); fflush(stdout);

	// Create pipes for stdin, stdout

	// Stdout
	if (!CreatePipe(&hTempPipe, &hStdoutPipeW, &saAttr, 0))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	// Make the read end of the stdout pipe not inheritable
	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 
		GetCurrentProcess(), &hStdoutPipeR, 
		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
	{
		nError = GetLastError();
		goto CLEANUP;
	}

	// Stdin
	if (!CreatePipe(&hStdinPipeR, &hTempPipe, &saAttr, 0))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	// Make the write end of the stdin pipe not inheritable
	if (!DuplicateHandle(GetCurrentProcess(), hTempPipe, 
		GetCurrentProcess(), &hStdinPipeW, 
		0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
	{
		nError = GetLastError();
		goto CLEANUP;
	}

	// Set stdin, stdout, and stderr to the ends of the pipe the created process will use
	if (!SetStdHandle(STD_INPUT_HANDLE, hStdinPipeR))
	{
		nError = GetLastError();
		goto CLEANUP;
	}
	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdoutPipeW))
	{
		nError = GetLastError();
		goto RESTORE_CLEANUP;
	}
	if (!SetStdHandle(STD_ERROR_HANDLE, hStdoutPipeW))
	{
		nError = GetLastError();
		goto RESTORE_CLEANUP;
	}

	// Set up the STARTINFO structure
	memset(&saInfo, 0, sizeof(STARTUPINFO));
	saInfo.cb         = sizeof(STARTUPINFO);
	saInfo.hStdInput  = hStdinPipeR;
	saInfo.hStdOutput = hStdoutPipeW;
	saInfo.hStdError  = hStdoutPipeW;
	saInfo.dwFlags    = STARTF_USESTDHANDLES;

	if (CreateProcess(
		NULL,
		pszCmdLine,
		NULL, NULL, TRUE,
		//DETACHED_PROCESS | IDLE_PRIORITY_CLASS, 
		//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS,
		CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,
		//DETACHED_PROCESS | IDLE_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP,
		//CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS | CREATE_SUSPENDED, 
		NULL, //pEnv,
		NULL,
		&saInfo, &psInfo))
	{
		CloseHandle(psInfo.hThread);
		bSuccess = true;
	}
	else
	{
		nError = GetLastError();
		printf("CreateProcess failed for '%s', error %d\n", pszCmdLine, nError);
	}

RESTORE_CLEANUP:
	// Restore stdin, stdout, stderr
	if (!SetStdHandle(STD_INPUT_HANDLE, hStdin))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stdin, error %d\n", nError);
	}
	if (!SetStdHandle(STD_OUTPUT_HANDLE, hStdout))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stdout, error %d\n", nError);
	}
	if (!SetStdHandle(STD_ERROR_HANDLE, hStderr))
	{
		nError = GetLastError();
		printf("SetStdHandle failed to restore stderr, error %d\n", nError);
	}

CLEANUP:

	CloseHandle(hStdoutPipeW);
	CloseHandle(hStdinPipeR);

	if (bSuccess)
	{
		MPD_CMD_HANDLE hCmd;
		CommandData cmd;
		char *pBuf;

		ProcessNode *p = new ProcessNode;
		strcpy(p->pszCmdLine, pszCmdLine);
		p->nPid = psInfo.dwProcessId;
		//printf("%d\n", psInfo.dwProcessId);fflush(stdout);
		p->nGroupID = nGroupID;
		p->hAbortEvent = hAbortEvent;
		p->hProcess = psInfo.hProcess;
		p->pNext = g_pProcessList;
		g_pProcessList = p;

		cmd.nCommand = MPD_CMD_LAUNCH_RET;
		pBuf = cmd.pCommandBuffer;
		*((unsigned long *)pBuf) = nSrcIP;
		pBuf = pBuf + sizeof(unsigned long);
		*((int *)pBuf) = nSrcPort;
		pBuf = pBuf + sizeof(int);
		*((LaunchNode **)pBuf) = pLaunchNode;
		pBuf = pBuf + sizeof(LaunchNode *);
		*((DWORD*)pBuf) = psInfo.dwProcessId;
		cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		ReleaseMutex(g_hLaunchMutex);

		// Tell everyone on the ring that the load on this node has increased by one process.
		cmd.nCommand = MPD_CMD_INCREMENT;
		cmd.hCmd.nBufferLength = 0;
		//printf("Inserting INCREMENT command.\n");fflush(stdout);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		TerminalClientThreadArg *pArg = new TerminalClientThreadArg;
		pArg->hInput = hStdoutPipeR;
		pArg->hOutput = hStdinPipeW;
		TerminalClientThread(pArg);
		// The process should already have exited causing the TerminalClientThread function to return.
		WaitForSingleObject(psInfo.hProcess, 1000);
		// Remove the process handle from the list by setting it to NULL
		WaitForSingleObject(g_hLaunchMutex, 10000);
		p = g_pProcessList;
		while (p != NULL)
		{
			if (p->hProcess == psInfo.hProcess)
			{
				p->hProcess = NULL;
				break;
			}
			p = p->pNext;
		}
		ReleaseMutex(g_hLaunchMutex);

		// Tell everyone on the ring that the load on this node has decreased by one process.
		cmd.nCommand = MPD_CMD_DECREMENT;
		cmd.hCmd.nBufferLength = 0;
		//printf("Inserting DECREMENT command.\n");fflush(stdout);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		// Send the exit code back
		cmd.nCommand = MPD_CMD_LAUNCH_EXITCODE;
		pBuf = cmd.pCommandBuffer;
		*((unsigned long *)pBuf) = nSrcIP;
		pBuf = pBuf + sizeof(unsigned long);
		*((int *)pBuf) = nSrcPort;
		pBuf = pBuf + sizeof(int);
		*((LaunchNode **)pBuf) = pLaunchNode;
		pBuf = pBuf + sizeof(LaunchNode *);
		GetExitCodeProcess(psInfo.hProcess, (DWORD*)pBuf);
		//printf("Process exiting, send exit code: %d\n", *(DWORD*)pBuf);fflush(stdout);
		pBuf = pBuf + sizeof(DWORD);
		*((int *)pBuf) = nGroupID;
		pBuf = pBuf + sizeof(int);
		*((int *)pBuf) = nGroupRank;
		cmd.hCmd.nBufferLength = sizeof(unsigned long) + sizeof(int) + sizeof(LaunchNode*) + sizeof(DWORD) + sizeof(int) + sizeof(int);
		hCmd = InsertCommand(cmd);
		WaitForCommand(hCmd);

		CloseHandle(psInfo.hProcess);
	}
	else
	{
		//printf("0\n");fflush(stdout);
		ReleaseMutex(g_hLaunchMutex);
	}

	CloseHandle(hStdoutPipeR);
	CloseHandle(hStdinPipeW);
}