PostgreSQL Source Code: src/include/storage/waiteventset.h File Reference (original) (raw)
Go to the source code of this file.
Macros | |
---|---|
#define | WL_LATCH_SET (1 << 0) |
#define | WL_SOCKET_READABLE (1 << 1) |
#define | WL_SOCKET_WRITEABLE (1 << 2) |
#define | WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */ |
#define | WL_POSTMASTER_DEATH (1 << 4) |
#define | WL_EXIT_ON_PM_DEATH (1 << 5) |
#define | WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE |
#define | WL_SOCKET_CLOSED (1 << 7) |
#define | WL_SOCKET_ACCEPT WL_SOCKET_READABLE |
#define | WL_SOCKET_MASK |
Functions | |
---|---|
void | InitializeWaitEventSupport (void) |
WaitEventSet * | CreateWaitEventSet (ResourceOwner resowner, int nevents) |
void | FreeWaitEventSet (WaitEventSet *set) |
void | FreeWaitEventSetAfterFork (WaitEventSet *set) |
int | AddWaitEventToSet (WaitEventSet *set, uint32 events, pgsocket fd, struct Latch *latch, void *user_data) |
void | ModifyWaitEvent (WaitEventSet *set, int pos, uint32 events, struct Latch *latch) |
int | WaitEventSetWait (WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info) |
int | GetNumRegisteredWaitEvents (WaitEventSet *set) |
bool | WaitEventSetCanReportClosed (void) |
void | WakeupMyProc (void) |
void | WakeupOtherProc (int pid) |
◆ WL_EXIT_ON_PM_DEATH
#define WL_EXIT_ON_PM_DEATH (1 << 5)
◆ WL_LATCH_SET
#define WL_LATCH_SET (1 << 0)
◆ WL_POSTMASTER_DEATH
#define WL_POSTMASTER_DEATH (1 << 4)
◆ WL_SOCKET_ACCEPT
◆ WL_SOCKET_CLOSED
#define WL_SOCKET_CLOSED (1 << 7)
◆ WL_SOCKET_CONNECTED
◆ WL_SOCKET_MASK
Value:
WL_SOCKET_WRITEABLE | \
WL_SOCKET_CONNECTED | \
WL_SOCKET_ACCEPT | \
WL_SOCKET_CLOSED)
#define WL_SOCKET_READABLE
Definition at line 53 of file waiteventset.h.
◆ WL_SOCKET_READABLE
#define WL_SOCKET_READABLE (1 << 1)
◆ WL_SOCKET_WRITEABLE
#define WL_SOCKET_WRITEABLE (1 << 2)
◆ WL_TIMEOUT
◆ WaitEvent
◆ AddWaitEventToSet()
Definition at line 569 of file waiteventset.c.
571{
573
574
576
578 {
581 }
582
583 if (latch)
584 {
586 elog(ERROR, "cannot wait on a latch owned by another process");
588 elog(ERROR, "cannot wait on more than one latch");
590 elog(ERROR, "latch events only support being set");
591 }
592 else
593 {
595 elog(ERROR, "cannot wait on latch without a specified latch");
596 }
597
598
600 elog(ERROR, "cannot wait on socket event without a socket");
601
604 event->fd = fd;
605 event->events = events;
606 event->user_data = user_data;
607#ifdef WIN32
608 event->reset = false;
609#endif
610
612 {
613 set->latch = latch;
615#if defined(WAIT_USE_SELF_PIPE)
617#elif defined(WAIT_USE_SIGNALFD)
618 event->fd = signal_fd;
619#else
621#ifdef WAIT_USE_EPOLL
622 return event->pos;
623#endif
624#endif
625 }
627 {
628#ifndef WIN32
630#endif
631 }
632
633
634#if defined(WAIT_USE_EPOLL)
635 WaitEventAdjustEpoll(set, event, EPOLL_CTL_ADD);
636#elif defined(WAIT_USE_KQUEUE)
637 WaitEventAdjustKqueue(set, event, 0);
638#elif defined(WAIT_USE_POLL)
640#elif defined(WAIT_USE_WIN32)
641 WaitEventAdjustWin32(set, event);
642#endif
643
644 return event->pos;
645}
Assert(PointerIsAligned(start, uint64))
int postmaster_alive_fds[2]
#define POSTMASTER_FD_WATCH
static int fd(const char *x, int i)
bool exit_on_postmaster_death
static int selfpipe_readfd
static void WaitEventAdjustPoll(WaitEventSet *set, WaitEvent *event)
#define WL_EXIT_ON_PM_DEATH
#define WL_POSTMASTER_DEATH
References Assert(), elog, ERROR, WaitEventSet::events, WaitEventSet::exit_on_postmaster_death, fd(), WaitEventSet::latch, WaitEventSet::latch_pos, MyProcPid, WaitEventSet::nevents, WaitEventSet::nevents_space, Latch::owner_pid, PGINVALID_SOCKET, WaitEvent::pos, postmaster_alive_fds, POSTMASTER_FD_WATCH, selfpipe_readfd, WaitEventAdjustPoll(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_SOCKET_MASK.
Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), InitializeLatchWaitSet(), postgresForeignAsyncConfigureWait(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().
◆ CreateWaitEventSet()
Definition at line 363 of file waiteventset.c.
364{
368
369
370
371
372
373
374
377
378#if defined(WAIT_USE_EPOLL)
379 sz += MAXALIGN(sizeof(struct epoll_event) * nevents);
380#elif defined(WAIT_USE_KQUEUE)
381 sz += MAXALIGN(sizeof(struct kevent) * nevents);
382#elif defined(WAIT_USE_POLL)
383 sz += MAXALIGN(sizeof(struct pollfd) * nevents);
384#elif defined(WAIT_USE_WIN32)
385
386 sz += MAXALIGN(sizeof(HANDLE) * (nevents + 1));
387#endif
388
389 if (resowner != NULL)
391
393
396
399
400#if defined(WAIT_USE_EPOLL)
401 set->epoll_ret_events = (struct epoll_event *) data;
402 data += MAXALIGN(sizeof(struct epoll_event) * nevents);
403#elif defined(WAIT_USE_KQUEUE)
404 set->kqueue_ret_events = (struct kevent *) data;
405 data += MAXALIGN(sizeof(struct kevent) * nevents);
406#elif defined(WAIT_USE_POLL)
408 data += MAXALIGN(sizeof(struct pollfd) * nevents);
409#elif defined(WAIT_USE_WIN32)
410 set->handles = (HANDLE) data;
412#endif
413
414 set->latch = NULL;
417
418 if (resowner != NULL)
419 {
421 set->owner = resowner;
422 }
423
424#if defined(WAIT_USE_EPOLL)
426 elog(ERROR, "AcquireExternalFD, for epoll_create1, failed: %m");
427 set->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
428 if (set->epoll_fd < 0)
429 {
431 elog(ERROR, "epoll_create1 failed: %m");
432 }
433#elif defined(WAIT_USE_KQUEUE)
435 elog(ERROR, "AcquireExternalFD, for kqueue, failed: %m");
436 set->kqueue_fd = kqueue();
437 if (set->kqueue_fd < 0)
438 {
440 elog(ERROR, "kqueue failed: %m");
441 }
442 if (fcntl(set->kqueue_fd, F_SETFD, FD_CLOEXEC) == -1)
443 {
444 int save_errno = errno;
445
446 close(set->kqueue_fd);
448 errno = save_errno;
449 elog(ERROR, "fcntl(F_SETFD) failed on kqueue descriptor: %m");
450 }
451 set->report_postmaster_not_running = false;
452#elif defined(WAIT_USE_WIN32)
453
454
455
456
457
458
459
460
461
462
465#endif
466
467 return set;
468}
#define StaticAssertStmt(condition, errmessage)
void ReleaseExternalFD(void)
bool AcquireExternalFD(void)
void * MemoryContextAllocZero(MemoryContext context, Size size)
MemoryContext TopMemoryContext
void ResourceOwnerEnlarge(ResourceOwner owner)
HANDLE pgwin32_signal_event
static void ResourceOwnerRememberWaitEventSet(ResourceOwner owner, WaitEventSet *set)
References AcquireExternalFD(), close, data, elog, ERROR, WaitEventSet::events, WaitEventSet::exit_on_postmaster_death, WaitEventSet::latch, MAXALIGN, MemoryContextAllocZero(), WaitEventSet::nevents_space, WaitEventSet::owner, pgwin32_signal_event, WaitEventSet::pollfds, ReleaseExternalFD(), ResourceOwnerEnlarge(), ResourceOwnerRememberWaitEventSet(), StaticAssertStmt, and TopMemoryContext.
Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), InitializeLatchWaitSet(), pq_init(), SysLoggerMain(), and WaitLatchOrSocket().
◆ FreeWaitEventSet()
Definition at line 480 of file waiteventset.c.
481{
483 {
485 set->owner = NULL;
486 }
487
488#if defined(WAIT_USE_EPOLL)
489 close(set->epoll_fd);
491#elif defined(WAIT_USE_KQUEUE)
492 close(set->kqueue_fd);
494#elif defined(WAIT_USE_WIN32)
497 cur_event++)
498 {
500 {
501
502 }
504 {
505
506 }
507 else
508 {
509
510 WSAEventSelect(cur_event->fd, NULL, 0);
511 WSACloseEvent(set->handles[cur_event->pos + 1]);
512 }
513 }
514#endif
515
517}
void pfree(void *pointer)
static void ResourceOwnerForgetWaitEventSet(ResourceOwner owner, WaitEventSet *set)
References close, WaitEventSet::events, WaitEventSet::nevents, WaitEventSet::owner, pfree(), ReleaseExternalFD(), ResourceOwnerForgetWaitEventSet(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.
Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), ResOwnerReleaseWaitEventSet(), and WaitLatchOrSocket().
◆ FreeWaitEventSetAfterFork()
◆ GetNumRegisteredWaitEvents()
◆ InitializeWaitEventSupport()
void InitializeWaitEventSupport | ( | void | ) |
---|
Definition at line 240 of file waiteventset.c.
241{
242#if defined(WAIT_USE_SELF_PIPE)
243 int pipefd[2];
244
246 {
247
248
249
250
251
252
254 {
255
257
260
263
266 }
267 else
268 {
269
270
271
272
273
274
276 }
277 }
278 else
279 {
280
283 }
284
285
286
287
288
289
290
291
292
293
294 if (pipe(pipefd) < 0)
295 elog(FATAL, "pipe() failed: %m");
296 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1)
297 elog(FATAL, "fcntl(F_SETFL) failed on read-end of self-pipe: %m");
298 if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1)
299 elog(FATAL, "fcntl(F_SETFL) failed on write-end of self-pipe: %m");
300 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)
301 elog(FATAL, "fcntl(F_SETFD) failed on read-end of self-pipe: %m");
302 if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1)
303 elog(FATAL, "fcntl(F_SETFD) failed on write-end of self-pipe: %m");
304
308
309
312
314#endif
315
316#ifdef WAIT_USE_SIGNALFD
317 sigset_t signalfd_mask;
318
320 {
321
322
323
324
325
326 if (signal_fd != -1)
327 {
328
329 (void) close(signal_fd);
330 signal_fd = -1;
332 }
333 }
334
335
337
338
339 sigemptyset(&signalfd_mask);
340 sigaddset(&signalfd_mask, SIGURG);
341 signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC);
342 if (signal_fd < 0)
343 elog(FATAL, "signalfd() failed");
345#endif
346
347#ifdef WAIT_USE_KQUEUE
348
350#endif
351}
void ReserveExternalFD(void)
static void latch_sigurg_handler(SIGNAL_ARGS)
static int selfpipe_owner_pid
static int selfpipe_writefd
References Assert(), close, elog, FATAL, IsUnderPostmaster, latch_sigurg_handler(), MyProcPid, pqsignal, ReleaseExternalFD(), ReserveExternalFD(), selfpipe_owner_pid, selfpipe_readfd, selfpipe_writefd, and UnBlockSig.
Referenced by InitPostmasterChild(), InitStandaloneProcess(), and PostmasterMain().
◆ ModifyWaitEvent()
Definition at line 655 of file waiteventset.c.
656{
658#if defined(WAIT_USE_KQUEUE)
659 int old_events;
660#endif
661
662 Assert(pos < set->nevents);
663
664 event = &set->events[pos];
665#if defined(WAIT_USE_KQUEUE)
666 old_events = event->events;
667#endif
668
669
670
671
672
673
674
675
677 {
679 elog(ERROR, "cannot remove postmaster death event");
681 return;
682 }
683
684
685
686
687
688
689
690 if (events == event->events &&
692 return;
693
695 elog(ERROR, "cannot modify latch event");
696
697
698 event->events = events;
699
701 {
703 elog(ERROR, "cannot wait on a latch owned by another process");
704 set->latch = latch;
705
706
707
708
709
710
711
712
713#if defined(WAIT_USE_WIN32)
714 if (!latch)
715 return;
716#else
717 return;
718#endif
719 }
720
721#if defined(WAIT_USE_EPOLL)
722 WaitEventAdjustEpoll(set, event, EPOLL_CTL_MOD);
723#elif defined(WAIT_USE_KQUEUE)
724 WaitEventAdjustKqueue(set, event, old_events);
725#elif defined(WAIT_USE_POLL)
727#elif defined(WAIT_USE_WIN32)
728 WaitEventAdjustWin32(set, event);
729#endif
730}
References Assert(), elog, ERROR, WaitEventSet::events, WaitEvent::events, WaitEventSet::exit_on_postmaster_death, WaitEventSet::latch, MyProcPid, Latch::owner_pid, WaitEventAdjustPoll(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, and WL_POSTMASTER_DEATH.
Referenced by pq_check_connection(), secure_read(), secure_write(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), WaitLatch(), and WalSndWait().
◆ WaitEventSetCanReportClosed()
bool WaitEventSetCanReportClosed | ( | void | ) |
---|
Definition at line 1867 of file waiteventset.c.
1868{
1869#if (defined(WAIT_USE_POLL) && defined(POLLRDHUP)) || \
1870 defined(WAIT_USE_EPOLL) || \
1871 defined(WAIT_USE_KQUEUE)
1872 return true;
1873#else
1874 return false;
1875#endif
1876}
Referenced by check_client_connection_check_interval().
◆ WaitEventSetWait()
Definition at line 1037 of file waiteventset.c.
1040{
1041 int returned_events = 0;
1044 long cur_timeout = -1;
1045
1046 Assert(nevents > 0);
1047
1048
1049
1050
1051
1052 if (timeout >= 0)
1053 {
1055 Assert(timeout >= 0 && timeout <= INT_MAX);
1056 cur_timeout = timeout;
1057 }
1058 else
1060
1062
1063#ifndef WIN32
1065#else
1066
1068#endif
1069 while (returned_events == 0)
1070 {
1071 int rc;
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1101 {
1102
1105
1106 }
1107
1109 {
1115 occurred_events++;
1116 returned_events++;
1117
1118
1120
1121 if (returned_events == nevents)
1122 break;
1123
1124
1125
1126
1127
1128
1129 cur_timeout = 0;
1130 timeout = 0;
1131 }
1132
1133
1134
1135
1136
1137
1139 occurred_events, nevents - returned_events);
1140
1141 if (set->latch &&
1144
1145 if (rc == -1)
1146 break;
1147 else
1148 returned_events += rc;
1149
1150
1151 if (returned_events == 0 && timeout >= 0)
1152 {
1156 if (cur_timeout <= 0)
1157 break;
1158 }
1159 }
1160#ifndef WIN32
1162#endif
1163
1165
1166 return returned_events;
1167}
#define pg_memory_barrier()
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MILLISEC(t)
#define INSTR_TIME_SET_ZERO(t)
void pgwin32_dispatch_queued_signals(void)
sig_atomic_t maybe_sleeping
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
static int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, WaitEvent *occurred_events, int nevents)
static volatile sig_atomic_t waiting
References Assert(), WaitEventSet::events, WaitEvent::events, WaitEvent::fd, INSTR_TIME_GET_MILLISEC, INSTR_TIME_SET_CURRENT, INSTR_TIME_SET_ZERO, INSTR_TIME_SUBTRACT, Latch::is_set, WaitEventSet::latch, WaitEventSet::latch_pos, Latch::maybe_sleeping, pg_memory_barrier, PGINVALID_SOCKET, pgstat_report_wait_end(), pgstat_report_wait_start(), pgwin32_dispatch_queued_signals(), WaitEvent::pos, start_time, WaitEvent::user_data, WaitEventSetWaitBlock(), waiting, and WL_LATCH_SET.
Referenced by ExecAppendAsyncEventWait(), pq_check_connection(), secure_read(), secure_write(), ServerLoop(), SysLoggerMain(), WaitLatch(), WaitLatchOrSocket(), and WalSndWait().
◆ WakeupMyProc()
void WakeupMyProc | ( | void | ) |
---|
◆ WakeupOtherProc()
void WakeupOtherProc | ( | int | pid | ) |
---|