views:

316

answers:

1

Is it possible to use IO Completion Ports for Serial I/O? According to Windows via C/C++ it is alluded to that it is possible, and does give an example of using IOCP with physical files showing work with CreateFile, ReadFile, WriteFile, etc. However can this actually work with serial comms - has anyone got it working?

I can't find any examples of this on the web, but I cannot be the first to attempt it?

+3  A: 

Yes, using I/O Completion Ports for Serial I/O works fine. There is some setup work needed to create a file handle for a serial port that is appropriate for IOCP. But once the setup is done, you can do asynchronous ReadFile() and WriteFile() operations just like with regular file handles and socket handles.

The setup is basically:

  1. Open serial port with CreateFile() passing in the FILE_FLAG_OVERLAPPED value as the dwFlagsAndAttributes parameter.
  2. Modify the serial port state as desired using GetCommState() and SetCommState(). Do this just like you would do when not using IOCP.
  3. Use GetCommTimeouts() and SetCommTimeouts() to turn off total-timeouts for read operations, since it typically doesn't make sense to have timeouts for asynchronous operations. (You would instead explicitly call CancelIO() to cancel a read operation instead.) Turning off total-timeouts is done by setting the ReadTotalTimeoutMultiplier and ReadTotalTimeoutConstant fields of the COMMTIMEOUTS structure to zero.

Now you can use the handle with IOCP just like you would do with regular file handles and socket handles. I.e. attach the handle to a completion port using CreateIoCompletionPort(), initiate I/O operations with ReadFile() or WriteFile() using an OVERLAPPED structure, dequeue completed, failed or canceled operations from the completion port using the GetQueuedCompletionStatus() function.

Additional serial port specific events can also be retrieved asynchronously using the WaitCommEvent() function.

Rolf W. Rasmussen
Ahh. I wasn't using GetCommTimeouts which was probably where I was going wrong - I could form a connection but not pass anything across.
graham.reeds
CancelIo() is completely broken. See http://stackoverflow.com/questions/3921111/how-to-find-out-when-cancelio-is-done for more information.
Gili