> Since I'm being blamed for global warming anyway (see, globals /are/ bad -
> not that I subscribe to that book-bashing theory {:v) )...
Ooops I think that was initially my fault... Like a carelessly discarded
cigarette butt my comment seems to have sparked a large flame :(
Hmm I didn't mean to imply that you _should_ use a global variable, merely
that you _could_!!
...Anyhoo, I'll try and be some assistance about your question rather than
getting drawn into stylistic arguments. (BTW I wouldn't have any problems if
I had to maintain your code).
> The problem I was hearing about (and can see for myself) is 100% CPU being
> hogged.
Hmm this was never problem back in the old MS-DOS days :)...
This bit of code seems fine to me, although there's no need for the
bTerminationComplete flag. You can wait in the main thread for the worker
thread's handle to become signalled signifying that the thread is truely
dead.
UINT CommsRXThreadProc(LPVOID pvParam)
{
COMMS_RX_THREAD_DATA_S *psThreadData ;
DWORD dwNumBytes ;
OVERLAPPED sNotifyOverlapData ;
psThreadData = (COMMS_RX_THREAD_DATA_S *)pvParam ;
if (psThreadData != NULL)
{
// Set it up to notify us of incoming data.
::SetCommMask(psThreadData->hPortHandle, EV_RXCHAR);
memset(&sNotifyOverlapData, 0, sizeof(OVERLAPPED) );
sNotifyOverlapData.hEvent = ::CreateEvent(NULL, FALSE, FALSE,
NULL);
while (!psThreadData->bTerminate)
{
dwNumBytes = WaitForRX(*psThreadData,
sNotifyOverlapData);
if (dwNumBytes > 0)
ReceiveBytes(*psThreadData, dwNumBytes);
}
::CloseHandle(sNotifyOverlapData.hEvent);
psThreadData->bTerminationComplete = TRUE ;
}
return 0 ;
}
> Yes, there's a tight little loop in there also, but this is what
WaitForRX()
> does:
I think the problem lies in this routine....
DWORD WaitForRX(COMMS_RX_THREAD_DATA_S& rsThreadData, OVERLAPPED&
rsNotifyOverlapData)
{
BOOL bDone ;
COMSTAT sStatus ;
DWORD dwEvent, dwError, dwDummy, dwNumBytes ;
dwNumBytes = 0 ; // Until we have definitely been notified of
something
// being received.
if (!::WaitCommEvent(rsThreadData.hPortHandle, &dwEvent,
&rsNotifyOverlapData) )
{
dwError = ::GetLastError();
if (dwError == ERROR_IO_PENDING)
{
bDone = FALSE ;
// Wait for completion of WaitCommEvent()
while (!rsThreadData.bTerminate && !bDone)
---> Here is where I think the problem is coming about. According to the
MSDN:
"If the overlapped operation cannot be completed immediately, the function
returns FALSE and the GetLastError function returns ERROR_IO_PENDING,
indicating that the operation is executing in the background. When this
happens, the system sets the hEvent member of the OVERLAPPED structure to
the not-signaled state before WaitCommEvent returns, and then it sets it to
the signaled state when one of the specified events or an error occurs. The
calling process can use one of the wait functions to determine the event
object's state and then use the GetOverlappedResult function to determine
the results of the WaitCommEvent operation. GetOverlappedResult reports the
success or failure of the operation, and the variable pointed to by the
lpEvtMask parameter is set to indicate the event that occurred."
So instead of sitting in a while loop you should wait on the event handle
stored inside the overlapped structure. This will enable the thread to yield
until the I/O actually occurs. Then GetOverlappedResult can be used to
retrieve the information.
Daniel
_______________________________________________
msvc mailing list
[email protected]
See http://beginthread.com/mailman/listinfo/msvc_beginthread.com for
subscription changes, and list archive.