bug-commoncpp
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

win32 serial.cpp patch for isPending


From: Adib Taraben
Subject: win32 serial.cpp patch for isPending
Date: Wed, 25 Feb 2004 17:50:09 +0100
User-agent: Mozilla Thunderbird 0.5 (Windows/20040207)

Hello all,

attached there is a patch for the win32 path of serial.cpp

As I already mention Serial::isPending does not wait until timeout but returns immediately.

To avoid this and have a defined timeout there is a need for "overlapped" io.

I changed the affected functions: open, aRead, aWrite, isPending.

I tested with serialecho from demo I could remove that "sleep(500)" with no CPU-load.

Note:
I mentioned that aRead and aWrite are always called with Length=1. As I create in this function the OVERLAPPED structure, then initialize ... .
First we can check why is aWrite not called by a chunk of bytes.
And I think it is better to have 3 separate OVERLAPPED members for read, write, wait. They can be initialized once.

Any comments?

Adib.


serial.diff
431c431
<                     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | 
FILE_FLAG_NO_BUFFERING,
---
>                     FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL | 
> FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
442c442
<       unsigned long   dwLength, dwError;
---
>       unsigned long   dwLength = 0, dwError, dwReadLength;
444,452c444,478
< 
<       // Clear the com port of any error condition prior to read
<       ClearCommError(dev, &dwError, &cs);
< 
< 
< 
<       if (0 == ReadFile(dev, (void *)Data, (unsigned long)Length, &dwLength, 
NULL))
<               return 0;
< 
---
>     OVERLAPPED ol;
>     
>     // Return zero if handle is invalid
>     if(dev == INVALID_HANDLE_VALUE)
>         return 0;
> 
>     // Read max length or only what is available
>     ClearCommError(dev, &dwError, &cs);
> 
>     // If not requiring an exact byte count, get whatever is available
>     if(dwLength > (int)cs.cbInQue)
>         dwReadLength = cs.cbInQue;
>     else
>         dwReadLength = Length;
> 
>     memset(&ol, 0, sizeof(OVERLAPPED));
>     ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
>     
>     if(dwReadLength > 0)
>     {
>         if(ReadFile(dev, Data, dwReadLength, &dwLength, &ol) == FALSE) 
>         {
>             if(GetLastError() == ERROR_IO_PENDING)
>             {
>                 WaitForSingleObject(ol.hEvent, INFINITE);
>                 GetOverlappedResult(dev, &ol, &dwLength, TRUE);
>             }
>             else
>                 ClearCommError(dev, &dwError, &cs);
>         }
>     }
>         
>     if(ol.hEvent != INVALID_HANDLE_VALUE)
>         CloseHandle(ol.hEvent);
>         
459a486
>     OVERLAPPED ol;
465c492,509
<       WriteFile(dev, Data, Length, &retSize, NULL);
---
>     
>     memset(&ol, 0, sizeof(OVERLAPPED));
>     ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
>       
>     if(WriteFile(dev, Data, Length, &retSize, &ol) == FALSE)
>     {
>         if(GetLastError() == ERROR_IO_PENDING)
>         {
>             WaitForSingleObject(ol.hEvent, INFINITE);
>             GetOverlappedResult(dev, &ol, &retSize, TRUE);
>         }
>         else
>             ClearCommError(dev, &dwError, &cs);
>     }
>     
>     if(ol.hEvent != INVALID_HANDLE_VALUE)
>         CloseHandle(ol.hEvent);
>         
865c909
<       ClearCommError(dev, &dwError, &cs);
---
>     ClearCommError(dev, &dwError, &cs);
867,875c911,955
<       switch(pending)
<       {
<       case pendingInput:
<               return (0 != cs.cbInQue);
<       case pendingOutput:
<               return (0 != cs.cbOutQue);
<       case pendingError:
<               return false;
<       }
---
>       if(timeout == 0 || ((pending == pendingInput) && (0 != cs.cbInQue)) ||
>          ((pending == pendingOutput) && (0 != cs.cbOutQue)) || (pending == 
> pendingError)) 
>     {
>       switch(pending)
>       {
>       case pendingInput:
>             return (0 != cs.cbInQue);
>       case pendingOutput:
>               return (0 != cs.cbOutQue);
>       case pendingError:
>               return false;
>       }
>     }
>     else
>     {
>         OVERLAPPED ol;
>         DWORD dwMask;
>         BOOL suc;
>                 
>         memset(&ol, 0, sizeof(OVERLAPPED));
>         ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
> 
>       if(pending == pendingInput)
>             dwMask = EV_RXCHAR;
>       else if(pending == pendingOutput)
>             dwMask = EV_TXEMPTY;
>       else   // on error
>             dwMask = EV_ERR;
> 
>         SetCommMask(dev, dwMask);
>         // let's wait for event or timeout
>         if((suc = WaitCommEvent(dev, &dwMask, &ol)) == FALSE)
>         {
>             if(GetLastError() == ERROR_IO_PENDING)
>             {
>                 dwError = WaitForSingleObject(ol.hEvent, timeout);
>                 suc = (dwError == WAIT_OBJECT_0);
>                 SetCommMask(dev, 0);
>             }
>             else
>                 ClearCommError(dev, &dwError, &cs);
>         }
>       
>         if(ol.hEvent != INVALID_HANDLE_VALUE)
>             CloseHandle(ol.hEvent);
876a957,958
>         return suc;
>     }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]