g_poll does not work on win32 sockets
Submitted by Marcus Brinkmann
Link to original bug (#579061)
Description
Please describe the problem: The w32 implementation of g_poll is incomplete with respects to sockets.
Consider this code:
int sockfd = socket (domain, type, proto);
connect (sockfd, &addr, sizeof addr);
GIOChannel *chan = g_io_channel_win32_new_sock (sockfd);
g_io_channel_set_encoding (chan, NULL, NULL);
g_io_channel_set_buffered (chan, FALSE);
g_io_channel_win32_make_pollfd (chan, G_IO_IN, &pollfd);
g_io_channel_win32_poll (&pollfd, 1, 100);
The call to g_io_channel_win32_make_pollfd translates to:
2163 case G_IO_WIN32_SOCKET:
2164 fd->fd = (gintptr) WSACreateEvent ();
2165 break;
2176 fd->events = condition;
and the call to g_io_channel_win32_poll is a wrapper for g_poll, which just initializes the handles table and calls poll_rest, which just calls WaitForMultipleObjectsEx.
What is missing here is a call to WSAEventSelect to make a connection between the socket and the event object. Because this event needs to be destroyed when it is no longer used, it makes sense to add the event to the channel object as well (and destroy it in the channel's destructor). In fact, we can share the event object with the watch implementation, which is exactly what the attached patch does.
As g_poll on w32 sockets can never have worked before, it is probably unused so far (GPA now uses it). This patch only touches the above code path, so I would guess that this will not break any existing glib users.
Steps to reproduce: 1. 2. 3.
Actual results:
Expected results:
Does this happen every time?
Other information:
Version: 2.20.x