PostgreSQL Source Code git master
latch.h File Reference
#include <signal.h>
#include "utils/resowner.h"
Include dependency graph for latch.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Latch
 
struct  WaitEvent
 

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
 

Typedefs

typedef struct Latch Latch
 
typedef struct WaitEvent WaitEvent
 
typedef struct WaitEventSet WaitEventSet
 

Functions

void InitializeLatchSupport (void)
 
void InitLatch (Latch *latch)
 
void InitSharedLatch (Latch *latch)
 
void OwnLatch (Latch *latch)
 
void DisownLatch (Latch *latch)
 
void SetLatch (Latch *latch)
 
void ResetLatch (Latch *latch)
 
void ShutdownLatchSupport (void)
 
WaitEventSetCreateWaitEventSet (ResourceOwner resowner, int nevents)
 
void FreeWaitEventSet (WaitEventSet *set)
 
void FreeWaitEventSetAfterFork (WaitEventSet *set)
 
int AddWaitEventToSet (WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
 
void ModifyWaitEvent (WaitEventSet *set, int pos, uint32 events, Latch *latch)
 
int WaitEventSetWait (WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
 
int WaitLatch (Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
 
int WaitLatchOrSocket (Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
 
void InitializeLatchWaitSet (void)
 
int GetNumRegisteredWaitEvents (WaitEventSet *set)
 
bool WaitEventSetCanReportClosed (void)
 

Macro Definition Documentation

◆ WL_EXIT_ON_PM_DEATH

#define WL_EXIT_ON_PM_DEATH   (1 << 5)

Definition at line 132 of file latch.h.

◆ WL_LATCH_SET

#define WL_LATCH_SET   (1 << 0)

Definition at line 127 of file latch.h.

◆ WL_POSTMASTER_DEATH

#define WL_POSTMASTER_DEATH   (1 << 4)

Definition at line 131 of file latch.h.

◆ WL_SOCKET_ACCEPT

#define WL_SOCKET_ACCEPT   WL_SOCKET_READABLE

Definition at line 144 of file latch.h.

◆ WL_SOCKET_CLOSED

#define WL_SOCKET_CLOSED   (1 << 7)

Definition at line 139 of file latch.h.

◆ WL_SOCKET_CONNECTED

#define WL_SOCKET_CONNECTED   WL_SOCKET_WRITEABLE

Definition at line 137 of file latch.h.

◆ WL_SOCKET_MASK

#define WL_SOCKET_MASK
Value:
WL_SOCKET_WRITEABLE | \
WL_SOCKET_CONNECTED | \
WL_SOCKET_ACCEPT | \
WL_SOCKET_CLOSED)
#define WL_SOCKET_READABLE
Definition: latch.h:128

Definition at line 146 of file latch.h.

◆ WL_SOCKET_READABLE

#define WL_SOCKET_READABLE   (1 << 1)

Definition at line 128 of file latch.h.

◆ WL_SOCKET_WRITEABLE

#define WL_SOCKET_WRITEABLE   (1 << 2)

Definition at line 129 of file latch.h.

◆ WL_TIMEOUT

#define WL_TIMEOUT   (1 << 3) /* not for WaitEventSetWait() */

Definition at line 130 of file latch.h.

Typedef Documentation

◆ Latch

typedef struct Latch Latch

◆ WaitEvent

typedef struct WaitEvent WaitEvent

◆ WaitEventSet

typedef struct WaitEventSet WaitEventSet

Definition at line 164 of file latch.h.

Function Documentation

◆ AddWaitEventToSet()

int AddWaitEventToSet ( WaitEventSet set,
uint32  events,
pgsocket  fd,
Latch latch,
void *  user_data 
)

Definition at line 957 of file latch.c.

959{
960 WaitEvent *event;
961
962 /* not enough space */
963 Assert(set->nevents < set->nevents_space);
964
965 if (events == WL_EXIT_ON_PM_DEATH)
966 {
967 events = WL_POSTMASTER_DEATH;
968 set->exit_on_postmaster_death = true;
969 }
970
971 if (latch)
972 {
973 if (latch->owner_pid != MyProcPid)
974 elog(ERROR, "cannot wait on a latch owned by another process");
975 if (set->latch)
976 elog(ERROR, "cannot wait on more than one latch");
977 if ((events & WL_LATCH_SET) != WL_LATCH_SET)
978 elog(ERROR, "latch events only support being set");
979 }
980 else
981 {
982 if (events & WL_LATCH_SET)
983 elog(ERROR, "cannot wait on latch without a specified latch");
984 }
985
986 /* waiting for socket readiness without a socket indicates a bug */
987 if (fd == PGINVALID_SOCKET && (events & WL_SOCKET_MASK))
988 elog(ERROR, "cannot wait on socket event without a socket");
989
990 event = &set->events[set->nevents];
991 event->pos = set->nevents++;
992 event->fd = fd;
993 event->events = events;
994 event->user_data = user_data;
995#ifdef WIN32
996 event->reset = false;
997#endif
998
999 if (events == WL_LATCH_SET)
1000 {
1001 set->latch = latch;
1002 set->latch_pos = event->pos;
1003#if defined(WAIT_USE_SELF_PIPE)
1004 event->fd = selfpipe_readfd;
1005#elif defined(WAIT_USE_SIGNALFD)
1006 event->fd = signal_fd;
1007#else
1008 event->fd = PGINVALID_SOCKET;
1009#ifdef WAIT_USE_EPOLL
1010 return event->pos;
1011#endif
1012#endif
1013 }
1014 else if (events == WL_POSTMASTER_DEATH)
1015 {
1016#ifndef WIN32
1018#endif
1019 }
1020
1021 /* perform wait primitive specific initialization, if needed */
1022#if defined(WAIT_USE_EPOLL)
1023 WaitEventAdjustEpoll(set, event, EPOLL_CTL_ADD);
1024#elif defined(WAIT_USE_KQUEUE)
1025 WaitEventAdjustKqueue(set, event, 0);
1026#elif defined(WAIT_USE_POLL)
1027 WaitEventAdjustPoll(set, event);
1028#elif defined(WAIT_USE_WIN32)
1029 WaitEventAdjustWin32(set, event);
1030#endif
1031
1032 return event->pos;
1033}
#define Assert(condition)
Definition: c.h:815
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
int MyProcPid
Definition: globals.c:46
static int selfpipe_readfd
Definition: latch.c:172
static void WaitEventAdjustPoll(WaitEventSet *set, WaitEvent *event)
Definition: latch.c:1170
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_LATCH_SET
Definition: latch.h:127
#define WL_POSTMASTER_DEATH
Definition: latch.h:131
#define WL_SOCKET_MASK
Definition: latch.h:146
#define PGINVALID_SOCKET
Definition: port.h:31
int postmaster_alive_fds[2]
Definition: postmaster.c:473
#define POSTMASTER_FD_WATCH
Definition: postmaster.h:84
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int owner_pid
Definition: latch.h:117
Latch * latch
Definition: latch.c:121
bool exit_on_postmaster_death
Definition: latch.c:129
int nevents
Definition: latch.c:106
int latch_pos
Definition: latch.c:122
int nevents_space
Definition: latch.c:107
WaitEvent * events
Definition: latch.c:113
int pos
Definition: latch.h:154

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()

WaitEventSet * CreateWaitEventSet ( ResourceOwner  resowner,
int  nevents 
)

Definition at line 751 of file latch.c.

752{
753 WaitEventSet *set;
754 char *data;
755 Size sz = 0;
756
757 /*
758 * Use MAXALIGN size/alignment to guarantee that later uses of memory are
759 * aligned correctly. E.g. epoll_event might need 8 byte alignment on some
760 * platforms, but earlier allocations like WaitEventSet and WaitEvent
761 * might not be sized to guarantee that when purely using sizeof().
762 */
763 sz += MAXALIGN(sizeof(WaitEventSet));
764 sz += MAXALIGN(sizeof(WaitEvent) * nevents);
765
766#if defined(WAIT_USE_EPOLL)
767 sz += MAXALIGN(sizeof(struct epoll_event) * nevents);
768#elif defined(WAIT_USE_KQUEUE)
769 sz += MAXALIGN(sizeof(struct kevent) * nevents);
770#elif defined(WAIT_USE_POLL)
771 sz += MAXALIGN(sizeof(struct pollfd) * nevents);
772#elif defined(WAIT_USE_WIN32)
773 /* need space for the pgwin32_signal_event */
774 sz += MAXALIGN(sizeof(HANDLE) * (nevents + 1));
775#endif
776
777 if (resowner != NULL)
778 ResourceOwnerEnlarge(resowner);
779
781
782 set = (WaitEventSet *) data;
783 data += MAXALIGN(sizeof(WaitEventSet));
784
785 set->events = (WaitEvent *) data;
786 data += MAXALIGN(sizeof(WaitEvent) * nevents);
787
788#if defined(WAIT_USE_EPOLL)
789 set->epoll_ret_events = (struct epoll_event *) data;
790 data += MAXALIGN(sizeof(struct epoll_event) * nevents);
791#elif defined(WAIT_USE_KQUEUE)
792 set->kqueue_ret_events = (struct kevent *) data;
793 data += MAXALIGN(sizeof(struct kevent) * nevents);
794#elif defined(WAIT_USE_POLL)
795 set->pollfds = (struct pollfd *) data;
796 data += MAXALIGN(sizeof(struct pollfd) * nevents);
797#elif defined(WAIT_USE_WIN32)
798 set->handles = (HANDLE) data;
799 data += MAXALIGN(sizeof(HANDLE) * nevents);
800#endif
801
802 set->latch = NULL;
803 set->nevents_space = nevents;
804 set->exit_on_postmaster_death = false;
805
806 if (resowner != NULL)
807 {
809 set->owner = resowner;
810 }
811
812#if defined(WAIT_USE_EPOLL)
813 if (!AcquireExternalFD())
814 elog(ERROR, "AcquireExternalFD, for epoll_create1, failed: %m");
815 set->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
816 if (set->epoll_fd < 0)
817 {
819 elog(ERROR, "epoll_create1 failed: %m");
820 }
821#elif defined(WAIT_USE_KQUEUE)
822 if (!AcquireExternalFD())
823 elog(ERROR, "AcquireExternalFD, for kqueue, failed: %m");
824 set->kqueue_fd = kqueue();
825 if (set->kqueue_fd < 0)
826 {
828 elog(ERROR, "kqueue failed: %m");
829 }
830 if (fcntl(set->kqueue_fd, F_SETFD, FD_CLOEXEC) == -1)
831 {
832 int save_errno = errno;
833
834 close(set->kqueue_fd);
836 errno = save_errno;
837 elog(ERROR, "fcntl(F_SETFD) failed on kqueue descriptor: %m");
838 }
839 set->report_postmaster_not_running = false;
840#elif defined(WAIT_USE_WIN32)
841
842 /*
843 * To handle signals while waiting, we need to add a win32 specific event.
844 * We accounted for the additional event at the top of this routine. See
845 * port/win32/signal.c for more details.
846 *
847 * Note: pgwin32_signal_event should be first to ensure that it will be
848 * reported when multiple events are set. We want to guarantee that
849 * pending signals are serviced.
850 */
851 set->handles[0] = pgwin32_signal_event;
852 StaticAssertStmt(WSA_INVALID_EVENT == NULL, "");
853#endif
854
855 return set;
856}
#define MAXALIGN(LEN)
Definition: c.h:768
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:895
size_t Size
Definition: c.h:562
void ReleaseExternalFD(void)
Definition: fd.c:1238
bool AcquireExternalFD(void)
Definition: fd.c:1185
#define close(a)
Definition: win32.h:12
static void ResourceOwnerRememberWaitEventSet(ResourceOwner owner, WaitEventSet *set)
Definition: latch.c:214
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
MemoryContext TopMemoryContext
Definition: mcxt.c:149
const void * data
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442
HANDLE pgwin32_signal_event
Definition: signal.c:27
ResourceOwner owner
Definition: latch.c:104
struct pollfd * pollfds
Definition: latch.c:142

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().

◆ DisownLatch()

void DisownLatch ( Latch latch)

Definition at line 489 of file latch.c.

490{
491 Assert(latch->is_shared);
492 Assert(latch->owner_pid == MyProcPid);
493
494 latch->owner_pid = 0;
495}
bool is_shared
Definition: latch.h:116

References Assert, Latch::is_shared, MyProcPid, and Latch::owner_pid.

Referenced by AuxiliaryProcKill(), ProcKill(), and ShutdownWalRecovery().

◆ FreeWaitEventSet()

void FreeWaitEventSet ( WaitEventSet set)

Definition at line 868 of file latch.c.

869{
870 if (set->owner)
871 {
873 set->owner = NULL;
874 }
875
876#if defined(WAIT_USE_EPOLL)
877 close(set->epoll_fd);
879#elif defined(WAIT_USE_KQUEUE)
880 close(set->kqueue_fd);
882#elif defined(WAIT_USE_WIN32)
883 for (WaitEvent *cur_event = set->events;
884 cur_event < (set->events + set->nevents);
885 cur_event++)
886 {
887 if (cur_event->events & WL_LATCH_SET)
888 {
889 /* uses the latch's HANDLE */
890 }
891 else if (cur_event->events & WL_POSTMASTER_DEATH)
892 {
893 /* uses PostmasterHandle */
894 }
895 else
896 {
897 /* Clean up the event object we created for the socket */
898 WSAEventSelect(cur_event->fd, NULL, 0);
899 WSACloseEvent(set->handles[cur_event->pos + 1]);
900 }
901 }
902#endif
903
904 pfree(set);
905}
static void ResourceOwnerForgetWaitEventSet(ResourceOwner owner, WaitEventSet *set)
Definition: latch.c:219
void pfree(void *pointer)
Definition: mcxt.c:1521

References close, WaitEventSet::events, WaitEventSet::nevents, WaitEventSet::owner, pfree(), ReleaseExternalFD(), ResourceOwnerForgetWaitEventSet(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by ConfigurePostmasterWaitSet(), ExecAppendAsyncEventWait(), ResOwnerReleaseWaitEventSet(), ShutdownLatchSupport(), and WaitLatchOrSocket().

◆ FreeWaitEventSetAfterFork()

void FreeWaitEventSetAfterFork ( WaitEventSet set)

Definition at line 911 of file latch.c.

912{
913#if defined(WAIT_USE_EPOLL)
914 close(set->epoll_fd);
916#elif defined(WAIT_USE_KQUEUE)
917 /* kqueues are not normally inherited by child processes */
919#endif
920
921 pfree(set);
922}

References close, pfree(), and ReleaseExternalFD().

Referenced by ClosePostmasterPorts().

◆ GetNumRegisteredWaitEvents()

int GetNumRegisteredWaitEvents ( WaitEventSet set)

Definition at line 2263 of file latch.c.

2264{
2265 return set->nevents;
2266}

References WaitEventSet::nevents.

Referenced by ExecAppendAsyncEventWait(), and postgresForeignAsyncConfigureWait().

◆ InitializeLatchSupport()

void InitializeLatchSupport ( void  )

Definition at line 232 of file latch.c.

233{
234#if defined(WAIT_USE_SELF_PIPE)
235 int pipefd[2];
236
238 {
239 /*
240 * We might have inherited connections to a self-pipe created by the
241 * postmaster. It's critical that child processes create their own
242 * self-pipes, of course, and we really want them to close the
243 * inherited FDs for safety's sake.
244 */
245 if (selfpipe_owner_pid != 0)
246 {
247 /* Assert we go through here but once in a child process */
249 /* Release postmaster's pipe FDs; ignore any error */
250 (void) close(selfpipe_readfd);
251 (void) close(selfpipe_writefd);
252 /* Clean up, just for safety's sake; we'll set these below */
255 /* Keep fd.c's accounting straight */
258 }
259 else
260 {
261 /*
262 * Postmaster didn't create a self-pipe ... or else we're in an
263 * EXEC_BACKEND build, in which case it doesn't matter since the
264 * postmaster's pipe FDs were closed by the action of FD_CLOEXEC.
265 * fd.c won't have state to clean up, either.
266 */
267 Assert(selfpipe_readfd == -1);
268 }
269 }
270 else
271 {
272 /* In postmaster or standalone backend, assert we do this but once */
273 Assert(selfpipe_readfd == -1);
275 }
276
277 /*
278 * Set up the self-pipe that allows a signal handler to wake up the
279 * poll()/epoll_wait() in WaitLatch. Make the write-end non-blocking, so
280 * that SetLatch won't block if the event has already been set many times
281 * filling the kernel buffer. Make the read-end non-blocking too, so that
282 * we can easily clear the pipe by reading until EAGAIN or EWOULDBLOCK.
283 * Also, make both FDs close-on-exec, since we surely do not want any
284 * child processes messing with them.
285 */
286 if (pipe(pipefd) < 0)
287 elog(FATAL, "pipe() failed: %m");
288 if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) == -1)
289 elog(FATAL, "fcntl(F_SETFL) failed on read-end of self-pipe: %m");
290 if (fcntl(pipefd[1], F_SETFL, O_NONBLOCK) == -1)
291 elog(FATAL, "fcntl(F_SETFL) failed on write-end of self-pipe: %m");
292 if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) == -1)
293 elog(FATAL, "fcntl(F_SETFD) failed on read-end of self-pipe: %m");
294 if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) == -1)
295 elog(FATAL, "fcntl(F_SETFD) failed on write-end of self-pipe: %m");
296
297 selfpipe_readfd = pipefd[0];
298 selfpipe_writefd = pipefd[1];
300
301 /* Tell fd.c about these two long-lived FDs */
304
306#endif
307
308#ifdef WAIT_USE_SIGNALFD
309 sigset_t signalfd_mask;
310
312 {
313 /*
314 * It would probably be safe to re-use the inherited signalfd since
315 * signalfds only see the current process's pending signals, but it
316 * seems less surprising to close it and create our own.
317 */
318 if (signal_fd != -1)
319 {
320 /* Release postmaster's signal FD; ignore any error */
321 (void) close(signal_fd);
322 signal_fd = -1;
324 }
325 }
326
327 /* Block SIGURG, because we'll receive it through a signalfd. */
328 sigaddset(&UnBlockSig, SIGURG);
329
330 /* Set up the signalfd to receive SIGURG notifications. */
331 sigemptyset(&signalfd_mask);
332 sigaddset(&signalfd_mask, SIGURG);
333 signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC);
334 if (signal_fd < 0)
335 elog(FATAL, "signalfd() failed");
337#endif
338
339#ifdef WAIT_USE_KQUEUE
340 /* Ignore SIGURG, because we'll receive it via kqueue. */
341 pqsignal(SIGURG, SIG_IGN);
342#endif
343}
sigset_t UnBlockSig
Definition: pqsignal.c:22
#define FATAL
Definition: elog.h:41
void ReserveExternalFD(void)
Definition: fd.c:1220
bool IsUnderPostmaster
Definition: globals.c:119
static void latch_sigurg_handler(SIGNAL_ARGS)
Definition: latch.c:2276
static int selfpipe_owner_pid
Definition: latch.c:176
static int selfpipe_writefd
Definition: latch.c:173
#define pqsignal
Definition: port.h:521

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().

◆ InitializeLatchWaitSet()

void InitializeLatchWaitSet ( void  )

Definition at line 346 of file latch.c.

347{
348 int latch_pos PG_USED_FOR_ASSERTS_ONLY;
349
350 Assert(LatchWaitSet == NULL);
351
352 /* Set up the WaitEventSet used by WaitLatch(). */
355 MyLatch, NULL);
358 PGINVALID_SOCKET, NULL, NULL);
359
360 Assert(latch_pos == LatchWaitSetLatchPos);
361}
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:204
struct Latch * MyLatch
Definition: globals.c:62
#define LatchWaitSetLatchPos
Definition: latch.c:158
static WaitEventSet * LatchWaitSet
Definition: latch.c:155
int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, void *user_data)
Definition: latch.c:957
WaitEventSet * CreateWaitEventSet(ResourceOwner resowner, int nevents)
Definition: latch.c:751

References AddWaitEventToSet(), Assert, CreateWaitEventSet(), IsUnderPostmaster, LatchWaitSet, LatchWaitSetLatchPos, MyLatch, PG_USED_FOR_ASSERTS_ONLY, PGINVALID_SOCKET, WL_EXIT_ON_PM_DEATH, and WL_LATCH_SET.

Referenced by InitPostmasterChild(), and InitStandaloneProcess().

◆ InitLatch()

void InitLatch ( Latch latch)

Definition at line 394 of file latch.c.

395{
396 latch->is_set = false;
397 latch->maybe_sleeping = false;
398 latch->owner_pid = MyProcPid;
399 latch->is_shared = false;
400
401#if defined(WAIT_USE_SELF_PIPE)
402 /* Assert InitializeLatchSupport has been called in this process */
404#elif defined(WAIT_USE_SIGNALFD)
405 /* Assert InitializeLatchSupport has been called in this process */
406 Assert(signal_fd >= 0);
407#elif defined(WAIT_USE_WIN32)
408 latch->event = CreateEvent(NULL, TRUE, FALSE, NULL);
409 if (latch->event == NULL)
410 elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
411#endif /* WIN32 */
412}
sig_atomic_t is_set
Definition: latch.h:114
sig_atomic_t maybe_sleeping
Definition: latch.h:115

References Assert, elog, ERROR, Latch::is_set, Latch::is_shared, Latch::maybe_sleeping, MyProcPid, Latch::owner_pid, selfpipe_owner_pid, and selfpipe_readfd.

Referenced by InitProcessLocalLatch().

◆ InitSharedLatch()

void InitSharedLatch ( Latch latch)

Definition at line 430 of file latch.c.

431{
432#ifdef WIN32
433 SECURITY_ATTRIBUTES sa;
434
435 /*
436 * Set up security attributes to specify that the events are inherited.
437 */
438 ZeroMemory(&sa, sizeof(sa));
439 sa.nLength = sizeof(sa);
440 sa.bInheritHandle = TRUE;
441
442 latch->event = CreateEvent(&sa, TRUE, FALSE, NULL);
443 if (latch->event == NULL)
444 elog(ERROR, "CreateEvent failed: error code %lu", GetLastError());
445#endif
446
447 latch->is_set = false;
448 latch->maybe_sleeping = false;
449 latch->owner_pid = 0;
450 latch->is_shared = true;
451}

References elog, ERROR, Latch::is_set, Latch::is_shared, Latch::maybe_sleeping, and Latch::owner_pid.

Referenced by InitProcGlobal(), and XLogRecoveryShmemInit().

◆ ModifyWaitEvent()

void ModifyWaitEvent ( WaitEventSet set,
int  pos,
uint32  events,
Latch latch 
)

Definition at line 1043 of file latch.c.

1044{
1045 WaitEvent *event;
1046#if defined(WAIT_USE_KQUEUE)
1047 int old_events;
1048#endif
1049
1050 Assert(pos < set->nevents);
1051
1052 event = &set->events[pos];
1053#if defined(WAIT_USE_KQUEUE)
1054 old_events = event->events;
1055#endif
1056
1057 /*
1058 * If neither the event mask nor the associated latch changes, return
1059 * early. That's an important optimization for some sockets, where
1060 * ModifyWaitEvent is frequently used to switch from waiting for reads to
1061 * waiting on writes.
1062 */
1063 if (events == event->events &&
1064 (!(event->events & WL_LATCH_SET) || set->latch == latch))
1065 return;
1066
1067 if (event->events & WL_LATCH_SET &&
1068 events != event->events)
1069 {
1070 elog(ERROR, "cannot modify latch event");
1071 }
1072
1073 if (event->events & WL_POSTMASTER_DEATH)
1074 {
1075 elog(ERROR, "cannot modify postmaster death event");
1076 }
1077
1078 /* FIXME: validate event mask */
1079 event->events = events;
1080
1081 if (events == WL_LATCH_SET)
1082 {
1083 if (latch && latch->owner_pid != MyProcPid)
1084 elog(ERROR, "cannot wait on a latch owned by another process");
1085 set->latch = latch;
1086
1087 /*
1088 * On Unix, we don't need to modify the kernel object because the
1089 * underlying pipe (if there is one) is the same for all latches so we
1090 * can return immediately. On Windows, we need to update our array of
1091 * handles, but we leave the old one in place and tolerate spurious
1092 * wakeups if the latch is disabled.
1093 */
1094#if defined(WAIT_USE_WIN32)
1095 if (!latch)
1096 return;
1097#else
1098 return;
1099#endif
1100 }
1101
1102#if defined(WAIT_USE_EPOLL)
1103 WaitEventAdjustEpoll(set, event, EPOLL_CTL_MOD);
1104#elif defined(WAIT_USE_KQUEUE)
1105 WaitEventAdjustKqueue(set, event, old_events);
1106#elif defined(WAIT_USE_POLL)
1107 WaitEventAdjustPoll(set, event);
1108#elif defined(WAIT_USE_WIN32)
1109 WaitEventAdjustWin32(set, event);
1110#endif
1111}
uint32 events
Definition: latch.h:155

References Assert, elog, ERROR, WaitEventSet::events, WaitEvent::events, WaitEventSet::latch, MyProcPid, Latch::owner_pid, WaitEventAdjustPoll(), WL_LATCH_SET, and WL_POSTMASTER_DEATH.

Referenced by pq_check_connection(), secure_read(), secure_write(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), WaitLatch(), and WalSndWait().

◆ OwnLatch()

void OwnLatch ( Latch latch)

Definition at line 463 of file latch.c.

464{
465 int owner_pid;
466
467 /* Sanity checks */
468 Assert(latch->is_shared);
469
470#if defined(WAIT_USE_SELF_PIPE)
471 /* Assert InitializeLatchSupport has been called in this process */
473#elif defined(WAIT_USE_SIGNALFD)
474 /* Assert InitializeLatchSupport has been called in this process */
475 Assert(signal_fd >= 0);
476#endif
477
478 owner_pid = latch->owner_pid;
479 if (owner_pid != 0)
480 elog(PANIC, "latch already owned by PID %d", owner_pid);
481
482 latch->owner_pid = MyProcPid;
483}
#define PANIC
Definition: elog.h:42

References Assert, elog, Latch::is_shared, MyProcPid, Latch::owner_pid, PANIC, selfpipe_owner_pid, and selfpipe_readfd.

Referenced by InitAuxiliaryProcess(), InitProcess(), and InitWalRecovery().

◆ ResetLatch()

void ResetLatch ( Latch latch)

Definition at line 724 of file latch.c.

725{
726 /* Only the owner should reset the latch */
727 Assert(latch->owner_pid == MyProcPid);
728 Assert(latch->maybe_sleeping == false);
729
730 latch->is_set = false;
731
732 /*
733 * Ensure that the write to is_set gets flushed to main memory before we
734 * examine any flag variables. Otherwise a concurrent SetLatch might
735 * falsely conclude that it needn't signal us, even though we have missed
736 * seeing some flag updates that SetLatch was supposed to inform us of.
737 */
739}
#define pg_memory_barrier()
Definition: atomics.h:143

References Assert, Latch::is_set, Latch::maybe_sleeping, MyProcPid, Latch::owner_pid, and pg_memory_barrier.

Referenced by ApplyLauncherMain(), autoprewarm_main(), BackgroundWriterMain(), CheckpointerMain(), CheckpointWriteDelay(), ConditionVariableTimedSleep(), copy_read_data(), do_pg_backup_stop(), gather_readnext(), lazy_truncate_heap(), libpqrcv_connect(), libpqrcv_PQgetResult(), libpqsrv_cancel(), libpqsrv_connect_internal(), libpqsrv_get_result(), LogicalParallelApplyLoop(), logicalrep_worker_stop_internal(), LogicalRepApplyLoop(), mq_putmessage(), pa_send_data(), pa_wait_for_xact_state(), pg_promote(), pg_sleep(), pg_wait_until_termination(), pgarch_MainLoop(), pgfdw_get_cleanup_result(), pq_check_connection(), ProcessPendingWrites(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), secure_read(), secure_write(), ServerLoop(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), ShutDownSlotSync(), summarizer_wait_for_wal(), SyncRepWaitForLSN(), SysLoggerMain(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_slot_activity(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), WalReceiverMain(), WalSndLoop(), WalSndWaitForWal(), WalWriterMain(), and worker_spi_main().

◆ SetLatch()

void SetLatch ( Latch latch)

Definition at line 632 of file latch.c.

633{
634#ifndef WIN32
635 pid_t owner_pid;
636#else
637 HANDLE handle;
638#endif
639
640 /*
641 * The memory barrier has to be placed here to ensure that any flag
642 * variables possibly changed by this process have been flushed to main
643 * memory, before we check/set is_set.
644 */
646
647 /* Quick exit if already set */
648 if (latch->is_set)
649 return;
650
651 latch->is_set = true;
652
654 if (!latch->maybe_sleeping)
655 return;
656
657#ifndef WIN32
658
659 /*
660 * See if anyone's waiting for the latch. It can be the current process if
661 * we're in a signal handler. We use the self-pipe or SIGURG to ourselves
662 * to wake up WaitEventSetWaitBlock() without races in that case. If it's
663 * another process, send a signal.
664 *
665 * Fetch owner_pid only once, in case the latch is concurrently getting
666 * owned or disowned. XXX: This assumes that pid_t is atomic, which isn't
667 * guaranteed to be true! In practice, the effective range of pid_t fits
668 * in a 32 bit integer, and so should be atomic. In the worst case, we
669 * might end up signaling the wrong process. Even then, you're very
670 * unlucky if a process with that bogus pid exists and belongs to
671 * Postgres; and PG database processes should handle excess SIGUSR1
672 * interrupts without a problem anyhow.
673 *
674 * Another sort of race condition that's possible here is for a new
675 * process to own the latch immediately after we look, so we don't signal
676 * it. This is okay so long as all callers of ResetLatch/WaitLatch follow
677 * the standard coding convention of waiting at the bottom of their loops,
678 * not the top, so that they'll correctly process latch-setting events
679 * that happen before they enter the loop.
680 */
681 owner_pid = latch->owner_pid;
682 if (owner_pid == 0)
683 return;
684 else if (owner_pid == MyProcPid)
685 {
686#if defined(WAIT_USE_SELF_PIPE)
687 if (waiting)
689#else
690 if (waiting)
691 kill(MyProcPid, SIGURG);
692#endif
693 }
694 else
695 kill(owner_pid, SIGURG);
696
697#else
698
699 /*
700 * See if anyone's waiting for the latch. It can be the current process if
701 * we're in a signal handler.
702 *
703 * Use a local variable here just in case somebody changes the event field
704 * concurrently (which really should not happen).
705 */
706 handle = latch->event;
707 if (handle)
708 {
709 SetEvent(handle);
710
711 /*
712 * Note that we silently ignore any errors. We might be in a signal
713 * handler or other critical path where it's not safe to call elog().
714 */
715 }
716#endif
717}
static void sendSelfPipeByte(void)
Definition: latch.c:2284
static volatile sig_atomic_t waiting
Definition: latch.c:162
#define kill(pid, sig)
Definition: win32_port.h:493

References Latch::is_set, kill, Latch::maybe_sleeping, MyProcPid, Latch::owner_pid, pg_memory_barrier, sendSelfPipeByte(), and waiting.

Referenced by avl_sigusr2_handler(), CheckDeadLockAlert(), ClientCheckTimeoutHandler(), ConditionVariableBroadcast(), ConditionVariableSignal(), die(), ForwardSyncRequest(), handle_pm_child_exit_signal(), handle_pm_pmsignal_signal(), handle_pm_reload_request_signal(), handle_pm_shutdown_request_signal(), handle_sig_alarm(), HandleCatchupInterrupt(), HandleNotifyInterrupt(), HandleParallelApplyMessageInterrupt(), HandleParallelMessageInterrupt(), IdleInTransactionSessionTimeoutHandler(), IdleSessionTimeoutHandler(), IdleStatsUpdateTimeoutHandler(), logicalrep_worker_wakeup_ptr(), pgarch_waken_stop(), PgArchWakeup(), ProcessClientReadInterrupt(), ProcessClientWriteInterrupt(), ProcessPendingWrites(), ProcSendSignal(), procsignal_sigusr1_handler(), ProcWakeup(), ReqShutdownXLOG(), RequestCheckpoint(), RequestXLogStreaming(), shm_mq_detach_internal(), shm_mq_inc_bytes_read(), shm_mq_send_bytes(), shm_mq_sendv(), shm_mq_set_receiver(), shm_mq_set_sender(), SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), sigUsr1Handler(), StatementCancelHandler(), StrategyGetBuffer(), SwitchBackToLocalLatch(), SwitchToSharedLatch(), SyncRepWakeQueue(), test_shm_mq_main(), TransactionTimeoutHandler(), WakeupRecovery(), WakeupWalSummarizer(), WalRcvForceReply(), WalSndLastCycleHandler(), WalSndWaitForWal(), and XLogSetAsyncXactLSN().

◆ ShutdownLatchSupport()

void ShutdownLatchSupport ( void  )

Definition at line 364 of file latch.c.

365{
366#if defined(WAIT_USE_POLL)
367 pqsignal(SIGURG, SIG_IGN);
368#endif
369
370 if (LatchWaitSet)
371 {
373 LatchWaitSet = NULL;
374 }
375
376#if defined(WAIT_USE_SELF_PIPE)
379 selfpipe_readfd = -1;
380 selfpipe_writefd = -1;
382#endif
383
384#if defined(WAIT_USE_SIGNALFD)
385 close(signal_fd);
386 signal_fd = -1;
387#endif
388}
void FreeWaitEventSet(WaitEventSet *set)
Definition: latch.c:868
#define InvalidPid
Definition: miscadmin.h:32

References close, FreeWaitEventSet(), InvalidPid, LatchWaitSet, pqsignal, selfpipe_owner_pid, selfpipe_readfd, and selfpipe_writefd.

◆ WaitEventSetCanReportClosed()

bool WaitEventSetCanReportClosed ( void  )

Definition at line 2248 of file latch.c.

2249{
2250#if (defined(WAIT_USE_POLL) && defined(POLLRDHUP)) || \
2251 defined(WAIT_USE_EPOLL) || \
2252 defined(WAIT_USE_KQUEUE)
2253 return true;
2254#else
2255 return false;
2256#endif
2257}

Referenced by check_client_connection_check_interval().

◆ WaitEventSetWait()

int WaitEventSetWait ( WaitEventSet set,
long  timeout,
WaitEvent occurred_events,
int  nevents,
uint32  wait_event_info 
)

Definition at line 1418 of file latch.c.

1421{
1422 int returned_events = 0;
1424 instr_time cur_time;
1425 long cur_timeout = -1;
1426
1427 Assert(nevents > 0);
1428
1429 /*
1430 * Initialize timeout if requested. We must record the current time so
1431 * that we can determine the remaining timeout if interrupted.
1432 */
1433 if (timeout >= 0)
1434 {
1436 Assert(timeout >= 0 && timeout <= INT_MAX);
1437 cur_timeout = timeout;
1438 }
1439 else
1441
1442 pgstat_report_wait_start(wait_event_info);
1443
1444#ifndef WIN32
1445 waiting = true;
1446#else
1447 /* Ensure that signals are serviced even if latch is already set */
1449#endif
1450 while (returned_events == 0)
1451 {
1452 int rc;
1453
1454 /*
1455 * Check if the latch is set already first. If so, we either exit
1456 * immediately or ask the kernel for further events available right
1457 * now without waiting, depending on how many events the caller wants.
1458 *
1459 * If someone sets the latch between this and the
1460 * WaitEventSetWaitBlock() below, the setter will write a byte to the
1461 * pipe (or signal us and the signal handler will do that), and the
1462 * readiness routine will return immediately.
1463 *
1464 * On unix, If there's a pending byte in the self pipe, we'll notice
1465 * whenever blocking. Only clearing the pipe in that case avoids
1466 * having to drain it every time WaitLatchOrSocket() is used. Should
1467 * the pipe-buffer fill up we're still ok, because the pipe is in
1468 * nonblocking mode. It's unlikely for that to happen, because the
1469 * self pipe isn't filled unless we're blocking (waiting = true), or
1470 * from inside a signal handler in latch_sigurg_handler().
1471 *
1472 * On windows, we'll also notice if there's a pending event for the
1473 * latch when blocking, but there's no danger of anything filling up,
1474 * as "Setting an event that is already set has no effect.".
1475 *
1476 * Note: we assume that the kernel calls involved in latch management
1477 * will provide adequate synchronization on machines with weak memory
1478 * ordering, so that we cannot miss seeing is_set if a notification
1479 * has already been queued.
1480 */
1481 if (set->latch && !set->latch->is_set)
1482 {
1483 /* about to sleep on a latch */
1484 set->latch->maybe_sleeping = true;
1486 /* and recheck */
1487 }
1488
1489 if (set->latch && set->latch->is_set)
1490 {
1491 occurred_events->fd = PGINVALID_SOCKET;
1492 occurred_events->pos = set->latch_pos;
1493 occurred_events->user_data =
1494 set->events[set->latch_pos].user_data;
1495 occurred_events->events = WL_LATCH_SET;
1496 occurred_events++;
1497 returned_events++;
1498
1499 /* could have been set above */
1500 set->latch->maybe_sleeping = false;
1501
1502 if (returned_events == nevents)
1503 break; /* output buffer full already */
1504
1505 /*
1506 * Even though we already have an event, we'll poll just once with
1507 * zero timeout to see what non-latch events we can fit into the
1508 * output buffer at the same time.
1509 */
1510 cur_timeout = 0;
1511 timeout = 0;
1512 }
1513
1514 /*
1515 * Wait for events using the readiness primitive chosen at the top of
1516 * this file. If -1 is returned, a timeout has occurred, if 0 we have
1517 * to retry, everything >= 1 is the number of returned events.
1518 */
1519 rc = WaitEventSetWaitBlock(set, cur_timeout,
1520 occurred_events, nevents - returned_events);
1521
1522 if (set->latch &&
1523 set->latch->maybe_sleeping)
1524 set->latch->maybe_sleeping = false;
1525
1526 if (rc == -1)
1527 break; /* timeout occurred */
1528 else
1529 returned_events += rc;
1530
1531 /* If we're not done, update cur_timeout for next iteration */
1532 if (returned_events == 0 && timeout >= 0)
1533 {
1534 INSTR_TIME_SET_CURRENT(cur_time);
1536 cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time);
1537 if (cur_timeout <= 0)
1538 break;
1539 }
1540 }
1541#ifndef WIN32
1542 waiting = false;
1543#endif
1544
1546
1547 return returned_events;
1548}
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:181
#define INSTR_TIME_GET_MILLISEC(t)
Definition: instr_time.h:191
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
static int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, WaitEvent *occurred_events, int nevents)
Definition: latch.c:1851
static time_t start_time
Definition: pg_ctl.c:95
void pgwin32_dispatch_queued_signals(void)
Definition: signal.c:120
pgsocket fd
Definition: latch.h:156
void * user_data
Definition: latch.h:157
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101

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().

◆ WaitLatch()

int WaitLatch ( Latch latch,
int  wakeEvents,
long  timeout,
uint32  wait_event_info 
)

Definition at line 517 of file latch.c.

519{
520 WaitEvent event;
521
522 /* Postmaster-managed callers must handle postmaster death somehow. */
524 (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
525 (wakeEvents & WL_POSTMASTER_DEATH));
526
527 /*
528 * Some callers may have a latch other than MyLatch, or no latch at all,
529 * or want to handle postmaster death differently. It's cheap to assign
530 * those, so just do it every time.
531 */
532 if (!(wakeEvents & WL_LATCH_SET))
533 latch = NULL;
536 ((wakeEvents & WL_EXIT_ON_PM_DEATH) != 0);
537
539 (wakeEvents & WL_TIMEOUT) ? timeout : -1,
540 &event, 1,
541 wait_event_info) == 0)
542 return WL_TIMEOUT;
543 else
544 return event.events;
545}
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: latch.c:1043
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:1418
#define WL_TIMEOUT
Definition: latch.h:130

References Assert, WaitEventSet::exit_on_postmaster_death, IsUnderPostmaster, LatchWaitSet, LatchWaitSetLatchPos, ModifyWaitEvent(), WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, and WL_TIMEOUT.

Referenced by ApplyLauncherMain(), autoprewarm_main(), BackgroundWriterMain(), CheckpointerMain(), CheckpointWriteDelay(), ConditionVariableTimedSleep(), do_pg_backup_stop(), gather_readnext(), lazy_truncate_heap(), LogicalParallelApplyLoop(), logicalrep_worker_stop_internal(), mq_putmessage(), pa_send_data(), pa_wait_for_xact_state(), pg_promote(), pg_sleep(), pg_wait_until_termination(), pgarch_MainLoop(), ProcSleep(), ProcWaitForSignal(), recoveryApplyDelay(), RegisterSyncRequest(), shm_mq_receive_bytes(), shm_mq_send_bytes(), shm_mq_wait_internal(), ShutDownSlotSync(), summarizer_wait_for_wal(), SyncRepWaitForLSN(), test_shm_mq_pipelined(), throttle(), wait_for_relation_state_change(), wait_for_slot_activity(), wait_for_worker_state_change(), wait_for_workers_to_become_ready(), WaitForBackgroundWorkerShutdown(), WaitForBackgroundWorkerStartup(), WaitForParallelWorkersToAttach(), WaitForParallelWorkersToFinish(), WaitForReplicationWorkerAttach(), WaitForWALToBecomeAvailable(), WalRcvWaitForStartPosition(), WalSummarizerMain(), WalWriterMain(), and worker_spi_main().

◆ WaitLatchOrSocket()

int WaitLatchOrSocket ( Latch latch,
int  wakeEvents,
pgsocket  sock,
long  timeout,
uint32  wait_event_info 
)

Definition at line 565 of file latch.c.

567{
568 int ret = 0;
569 int rc;
570 WaitEvent event;
572
573 if (wakeEvents & WL_TIMEOUT)
574 Assert(timeout >= 0);
575 else
576 timeout = -1;
577
578 if (wakeEvents & WL_LATCH_SET)
580 latch, NULL);
581
582 /* Postmaster-managed callers must handle postmaster death somehow. */
584 (wakeEvents & WL_EXIT_ON_PM_DEATH) ||
585 (wakeEvents & WL_POSTMASTER_DEATH));
586
587 if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
589 NULL, NULL);
590
591 if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
593 NULL, NULL);
594
595 if (wakeEvents & WL_SOCKET_MASK)
596 {
597 int ev;
598
599 ev = wakeEvents & WL_SOCKET_MASK;
600 AddWaitEventToSet(set, ev, sock, NULL, NULL);
601 }
602
603 rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
604
605 if (rc == 0)
606 ret |= WL_TIMEOUT;
607 else
608 {
609 ret |= event.events & (WL_LATCH_SET |
612 }
613
614 FreeWaitEventSet(set);
615
616 return ret;
617}
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165

References AddWaitEventToSet(), Assert, CreateWaitEventSet(), CurrentResourceOwner, FreeWaitEventSet(), IsUnderPostmaster, PGINVALID_SOCKET, WaitEventSetWait(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_POSTMASTER_DEATH, WL_SOCKET_MASK, and WL_TIMEOUT.

Referenced by be_tls_open_server(), copy_read_data(), libpqrcv_connect(), libpqrcv_PQgetResult(), libpqsrv_cancel(), libpqsrv_connect_internal(), libpqsrv_get_result(), LogicalRepApplyLoop(), pgfdw_get_cleanup_result(), read_or_wait(), secure_open_gssapi(), and WalReceiverMain().