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

Commita180776

Browse files
committed
Teach unix_latch.c to use poll() where available.
poll() is preferred over select() on platforms where both are available,because it tends to be a bit faster and it doesn't have an arbitrary limiton the range of FD numbers that can be accessed. The FD range limit doesnot appear to be a risk factor for any 9.1 usages, so this doesn't need tobe back-patched, but we need to have it in place if we keep on expandingthe uses of WaitLatch.
1 parentd82d848 commita180776

File tree

1 file changed

+98
-8
lines changed

1 file changed

+98
-8
lines changed

‎src/backend/port/unix_latch.c

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
* however reliably interrupts the sleep, and causes select() to return
1515
* immediately even if the signal arrives before select() begins.
1616
*
17+
* (Actually, we prefer poll() over select() where available, but the
18+
* same comments apply to it.)
19+
*
1720
* When SetLatch is called from the same process that owns the latch,
1821
* SetLatch writes the byte directly to the pipe. If it's owned by another
1922
* process, SIGUSR1 is sent and the signal handler in the waiting process
@@ -34,6 +37,12 @@
3437
#include<unistd.h>
3538
#include<sys/time.h>
3639
#include<sys/types.h>
40+
#ifdefHAVE_POLL_H
41+
#include<poll.h>
42+
#endif
43+
#ifdefHAVE_SYS_POLL_H
44+
#include<sys/poll.h>
45+
#endif
3746
#ifdefHAVE_SYS_SELECT_H
3847
#include<sys/select.h>
3948
#endif
@@ -175,12 +184,18 @@ int
175184
WaitLatchOrSocket(volatileLatch*latch,intwakeEvents,pgsocketsock,
176185
longtimeout)
177186
{
187+
intresult=0;
188+
intrc;
189+
#ifdefHAVE_POLL
190+
structpollfdpfds[3];
191+
intnfds;
192+
#else
178193
structtimevaltv,
179194
*tvp=NULL;
180195
fd_setinput_mask;
181196
fd_setoutput_mask;
182-
intrc;
183-
intresult=0;
197+
inthifd;
198+
#endif
184199

185200
/* Ignore WL_SOCKET_* events if no valid socket is given */
186201
if (sock==PGINVALID_SOCKET)
@@ -195,21 +210,29 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
195210
if (wakeEvents&WL_TIMEOUT)
196211
{
197212
Assert(timeout >=0);
213+
#ifndefHAVE_POLL
198214
tv.tv_sec=timeout /1000L;
199215
tv.tv_usec= (timeout %1000L)*1000L;
200216
tvp=&tv;
217+
#endif
218+
}
219+
else
220+
{
221+
#ifdefHAVE_POLL
222+
/* make sure poll() agrees there is no timeout */
223+
timeout=-1;
224+
#endif
201225
}
202226

203227
waiting= true;
204228
do
205229
{
206-
inthifd;
207-
208230
/*
209231
* Clear the pipe, then check if the latch is set already. If someone
210-
* sets the latch between this and the select() below, the setter will
211-
* write a byte to the pipe (or signal us and the signal handler will
212-
* do that), and the select() will return immediately.
232+
* sets the latch between this and the poll()/select() below, the
233+
* setter will write a byte to the pipe (or signal us and the signal
234+
* handler will do that), and the poll()/select() will return
235+
* immediately.
213236
*
214237
* Note: we assume that the kernel calls involved in drainSelfPipe()
215238
* and SetLatch() will provide adequate synchronization on machines
@@ -228,7 +251,73 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
228251
break;
229252
}
230253

231-
/* Must wait ... set up the event masks for select() */
254+
/* Must wait ... we use poll(2) if available, otherwise select(2) */
255+
#ifdefHAVE_POLL
256+
nfds=0;
257+
if (wakeEvents& (WL_SOCKET_READABLE |WL_SOCKET_WRITEABLE))
258+
{
259+
/* socket, if used, is always in pfds[0] */
260+
pfds[0].fd=sock;
261+
pfds[0].events=0;
262+
if (wakeEvents&WL_SOCKET_READABLE)
263+
pfds[0].events |=POLLIN;
264+
if (wakeEvents&WL_SOCKET_WRITEABLE)
265+
pfds[0].events |=POLLOUT;
266+
pfds[0].revents=0;
267+
nfds++;
268+
}
269+
270+
pfds[nfds].fd=selfpipe_readfd;
271+
pfds[nfds].events=POLLIN;
272+
pfds[nfds].revents=0;
273+
nfds++;
274+
275+
if (wakeEvents&WL_POSTMASTER_DEATH)
276+
{
277+
/* postmaster fd, if used, is always in pfds[nfds - 1] */
278+
pfds[nfds].fd=postmaster_alive_fds[POSTMASTER_FD_WATCH];
279+
pfds[nfds].events=POLLIN;
280+
pfds[nfds].revents=0;
281+
nfds++;
282+
}
283+
284+
/* Sleep */
285+
rc=poll(pfds,nfds, (int)timeout);
286+
287+
/* Check return code */
288+
if (rc<0)
289+
{
290+
if (errno==EINTR)
291+
continue;
292+
waiting= false;
293+
ereport(ERROR,
294+
(errcode_for_socket_access(),
295+
errmsg("poll() failed: %m")));
296+
}
297+
if (rc==0&& (wakeEvents&WL_TIMEOUT))
298+
{
299+
/* timeout exceeded */
300+
result |=WL_TIMEOUT;
301+
}
302+
if ((wakeEvents&WL_SOCKET_READABLE)&&
303+
(pfds[0].revents&POLLIN))
304+
{
305+
/* data available in socket */
306+
result |=WL_SOCKET_READABLE;
307+
}
308+
if ((wakeEvents&WL_SOCKET_WRITEABLE)&&
309+
(pfds[0].revents&POLLOUT))
310+
{
311+
result |=WL_SOCKET_WRITEABLE;
312+
}
313+
if ((wakeEvents&WL_POSTMASTER_DEATH)&&
314+
(pfds[nfds-1].revents&POLLIN))
315+
{
316+
result |=WL_POSTMASTER_DEATH;
317+
}
318+
319+
#else/* !HAVE_POLL */
320+
232321
FD_ZERO(&input_mask);
233322
FD_ZERO(&output_mask);
234323

@@ -288,6 +377,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
288377
{
289378
result |=WL_POSTMASTER_DEATH;
290379
}
380+
#endif/* HAVE_POLL */
291381
}while (result==0);
292382
waiting= false;
293383

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp