* Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
* conditions.
*
- * When waiting on a socket, EOF and error conditions are reported by
- * returning the socket as readable/writable or both, depending on
- * WL_SOCKET_READABLE/WL_SOCKET_WRITEABLE being specified.
+ * When waiting on a socket, EOF and error conditions always cause the socket
+ * to be reported as readable/writable/connected, so that the caller can deal
+ * with the condition.
*
* NB: These days this is just a wrapper around the WaitEventSet API. When
* using a latch very frequently, consider creating a longer living
AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
NULL, NULL);
- if (wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE))
+ if (wakeEvents & WL_SOCKET_MASK)
{
int ev;
- ev = wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE);
+ ev = wakeEvents & WL_SOCKET_MASK;
AddWaitEventToSet(set, ev, sock, NULL, NULL);
}
{
ret |= event.events & (WL_LATCH_SET |
WL_POSTMASTER_DEATH |
- WL_SOCKET_READABLE |
- WL_SOCKET_WRITEABLE);
+ WL_SOCKET_MASK);
}
FreeWaitEventSet(set);
* Add an event to the set. Possible events are:
* - WL_LATCH_SET: Wait for the latch to be set
* - WL_POSTMASTER_DEATH: Wait for postmaster to die
- * - WL_SOCKET_READABLE: Wait for socket to become readable
- * can be combined in one event with WL_SOCKET_WRITEABLE
- * - WL_SOCKET_WRITEABLE: Wait for socket to become writeable
- * can be combined with WL_SOCKET_READABLE
+ * - WL_SOCKET_READABLE: Wait for socket to become readable,
+ * can be combined in one event with other WL_SOCKET_* events
+ * - WL_SOCKET_WRITEABLE: Wait for socket to become writeable,
+ * can be combined with other WL_SOCKET_* events
+ * - WL_SOCKET_CONNECTED: Wait for socket connection to be established,
+ * can be combined with other WL_SOCKET_* events (on non-Windows
+ * platforms, this is the same as WL_SOCKET_WRITEABLE)
*
* Returns the offset in WaitEventSet->events (starting from 0), which can be
* used to modify previously added wait events using ModifyWaitEvent().
* i.e. it must be a process-local latch initialized with InitLatch, or a
* shared latch associated with the current process by calling OwnLatch.
*
- * In the WL_SOCKET_READABLE/WRITEABLE case, EOF and error conditions are
- * reported by returning the socket as readable/writable or both, depending on
- * WL_SOCKET_READABLE/WRITEABLE being specified.
+ * In the WL_SOCKET_READABLE/WRITEABLE/CONNECTED cases, EOF and error
+ * conditions cause the socket to be reported as readable/writable/connected,
+ * so that the caller can deal with the condition.
*
* The user_data pointer specified here will be set for the events returned
* by WaitEventSetWait(), allowing to easily associate additional data with
}
/* waiting for socket readiness without a socket indicates a bug */
- if (fd == PGINVALID_SOCKET &&
- (events & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE)))
+ if (fd == PGINVALID_SOCKET && (events & WL_SOCKET_MASK))
elog(ERROR, "cannot wait on socket event without a socket");
event = &set->events[set->nevents];
flags |= FD_READ;
if (event->events & WL_SOCKET_WRITEABLE)
flags |= FD_WRITE;
+ if (event->events & WL_SOCKET_CONNECTED)
+ flags |= FD_CONNECT;
if (*handle == WSA_INVALID_EVENT)
{
returned_events++;
}
}
- else if (cur_event->events & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE))
+ else if (cur_event->events & WL_SOCKET_MASK)
{
WSANETWORKEVENTS resEvents;
HANDLE handle = set->handles[cur_event->pos + 1];
/* writeable */
occurred_events->events |= WL_SOCKET_WRITEABLE;
}
+ if ((cur_event->events & WL_SOCKET_CONNECTED) &&
+ (resEvents.lNetworkEvents & FD_CONNECT))
+ {
+ /* connected */
+ occurred_events->events |= WL_SOCKET_CONNECTED;
+ }
if (resEvents.lNetworkEvents & FD_CLOSE)
{
- /* EOF */
- if (cur_event->events & WL_SOCKET_READABLE)
- occurred_events->events |= WL_SOCKET_READABLE;
- if (cur_event->events & WL_SOCKET_WRITEABLE)
- occurred_events->events |= WL_SOCKET_WRITEABLE;
+ /* EOF/error, so signal all caller-requested socket flags */
+ occurred_events->events |= (cur_event->events & WL_SOCKET_MASK);
}
if (occurred_events->events != 0)