event->fd = fd;
event->events = events;
event->user_data = user_data;
+#ifdef WIN32
+ event->reset = false;
+#endif
if (events == WL_LATCH_SET)
{
DWORD rc;
WaitEvent *cur_event;
+ /* Reset any wait events that need it */
+ for (cur_event = set->events;
+ cur_event < (set->events + set->nevents);
+ cur_event++)
+ {
+ if (cur_event->reset)
+ {
+ WaitEventAdjustWin32(set, cur_event);
+ cur_event->reset = false;
+ }
+ }
+
/*
* Sleep.
*
{
/* data available in socket */
occurred_events->events |= WL_SOCKET_READABLE;
+
+ /*------
+ * WaitForMultipleObjects doesn't guarantee that a read event will
+ * be returned if the latch is set at the same time. Even if it
+ * did, the caller might drop that event expecting it to reoccur
+ * on next call. So, we must force the event to be reset if this
+ * WaitEventSet is used again in order to avoid an indefinite
+ * hang. Refer https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx
+ * for the behavior of socket events.
+ *------
+ */
+ cur_event->reset = true;
}
if ((cur_event->events & WL_SOCKET_WRITEABLE) &&
(resEvents.lNetworkEvents & FD_WRITE))
uint32 events; /* triggered events */
pgsocket fd; /* socket fd associated with event */
void *user_data; /* pointer provided in AddWaitEventToSet */
+#ifdef WIN32
+ bool reset; /* Is reset of the event required? */
+#endif
} WaitEvent;
/* forward declaration to avoid exposing latch.c implementation details */