Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e42a21b

Browse files
committed
Assert that WaitLatchOrSocket callers cannot wait only for writability.
Since we have chosen to report socket EOF and error conditions via the WL_SOCKET_READABLE flag bit, it's unsafe to wait only for WL_SOCKET_WRITEABLE; the caller would never be notified of the socket condition, and in some of these implementations WaitLatchOrSocket would busy-wait until something else happens. Add this restriction to the API specification, and add Asserts to check that callers don't try to do that. At some point we might want to consider adjusting the API to relax this restriction, but until we have an actual use case for waiting on a write-only socket, it seems premature to design a solution.
1 parent ff4628f commit e42a21b

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/backend/port/unix_latch.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
172172
/*
173173
* Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
174174
* conditions.
175+
*
176+
* When waiting on a socket, WL_SOCKET_READABLE *must* be included in
177+
* 'wakeEvents'; WL_SOCKET_WRITEABLE is optional. The reason for this is
178+
* that EOF and error conditions are reported only via WL_SOCKET_READABLE.
175179
*/
176180
int
177181
WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
@@ -195,6 +199,8 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
195199
wakeEvents &= ~(WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE);
196200

197201
Assert(wakeEvents != 0); /* must have at least one wake event */
202+
/* Cannot specify WL_SOCKET_WRITEABLE without WL_SOCKET_READABLE */
203+
Assert((wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE)) != WL_SOCKET_WRITEABLE);
198204

199205
if ((wakeEvents & WL_LATCH_SET) && latch->owner_pid != MyProcPid)
200206
elog(ERROR, "cannot wait on a latch owned by another process");
@@ -295,7 +301,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
295301
if ((wakeEvents & WL_SOCKET_READABLE) &&
296302
(pfds[0].revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL)))
297303
{
298-
/* data available in socket */
304+
/* data available in socket, or EOF/error condition */
299305
result |= WL_SOCKET_READABLE;
300306
}
301307
if ((wakeEvents & WL_SOCKET_WRITEABLE) &&
@@ -373,7 +379,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
373379
}
374380
if ((wakeEvents & WL_SOCKET_READABLE) && FD_ISSET(sock, &input_mask))
375381
{
376-
/* data available in socket */
382+
/* data available in socket, or EOF */
377383
result |= WL_SOCKET_READABLE;
378384
}
379385
if ((wakeEvents & WL_SOCKET_WRITEABLE) && FD_ISSET(sock, &output_mask))

src/backend/port/win32_latch.c

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
106106
wakeEvents &= ~(WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE);
107107

108108
Assert(wakeEvents != 0); /* must have at least one wake event */
109+
/* Cannot specify WL_SOCKET_WRITEABLE without WL_SOCKET_READABLE */
110+
Assert((wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE)) != WL_SOCKET_WRITEABLE);
109111

110112
if ((wakeEvents & WL_LATCH_SET) && latch->owner_pid != MyProcPid)
111113
elog(ERROR, "cannot wait on a latch owned by another process");

0 commit comments

Comments
 (0)