14
14
* however reliably interrupts the sleep, and causes select() to return
15
15
* immediately even if the signal arrives before select() begins.
16
16
*
17
+ * (Actually, we prefer poll() over select() where available, but the
18
+ * same comments apply to it.)
19
+ *
17
20
* When SetLatch is called from the same process that owns the latch,
18
21
* SetLatch writes the byte directly to the pipe. If it's owned by another
19
22
* process, SIGUSR1 is sent and the signal handler in the waiting process
34
37
#include <unistd.h>
35
38
#include <sys/time.h>
36
39
#include <sys/types.h>
40
+ #ifdef HAVE_POLL_H
41
+ #include <poll.h>
42
+ #endif
43
+ #ifdef HAVE_SYS_POLL_H
44
+ #include <sys/poll.h>
45
+ #endif
37
46
#ifdef HAVE_SYS_SELECT_H
38
47
#include <sys/select.h>
39
48
#endif
@@ -175,12 +184,18 @@ int
175
184
WaitLatchOrSocket (volatile Latch * latch , int wakeEvents , pgsocket sock ,
176
185
long timeout )
177
186
{
187
+ int result = 0 ;
188
+ int rc ;
189
+ #ifdef HAVE_POLL
190
+ struct pollfd pfds [3 ];
191
+ int nfds ;
192
+ #else
178
193
struct timeval tv ,
179
194
* tvp = NULL ;
180
195
fd_set input_mask ;
181
196
fd_set output_mask ;
182
- int rc ;
183
- int result = 0 ;
197
+ int hifd ;
198
+ #endif
184
199
185
200
/* Ignore WL_SOCKET_* events if no valid socket is given */
186
201
if (sock == PGINVALID_SOCKET )
@@ -195,21 +210,29 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
195
210
if (wakeEvents & WL_TIMEOUT )
196
211
{
197
212
Assert (timeout >= 0 );
213
+ #ifndef HAVE_POLL
198
214
tv .tv_sec = timeout / 1000L ;
199
215
tv .tv_usec = (timeout % 1000L ) * 1000L ;
200
216
tvp = & tv ;
217
+ #endif
218
+ }
219
+ else
220
+ {
221
+ #ifdef HAVE_POLL
222
+ /* make sure poll() agrees there is no timeout */
223
+ timeout = -1 ;
224
+ #endif
201
225
}
202
226
203
227
waiting = true;
204
228
do
205
229
{
206
- int hifd ;
207
-
208
230
/*
209
231
* 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.
213
236
*
214
237
* Note: we assume that the kernel calls involved in drainSelfPipe()
215
238
* and SetLatch() will provide adequate synchronization on machines
@@ -228,7 +251,73 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
228
251
break ;
229
252
}
230
253
231
- /* Must wait ... set up the event masks for select() */
254
+ /* Must wait ... we use poll(2) if available, otherwise select(2) */
255
+ #ifdef HAVE_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
+
232
321
FD_ZERO (& input_mask );
233
322
FD_ZERO (& output_mask );
234
323
@@ -288,6 +377,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
288
377
{
289
378
result |= WL_POSTMASTER_DEATH ;
290
379
}
380
+ #endif /* HAVE_POLL */
291
381
} while (result == 0 );
292
382
waiting = false;
293
383
0 commit comments