From 92b0b27733f0f22e230a9139657d9b432ebf6ee0 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Tue, 21 Feb 2023 11:50:08 +1300 Subject: [PATCH v5 3/3] Use pipe2() for postmaster pipe, where available. The 2-argument variant of pipe() (expected in the next POSIX revision) saves the need to make a separate fcntl() call later. It's already available on all targeted Unixes except macOS and AIX. Discussion: https://postgr.es/m/CA%2BhUKGKb6FsAdQWcRL35KJsftv%2B9zXqQbzwkfRf1i0J2e57%2BhQ%40mail.gmail.com --- configure | 12 ++++++++++++ configure.ac | 1 + meson.build | 1 + src/backend/postmaster/postmaster.c | 10 ++++++++++ src/backend/utils/init/miscinit.c | 9 ++++++++- src/include/pg_config.h.in | 4 ++++ 6 files changed, 36 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d06f64cdbb..0aff9f5732 100755 --- a/configure +++ b/configure @@ -16231,6 +16231,18 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ACCEPT4 $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "pipe2" "ac_cv_have_decl_pipe2" "#include +" +if test "x$ac_cv_have_decl_pipe2" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PIPE2 $ac_have_decl +_ACEOF + ac_fn_c_check_decl "$LINENO" "preadv" "ac_cv_have_decl_preadv" "#include " if test "x$ac_cv_have_decl_preadv" = xyes; then : diff --git a/configure.ac b/configure.ac index 070a0b33db..d75eb76897 100644 --- a/configure.ac +++ b/configure.ac @@ -1844,6 +1844,7 @@ AC_CHECK_DECLS([strlcat, strlcpy, strnlen]) # We can't use AC_REPLACE_FUNCS to replace these functions, because it # won't handle deployment target restrictions on macOS AC_CHECK_DECLS([accept4], [], [], [#include ]) +AC_CHECK_DECLS([pipe2], [], [], [#include ]) AC_CHECK_DECLS([preadv], [], [AC_LIBOBJ(preadv)], [#include ]) AC_CHECK_DECLS([pwritev], [], [AC_LIBOBJ(pwritev)], [#include ]) diff --git a/meson.build b/meson.build index c91fb05133..ad2faefff4 100644 --- a/meson.build +++ b/meson.build @@ -2098,6 +2098,7 @@ decl_checks = [ # restrictions on macOS decl_checks += [ ['accept4', 'sys/socket.h'], + ['pipe2', 'unistd.h'], ['preadv', 'sys/uio.h'], ['pwritev', 'sys/uio.h'], ] diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 2552327d90..fdcfdfd558 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -6506,12 +6506,22 @@ InitPostmasterDeathWatchHandle(void) * close the write end as soon as possible after forking, because EOF * won't be signaled in the read end until all processes have closed the * write fd. That is taken care of in ClosePostmasterPorts(). + * + * If this platform has pipe2(), and we're not in an EXEC_BACKEND build, + * then we can avoid a later fcntl() call by asking for O_CLOEXEC now. */ Assert(MyProcPid == PostmasterPid); +#if HAVE_DECL_PIPE2 && !defined(EXEC_BACKEND) + if (pipe2(postmaster_alive_fds, O_CLOEXEC) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg_internal("could not create pipe to monitor postmaster death: %m"))); +#else if (pipe(postmaster_alive_fds) < 0) ereport(FATAL, (errcode_for_file_access(), errmsg_internal("could not create pipe to monitor postmaster death: %m"))); +#endif /* Notify fd.c that we've eaten two FDs for the pipe. */ ReserveExternalFD(); diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 7eb7fe87f6..f706b73e91 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -164,13 +164,20 @@ InitPostmasterChild(void) /* Request a signal if the postmaster dies, if possible. */ PostmasterDeathSignalInit(); - /* Don't give the pipe to subprograms that we execute. */ + /* + * Don't give the pipe to subprograms that we execute. We only need to + * do this explicitly here if the platform lacks pipe2(), or we're in an + * EXEC_BACKEND build so the pipe had to survive the first level of + * exec*() to get here. + */ #ifndef WIN32 +#if !HAVE_DECL_PIPE2 || defined(EXEC_BACKEND) if (fcntl(postmaster_alive_fds[POSTMASTER_FD_WATCH], F_SETFD, FD_CLOEXEC) < 0) ereport(FATAL, (errcode_for_socket_access(), errmsg_internal("could not set postmaster death monitoring pipe to FD_CLOEXEC mode: %m"))); #endif +#endif } /* diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index e21d0f05f5..5cd5acf98e 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -123,6 +123,10 @@ to 0 if you don't. */ #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN +/* Define to 1 if you have the declaration of `pipe2', and to 0 if you don't. + */ +#undef HAVE_DECL_PIPE2 + /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you don't. */ #undef HAVE_DECL_POSIX_FADVISE -- 2.39.1