Note that there are some explanatory texts on larger screens.

plurals
  1. POSerial Port Receive Thread Not Behaving as Expected - C++
    primarykey
    data
    text
    <p>My application uses a separate thread for handling received serial data asynchronously. The PC gets into the receive-handler as expected, but from there things go weird.</p> <p>This is my thread function:</p> <pre><code>// Create event for OVERLAPPED structure. s_ov.hEvent = ::CreateEvent( NULL, // No security TRUE, // Create a manual-reset event object FALSE, // Initial state is non-signaled NULL // No name specified ); // Load event handles. pHandles[0] = s_hSerialPortRxThreadExitEvent; while ( bContinue ) { if ( !::WaitCommEvent( s_hSerialPort, &amp;dwEventMask, &amp;s_ov ) ) { if ( ::GetLastError() != ERROR_IO_PENDING ) { TRACE(_T("SerialPortRxThreadFn : Call to WaitCommEvent failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); return ::GetLastError(); } } pHandles[1] = s_ov.hEvent; dwObjectWaitState = ::WaitForMultipleObjects( 2, pHandles, FALSE, INFINITE ); switch ( dwObjectWaitState ) { case WAIT_ABANDONED: TRACE(_T("SerialPortRxThreadFn : Owner thread terminated prematurely.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ERROR_ARENA_TRASHED, __WFILE__, __LINE__); return ERROR_ARENA_TRASHED; break; case WAIT_TIMEOUT: TRACE(_T("SerialPortRxThreadFn : The timeout is set to INFINITE; there should be no timeout. State is nonsignaled.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), WAIT_TIMEOUT, __WFILE__, __LINE__); return WAIT_TIMEOUT; break; case WAIT_FAILED: TRACE(_T("SerialPortRxThreadFn : Call to WaitCommEvent failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); return ::GetLastError(); break; case WAIT_OBJECT_0: // thread exit event signalled bContinue = FALSE; if ( !::ResetEvent( pHandles[0] ) ) { TRACE(_T("SerialPortRxThreadFn : Failed to reset the serial port thread exit event.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); return ::GetLastError(); } break; case WAIT_OBJECT_0 + 1: // OVERLAPPED structure event signalled // Read data from serial port. if ( !::ReadFile( s_hSerialPort, pBuf, RX_BUF_SIZE, &amp;dwWritten, &amp;s_ov ) ) // &lt;- Set breakpoint here { TRACE(_T("SerialPortRxThreadFn : Call to ReadFile filed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); return ::GetLastError(); } // Discontinue thread operation if there are no more bytes in the serial port receive buffer. if ( dwWritten == 0 ) // &lt;- Or, set breakpoint here { bContinue = FALSE; } // Copy the received bytes to the thread-safe buffer. else if ( !s_pobjRxRingBuffer-&gt;Add( pBuf, dwWritten, TRUE ) ) { TRACE(_T("SerialPortRxThreadFn : Failed to add bytes to ring buffer.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ERROR_INSUFFICIENT_BUFFER, __WFILE__, __LINE__); return ERROR_INSUFFICIENT_BUFFER; } else if ( s_SpCallbackFn != NULL ) { // Notify application of received data. if ( (dwRetVal = s_SpCallbackFn( s_pobjRxRingBuffer-&gt;ItemsInBuffer() )) != ERROR_SUCCESS ) { TRACE(_T("SerialPortRxThreadFn : Serial port callback function failed.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), dwRetVal, __WFILE__, __LINE__); return dwRetVal; } } if ( !::ResetEvent( pHandles[1] ) ) { TRACE(_T("SerialPortRxThreadFn : Failed to reset the OVERLAPPED structure event.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); return ::GetLastError(); } break; default: // Do nothing. break; } } ::CloseHandle( s_ov.hEvent ); return ERROR_SUCCESS; </code></pre> <p>If I set my breakpoint on the line calling <code>ReadFile</code> everything works as I expect, and the PC gets into the callback function. However, if I set my breakpoint at the next line, where <code>dwWritten</code> is evaluated for zero, it is zero, the expression evaluates as TRUE, and the loop exits; the PC never gets to the callback. What am I doing wrong? Thanks.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload