Wireshark-dev: [Wireshark-dev] Waiting for something to happen on a pipe/socket on Windows
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Tue, 27 Jun 2017 13:59:49 -0700
(Sending to a broader list, in case anybody has answers.)

On Jun 26, 2017, at 10:53 AM, Stig Bjørlykke <stig@xxxxxxxxxxxxx> wrote:

> The extcap interface toolbar is not supported on Windows yet,
> basically because I don't know how the pipe handling is done when
> using select(),

Sadly, Windows' handling of "wait for something to happen" is a bit clumsier than UN*X's.

UN*Xes have select() and poll(), with the possible addition of some other similar mechanisms such as Linux's epoll() or *BSD/Darwin's kqueues.  You can wait for a device, a socket, or a pipe with them.  (Sadly, in the general case, you can't wait for a process or thread to terminate with select(), although you can do it with kqueues on at least some platforms.  I'm not sure whether the inability to wait for a mutex to unlock or a condition variable to be signaled is a significant issue or not.)

Windows has select()

	https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx

which works on sockets, sockets, sockets, and sockets, and WaitForMultipleObjects():

	https://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

which works on a number of things - only one of which is the equivalent of a readable file descriptor, namely "console input".  It doesn't appear that you can use a HANDLE for a pipe (named or unnamed), and, while Microsoft seem to indicate that you can do regular ReadFile()/WriteFile() I/O on a socket:

	https://msdn.microsoft.com/en-us/library/windows/desktop/ms740522(v=vs.85).aspx

they don't indicate what the connection is between a socket descriptor and a socket handle (they have the same size, 32 bits in Win32 and 64 bits in Win64, but are SOCKET values usable as HANDLEs, or is there a "get a handle for this socket descriptor" call?) - and even if you get a HANDLE it probably works no better with WaitForMultipleEvents() than do pipe HANDLEs.

For named pipes, you can use "overlapped mode" for asynchronous I/O:

	https://msdn.microsoft.com/en-us/library/aa365788(VS.85).aspx

and can create an event handle that's signaled when a read or write completes, and hand *that* to WaitForMultipleObjects().  This appears, from some Web searching, to be the closest thing to waiting for a read to be possible, but it would be done differently - instead of

	select();
	if (pipe is readable) {
		read into buffer;
		process that data if we can;
	}

it'd be more like

	start an asynchronous read into the buffer;
	WaitForMultipleObjects();
	if (event for that pipe was triggered) {
		process the data that was read if we can;
	}

Anonymous pipes are just named pipes with created unique names:

	https://msdn.microsoft.com/en-us/library/aa365141(v=vs.85).aspx

but, as that page says, "Asynchronous (overlapped) read and write operations are not supported by anonymous pipes.".

For sockets, it appears you can do an operation that's similar to select(), but, instead of waiting, returns an event handle:

	https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx

However, those event handles may, or may not, be like regular Windows event handles; they are documented as working with WSAWaitForMultipleEvents() rather than with WaitForMultipleObjects():

	https://msdn.microsoft.com/en-us/library/windows/desktop/ms742219(v=vs.85).aspx

and they also don't indicate whether you can use regular event objects with WSAWaitForMultipleEvents().

Furthermore, GUI applications should probably use MsgWaitForMultipleObjects().  I think that's what's used in the GUI event loops of GTK+ and Qt on Windows.

So doing the equivalent of select()/poll() on Windows appears to be a challenge.

If anybody has more information than what I found, that'd be helpful.