Daniel42
November 6th, 2004, 01:05 AM
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.
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.
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.
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.