CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Nov 2004
    Posts
    2

    Exclamation Trouble exiting worker thread.

    Hi, I'm relatively new to the programming world, but decided to take on a fairly difficult challenge for someone who'd never programmed for Pocket PC and do a final year engineering assignment contain some subtantial programming.

    I have run into difficulties with a worker thread. I am using it for the monitoring of a Bluetooth serial port. I am using the WaitCommEvent() function in combination with ReadFile() to read in data from the port. As I am programming for the Pocket PC platform I am unable to used overlapped files, and therefore the WaitCommEvent() function is blocking. When I want to exit the program, I believe that the thread is not being exitted due to the blocking funciton. This results in part of the process still running. The program can not be subsequently executed, and when I try to delete the executable file I get a file sharing violation error.

    Could anyone please assist me in exiting the funciton?

    My code for the thread, and other various functions is below. I believe the problem lies in the thread as I have eliminated the WaitCommEvent() function and the program exits successfully.
    Code:
    DWORD WINAPI CRealtimeTab::TheSerialThread(LPVOID lpVoid)
    {
    	int i = 0;
    	int Counter = 0;
    	int intLength = 0;
    	
    	DWORD dwCommEvent = NULL;
    	DWORD dwBytesRead;
    	
    	char *ProcessChar = new char[1024];
    	char *chSerialInData = new char[1024];
    	char chRead;
    
    	CString CstrThreadMessage;
    	char *charThreadMessage;
    
    	
    	COMMTIMEOUTS Timeout;
    
    	Timeout.ReadIntervalTimeout = 50;
    	Timeout.ReadTotalTimeoutConstant = 100;
    	Timeout.ReadTotalTimeoutMultiplier = 50;
    	Timeout.WriteTotalTimeoutConstant = 100;
    	Timeout.WriteTotalTimeoutMultiplier = 50;
    
    	CRealtimeTab *DLG;
    	DLG = (CRealtimeTab*)lpVoid;
    
    	GetExitCodeThread(DLG->SerialThread, &dwThreadExitCode);
    
    	SetCommTimeouts(DLG->hComPort, &Timeout);
    
    
    	if (!SetCommMask(DLG->hComPort, EV_RXCHAR))
    	// Error setting communications event mask
    	CstrThreadMessage.Format(_T("Error setting communications event mask"));
    	charThreadMessage = GetAnsiString(CstrThreadMessage, CP_ACP);
    	::PostMessage(DLG->m_hWnd, UWM_THREAD_MSG, (WPARAM)charThreadMessage, 0);
    
    	do
    	{
    		Counter = 0;
    		chSerialInData = new char[1024];
    
    		if(WaitCommEvent(DLG->hComPort, &dwCommEvent, NULL))
    		{
    				do
    				{
    					if(ReadFile(DLG->hComPort, &chRead, 1, &dwBytesRead, NULL))
    					{
    						// A byte has been read; process it.
    						ProcessChar[Counter] = chRead;
    						Counter++;
    					}
    					else
    					{
    						// An error occurred in the ReadFile call.
    						CstrThreadMessage.Format(_T("Read Error:\nGetLastError() returns %d"), GetLastError());
    						charThreadMessage = GetAnsiString(CstrThreadMessage, CP_ACP);
    						::PostMessage(DLG->m_hWnd, UWM_THREAD_MSG, (WPARAM)charThreadMessage, 0);
    						Sleep(0);
    						break;
    					}
    				}while(dwBytesRead);
    			
    
    				for(i = 0; i < (Counter - 1); i++)
    				{
    					chSerialInData[i] = ProcessChar[i];
    				}
    	
    				delete [] chSerialInData;
    				::PostMessage(DLG->m_hWnd, UWM_RX_SERIAL_DATA, (WPARAM)chSerialInData, (LPARAM)(Counter-1));
    		}
    		else
    		{
    			// Error in WaitCommEvent
    			CstrThreadMessage.Format(_T("Error in WaitCommEvent"));
    			charThreadMessage = GetAnsiString(CstrThreadMessage, CP_ACP);
    			::PostMessage(DLG->m_hWnd, UWM_THREAD_MSG, (WPARAM)charThreadMessage, 0);
    			break;
    		}
    	}while(WaitForSingleObject(DLG->ExitEvent, INFINITE) != WAIT_OBJECT_0);
    	
    	ExitThread(dwThreadExitCode);
    	return 1;
    }
    
    void CRealtimeTab::OnDestroy() 
    {
    	CDialog::OnDestroy();
    	
    	CloseComms();
    	
    	CDialog::OnClose();
    	
    }
    
    void CRealtimeTab::CloseComms()
    {
    	ExitEvent = CreateEvent(NULL, FALSE, FALSE, _T("Exit"));
    	
    	SetEvent(ExitEvent);
    
    	CloseHandle(SerialThread);
    
    	delete SerialThread;
    
    	ClearVariables();
    
    	m_pDevice->SPPDisconnect();
    	DisconnectFromStack();
    	m_pStack->BtRadioOff();
    
    	MessageBox(_T("Closing Comms"), NULL, MB_OK);
    
    	delete m_pDevice;
    	delete m_pStack;
    }
    Regards
    Daniel.
    Last edited by Andreas Masur; November 6th, 2004 at 06:48 AM. Reason: Added code tags...

  2. #2
    Join Date
    Jun 2004
    Location
    Chicago, United States
    Posts
    88

    Re: Trouble exiting worker thread.

    You call WaitCommEvent with lpOverlapped = NULL. It is a blocking call and it means the thread function waits for an event to occur (EV_RXCHAR in your example). If there are no input bytes the WaitCommEvent does not return and your thread is frozen.
    You can use the code shown below to shutdown the thread :
    Code:
    // thread function
    DWORD WINAPI CRealtimeTab::TheSerialThread(LPVOID lpVoid)
    {
    	// use shutdown event (m_hShutdownEvent) and WaitForSingleObject() in your thread
    	if(::WaitForSingleObject(m_hShutdownEvent,0)==WAIT_OBJECT_0)
    	{
    		return 0;	// return from the thread
    	}
    	....
    	Your code
    	....
    }
    // Shutdown function
    CRealtimeTab::Shutdown()
    {
    	::SetEvent(m_hShutdownEvent); // set shutdown event
    	SetCommMask(m_hComPort, 0); // unblock the thread (WaitCommEvent returns immediately after this call)
    	if(::WaitForSingleObject(m_hYourThread,1000)!=WAIT_OBJECT_0) // m_hYourThread is a handle to the thread
    		::TerminateThread(m_hYourThread,1);
    );
    }
    Last edited by amarcode; November 6th, 2004 at 12:32 PM.
    A.M.
    My Latest Articles:
    CCustomBitmapButton - An owner-draw button and a frame for the caption bar, in one class.
    CCustomTabCtrl - A clone of the Excel tab sheet control.

  3. #3
    Join Date
    Nov 2004
    Posts
    2

    Re: Trouble exiting worker thread.

    Thanks heaps amarcode, I'll give it a try!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured