0

I'm handling a non-standard modem via serial port in an overlapped manner. Besides reading from and writing to the telecommunication line, I have to check the control lines like CTS and DSR using the WaitCommEvent() function.

DWORD EvtMask;
/// (some scopes/levels ommitted)

const BOOL syncChange = WaitComEvent(hFile, &EvtMask, &overlapped);
if (!syncChange) {
    assert(GetLastError() == ERROR_IO_PENDING);
    /// *background activity* probably writing into EvtMask
    /// until overlapped.hEvent gets signalled
}

In the (practically all) cases the function call indicates *background activity*, I have to wait on the overlapped.hEvent to happen. Since I'm also waiting for events from alternative sources (like IPC caused by user input, program termination), I use the WaitForMuiltipleObjects() function. But, if the blocking wait is finished for other reasons than control line changes, how can I stop the background activity on EvtMask? The code I'm based on, currently uses SetCommMask(hFile, 0), but I did not find a reliable reference for this being appropriate.

I also observe cases where changes to control lines are not supported properly (driver?, VM?), so I have to do a sliced wait with in-between checking.

What must be done to safely leave the scope where the variable EvtMask is declared?

Wolf
  • 9,679
  • 7
  • 62
  • 108

1 Answers1

1

The code you have is correct, and fully supported by the documentation, which clearly says:

If a process attempts to change the device handle's event mask by using the SetCommMask function while an overlapped WaitCommEvent operation is in progress, WaitCommEvent returns immediately.

I've used this fact on both "real" serial ports, and USB virtual serial port emulations, and it works reliably.

(In my particular case, I was watching for EV_TXEMPTY so that I could guarantee a minimal separation between certain transmissions on the wire)

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Nice, this very portion was *not* clear to me. It mixes WaitCommEvent-calls and the operation started in background. Nevertheless thanks for having a look at it. And it's definitely helpful :-) – Wolf Oct 10 '14 at 12:46
  • Just a tiny detail: after calling `SetCommMask` with the zero mask, have you to call `WaitCommEvent` once more? – Wolf Oct 13 '14 at 07:50
  • @Wolf: The pending `WaitCommEvent` operation will complete immediately (or at least, very soon -- don't assume you have your memory back as soon as `SetCommMask` is called). So if you want notifications once more, you have to call it once more. – Ben Voigt Oct 13 '14 at 13:03
  • If I use a zero mask, then there will be probably no real notifications. But it seems likely that the variable I used in the `WaitCommEvent` call is still bound. Don't I have to call `GetOverlappedResult(..., TRUE)`? – Wolf Oct 15 '14 at 09:00
  • @Wolf: You should handle a forced completion the same way you handle any other. Call `GetOverlappedResult` and if you are still interested in events, call `WaitCommEvent` again, otherwise you can do away with the memory. – Ben Voigt Oct 15 '14 at 14:09