Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4bad60e

Browse files
committed
Allow latches to wait for socket writability without waiting for readability.
So far WaitLatchOrSocket() required to pass in WL_SOCKET_READABLE asthat solely was used to indicate error conditions, like EOF. Waitingfor WL_SOCKET_WRITEABLE would have meant to busy wait upon socketerrors.Adjust the API to signal errors by returning the socket as readable,writable or both, depending on WL_SOCKET_READABLE/WL_SOCKET_WRITEABLEbeing specified. It would arguably be nicer to return WL_SOCKET_ERRORbut that's not possible on platforms and would probably also result inmore complex callsites.This previously had explicitly been forbidden ine42a21b, asthere was no strong use case at that point. We now are looking intomaking FE/BE communication use latches, so changing this makes sense.There also are some portability concerns because there cases of olderplatforms where select(2) is known to, in violation of POSIX, notreturn a socket as writable after the peer has closed it. So far theplatforms where that's the case provide a working poll(2). If we findone where that's not the case, we'll need to add a workaround for thatplatform.Discussion: 20140927191243.GD5423@alap3.anarazel.deReviewed-By: Heikki Linnakangas, Noah Misch
1 parent3dfce37 commit4bad60e

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

‎src/backend/port/unix_latch.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
200200
* Like WaitLatch, but with an extra socket argument for WL_SOCKET_*
201201
* conditions.
202202
*
203-
* When waiting on a socket,WL_SOCKET_READABLE *must* be included in
204-
*'wakeEvents'; WL_SOCKET_WRITEABLE is optional. The reason for this is
205-
*that EOF and error conditions are reported only via WL_SOCKET_READABLE.
203+
* When waiting on a socket,EOF and error conditions are reported by
204+
*returning the socket as readable/writable or both, depending on
205+
*WL_SOCKET_READABLE/WL_SOCKET_WRITEABLE being specified.
206206
*/
207207
int
208208
WaitLatchOrSocket(volatileLatch*latch,intwakeEvents,pgsocketsock,
@@ -230,8 +230,6 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
230230
wakeEvents &= ~(WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE);
231231

232232
Assert(wakeEvents!=0);/* must have at least one wake event */
233-
/* Cannot specify WL_SOCKET_WRITEABLE without WL_SOCKET_READABLE */
234-
Assert((wakeEvents& (WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE))!=WL_SOCKET_WRITEABLE);
235233

236234
if ((wakeEvents&WL_LATCH_SET)&&latch->owner_pid!=MyProcPid)
237235
elog(ERROR,"cannot wait on a latch owned by another process");
@@ -291,7 +289,16 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
291289
break;
292290
}
293291

294-
/* Must wait ... we use poll(2) if available, otherwise select(2) */
292+
/*
293+
* Must wait ... we use poll(2) if available, otherwise select(2).
294+
*
295+
* On at least older linux kernels select(), in violation of POSIX,
296+
* doesn't reliably return a socket as writable if closed - but we
297+
* rely on that. So far all the known cases of this problem are on
298+
* platforms that also provide a poll() implementation without that
299+
* bug. If we find one where that's not the case, we'll need to add a
300+
* workaround.
301+
*/
295302
#ifdefHAVE_POLL
296303
nfds=0;
297304
if (wakeEvents& (WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE))
@@ -346,16 +353,25 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
346353
{
347354
/* at least one event occurred, so check revents values */
348355
if ((wakeEvents&WL_SOCKET_READABLE)&&
349-
(pfds[0].revents&(POLLIN |POLLHUP |POLLERR |POLLNVAL)))
356+
(pfds[0].revents&POLLIN))
350357
{
351358
/* data available in socket, or EOF/error condition */
352359
result |=WL_SOCKET_READABLE;
353360
}
354361
if ((wakeEvents&WL_SOCKET_WRITEABLE)&&
355362
(pfds[0].revents&POLLOUT))
356363
{
364+
/* socket is writable */
357365
result |=WL_SOCKET_WRITEABLE;
358366
}
367+
if (pfds[0].revents& (POLLHUP |POLLERR |POLLNVAL))
368+
{
369+
/* EOF/error condition */
370+
if (wakeEvents&WL_SOCKET_READABLE)
371+
result |=WL_SOCKET_READABLE;
372+
if (wakeEvents&WL_SOCKET_WRITEABLE)
373+
result |=WL_SOCKET_WRITEABLE;
374+
}
359375

360376
/*
361377
* We expect a POLLHUP when the remote end is closed, but because
@@ -439,6 +455,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
439455
}
440456
if ((wakeEvents&WL_SOCKET_WRITEABLE)&&FD_ISSET(sock,&output_mask))
441457
{
458+
/* socket is writable, or EOF */
442459
result |=WL_SOCKET_WRITEABLE;
443460
}
444461
if ((wakeEvents&WL_POSTMASTER_DEATH)&&

‎src/backend/port/win32_latch.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
117117
wakeEvents &= ~(WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE);
118118

119119
Assert(wakeEvents!=0);/* must have at least one wake event */
120-
/* Cannot specify WL_SOCKET_WRITEABLE without WL_SOCKET_READABLE */
121-
Assert((wakeEvents& (WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE))!=WL_SOCKET_WRITEABLE);
122120

123121
if ((wakeEvents&WL_LATCH_SET)&&latch->owner_pid!=MyProcPid)
124122
elog(ERROR,"cannot wait on a latch owned by another process");
@@ -152,10 +150,10 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
152150
if (wakeEvents& (WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE))
153151
{
154152
/* Need an event object to represent events on the socket */
155-
intflags=0;
153+
intflags=FD_CLOSE;/* always check for errors/EOF */
156154

157155
if (wakeEvents&WL_SOCKET_READABLE)
158-
flags |=(FD_READ |FD_CLOSE);
156+
flags |=FD_READ;
159157
if (wakeEvents&WL_SOCKET_WRITEABLE)
160158
flags |=FD_WRITE;
161159

@@ -232,7 +230,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
232230
elog(ERROR,"failed to enumerate network events: error code %u",
233231
WSAGetLastError());
234232
if ((wakeEvents&WL_SOCKET_READABLE)&&
235-
(resEvents.lNetworkEvents&(FD_READ |FD_CLOSE)))
233+
(resEvents.lNetworkEvents&FD_READ))
236234
{
237235
result |=WL_SOCKET_READABLE;
238236
}
@@ -241,6 +239,13 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
241239
{
242240
result |=WL_SOCKET_WRITEABLE;
243241
}
242+
if (resEvents.lNetworkEvents&FD_CLOSE)
243+
{
244+
if (wakeEvents&WL_SOCKET_READABLE)
245+
result |=WL_SOCKET_READABLE;
246+
if (wakeEvents&WL_SOCKET_WRITEABLE)
247+
result |=WL_SOCKET_WRITEABLE;
248+
}
244249
}
245250
elseif ((wakeEvents&WL_POSTMASTER_DEATH)&&
246251
rc==WAIT_OBJECT_0+pmdeath_eventno)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp