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

Appearance settings

Commit 3347c98

Browse filesBrowse files
committed
Use a long lived WaitEventSet for WaitLatch().
Create LatchWaitSet at backend startup time, and use it to implement WaitLatch(). This avoids repeated epoll/kqueue setup and teardown system calls. Reorder SubPostmasterMain() slightly so that we restore the postmaster pipe and Windows signal emulation before we reach InitPostmasterChild(), to make this work in EXEC_BACKEND builds. Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGJAC4Oqao%3DqforhNey20J8CiG2R%3DoBPqvfR0vOJrFysGw%40mail.gmail.com
1 parent d6c08e2 commit 3347c98
Copy full SHA for 3347c98

File tree

Expand file treeCollapse file tree

4 files changed

+67
-16
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+67
-16
lines changed

‎src/backend/postmaster/postmaster.c

Copy file name to clipboardExpand all lines: src/backend/postmaster/postmaster.c
+12-12Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4896,9 +4896,6 @@ SubPostmasterMain(int argc, char *argv[])
48964896
IsPostmasterEnvironment = true;
48974897
whereToSendOutput = DestNone;
48984898

4899-
/* Setup as postmaster child */
4900-
InitPostmasterChild();
4901-
49024899
/* Setup essential subsystems (to ensure elog() behaves sanely) */
49034900
InitializeGUCOptions();
49044901

@@ -4913,6 +4910,18 @@ SubPostmasterMain(int argc, char *argv[])
49134910
/* Close the postmaster's sockets (as soon as we know them) */
49144911
ClosePostmasterPorts(strcmp(argv[1], "--forklog") == 0);
49154912

4913+
/*
4914+
* Start our win32 signal implementation. This has to be done after we
4915+
* read the backend variables, because we need to pick up the signal pipe
4916+
* from the parent process.
4917+
*/
4918+
#ifdef WIN32
4919+
pgwin32_signal_initialize();
4920+
#endif
4921+
4922+
/* Setup as postmaster child */
4923+
InitPostmasterChild();
4924+
49164925
/*
49174926
* Set up memory area for GSS information. Mirrors the code in ConnCreate
49184927
* for the non-exec case.
@@ -4956,15 +4965,6 @@ SubPostmasterMain(int argc, char *argv[])
49564965
if (strcmp(argv[1], "--forkavworker") == 0)
49574966
AutovacuumWorkerIAm();
49584967

4959-
/*
4960-
* Start our win32 signal implementation. This has to be done after we
4961-
* read the backend variables, because we need to pick up the signal pipe
4962-
* from the parent process.
4963-
*/
4964-
#ifdef WIN32
4965-
pgwin32_signal_initialize();
4966-
#endif
4967-
49684968
/* In EXEC_BACKEND case we will not have inherited these settings */
49694969
pqinitmask();
49704970
PG_SETMASK(&BlockSig);

‎src/backend/storage/ipc/latch.c

Copy file name to clipboardExpand all lines: src/backend/storage/ipc/latch.c
+52-4Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "storage/latch.h"
5757
#include "storage/pmsignal.h"
5858
#include "storage/shmem.h"
59+
#include "utils/memutils.h"
5960

6061
/*
6162
* Select the fd readiness primitive to use. Normally the "most modern"
@@ -129,6 +130,12 @@ struct WaitEventSet
129130
#endif
130131
};
131132

133+
/* A common WaitEventSet used to implement WatchLatch() */
134+
static WaitEventSet *LatchWaitSet;
135+
136+
/* The position of the latch in LatchWaitSet. */
137+
#define LatchWaitSetLatchPos 0
138+
132139
#ifndef WIN32
133140
/* Are we currently in WaitLatch? The signal handler would like to know. */
134141
static volatile sig_atomic_t waiting = false;
@@ -242,6 +249,24 @@ InitializeLatchSupport(void)
242249
#endif
243250
}
244251

252+
void
253+
InitializeLatchWaitSet(void)
254+
{
255+
int latch_pos PG_USED_FOR_ASSERTS_ONLY;
256+
257+
Assert(LatchWaitSet == NULL);
258+
259+
/* Set up the WaitEventSet used by WaitLatch(). */
260+
LatchWaitSet = CreateWaitEventSet(TopMemoryContext, 2);
261+
latch_pos = AddWaitEventToSet(LatchWaitSet, WL_LATCH_SET, PGINVALID_SOCKET,
262+
MyLatch, NULL);
263+
if (IsUnderPostmaster)
264+
AddWaitEventToSet(LatchWaitSet, WL_EXIT_ON_PM_DEATH,
265+
PGINVALID_SOCKET, NULL, NULL);
266+
267+
Assert(latch_pos == LatchWaitSetLatchPos);
268+
}
269+
245270
/*
246271
* Initialize a process-local latch.
247272
*/
@@ -365,8 +390,31 @@ int
365390
WaitLatch(Latch *latch, int wakeEvents, long timeout,
366391
uint32 wait_event_info)
367392
{
368-
return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout,
369-
wait_event_info);
393+
WaitEvent event;
394+
395+
/* Postmaster-managed callers must handle postmaster death somehow. */
396+
Assert(!IsUnderPostmaster ||
397+
(wakeEvents & WL_EXIT_ON_PM_DEATH) ||
398+
(wakeEvents & WL_POSTMASTER_DEATH));
399+
400+
/*
401+
* Some callers may have a latch other than MyLatch, or no latch at all,
402+
* or want to handle postmaster death differently. It's cheap to assign
403+
* those, so just do it every time.
404+
*/
405+
if (!(wakeEvents & WL_LATCH_SET))
406+
latch = NULL;
407+
ModifyWaitEvent(LatchWaitSet, LatchWaitSetLatchPos, WL_LATCH_SET, latch);
408+
LatchWaitSet->exit_on_postmaster_death =
409+
((wakeEvents & WL_EXIT_ON_PM_DEATH) != 0);
410+
411+
if (WaitEventSetWait(LatchWaitSet,
412+
(wakeEvents & WL_TIMEOUT) ? timeout : -1,
413+
&event, 1,
414+
wait_event_info) == 0)
415+
return WL_TIMEOUT;
416+
else
417+
return event.events;
370418
}
371419

372420
/*
@@ -830,7 +878,8 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
830878

831879
/*
832880
* Change the event mask and, in the WL_LATCH_SET case, the latch associated
833-
* with the WaitEvent.
881+
* with the WaitEvent. The latch may be changed to NULL to disable the latch
882+
* temporarily, and then set back to a latch later.
834883
*
835884
* 'pos' is the id returned by AddWaitEventToSet.
836885
*/
@@ -862,7 +911,6 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
862911
if (event->events & WL_LATCH_SET &&
863912
events != event->events)
864913
{
865-
/* we could allow to disable latch events for a while */
866914
elog(ERROR, "cannot modify latch event");
867915
}
868916

‎src/backend/utils/init/miscinit.c

Copy file name to clipboardExpand all lines: src/backend/utils/init/miscinit.c
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ InitPostmasterChild(void)
120120
InitializeLatchSupport();
121121
MyLatch = &LocalLatchData;
122122
InitLatch(MyLatch);
123+
InitializeLatchWaitSet();
123124

124125
/*
125126
* If possible, make this process a group leader, so that the postmaster
@@ -152,6 +153,7 @@ InitStandaloneProcess(const char *argv0)
152153
InitializeLatchSupport();
153154
MyLatch = &LocalLatchData;
154155
InitLatch(MyLatch);
156+
InitializeLatchWaitSet();
155157

156158
/* Compute paths, no postmaster to inherit from */
157159
if (my_exec_path[0] == '\0')

‎src/include/storage/latch.h

Copy file name to clipboardExpand all lines: src/include/storage/latch.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ extern int WaitLatch(Latch *latch, int wakeEvents, long timeout,
176176
uint32 wait_event_info);
177177
extern int WaitLatchOrSocket(Latch *latch, int wakeEvents,
178178
pgsocket sock, long timeout, uint32 wait_event_info);
179+
extern void InitializeLatchWaitSet(void);
179180

180181
/*
181182
* Unix implementation uses SIGUSR1 for inter-process signaling.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.