From 164adc4d3924d5f0310dba24d4035313ca69245d Mon Sep 17 00:00:00 2001 From: Neil Conway Date: Thu, 10 Mar 2005 07:14:03 +0000 Subject: Refactor fork()-related code. We need to do various housekeeping tasks before we can invoke fork() -- flush stdio buffers, save and restore the profiling timer on Linux with LINUX_PROFILE, and handle BeOS stuff. This patch moves that code into a single function, fork_process(), instead of duplicating it at the various callsites of fork(). This patch doesn't address the EXEC_BACKEND case; there is room for further cleanup there. --- src/backend/postmaster/fork_process.c | 80 +++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/backend/postmaster/fork_process.c (limited to 'src/backend/postmaster/fork_process.c') diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c new file mode 100644 index 00000000000..3098087db44 --- /dev/null +++ b/src/backend/postmaster/fork_process.c @@ -0,0 +1,80 @@ +/* + * fork_process.c + * A simple wrapper on top of fork(). This does not handle the + * EXEC_BACKEND case; it might be extended to do so, but it would be + * considerably more complex. + * + * Copyright (c) 1996-2005, PostgreSQL Global Development Group + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/postmaster/fork_process.c,v 1.1 2005/03/10 07:14:03 neilc Exp $ + */ +#include "postgres.h" +#include "postmaster/fork_process.h" + +#include + +/* + * Wrapper for fork(). Return values are the same as those for fork(): + * -1 if the fork failed, 0 in the child process, and the PID of the + * child in the parent process. + */ +pid_t +fork_process(void) +{ + pid_t result; +#ifdef LINUX_PROFILE + struct itimerval prof_itimer; +#endif + + /* + * Flush stdio channels just before fork, to avoid double-output + * problems. Ideally we'd use fflush(NULL) here, but there are still a + * few non-ANSI stdio libraries out there (like SunOS 4.1.x) that + * coredump if we do. Presently stdout and stderr are the only stdio + * output channels used by the postmaster, so fflush'ing them should + * be sufficient. + */ + fflush(stdout); + fflush(stderr); + +#ifdef LINUX_PROFILE + /* + * Linux's fork() resets the profiling timer in the child process. If + * we want to profile child processes then we need to save and restore + * the timer setting. This is a waste of time if not profiling, + * however, so only do it if commanded by specific -DLINUX_PROFILE + * switch. + */ + getitimer(ITIMER_PROF, &prof_itimer); +#endif + +#ifdef __BEOS__ + /* Specific beos actions before backend startup */ + beos_before_backend_startup(); +#endif + + result = fork(); + if (result == (pid_t) -1) + { + /* fork failed */ +#ifdef __BEOS__ + /* Specific beos backend startup actions */ + beos_backend_startup_failed(); +#endif + } + else if (result == 0) + { + /* fork succeeded, in child */ +#ifdef LINUX_PROFILE + setitimer(ITIMER_PROF, &prof_itimer, NULL); +#endif + +#ifdef __BEOS__ + /* Specific beos backend startup actions */ + beos_backend_startup(); +#endif + } + + return result; +} -- cgit v1.2.3