diff options
author | Neil Conway <neilc@samurai.com> | 2005-03-10 07:14:03 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2005-03-10 07:14:03 +0000 |
commit | 164adc4d3924d5f0310dba24d4035313ca69245d (patch) | |
tree | 4a7dfc4714ac642f31b1a60d31ecdc4ba1d59065 /src/backend/postmaster/fork_process.c | |
parent | e829f822239186df59829afae5cc2769b783630b (diff) | |
download | postgresql-164adc4d3924d5f0310dba24d4035313ca69245d.tar.gz postgresql-164adc4d3924d5f0310dba24d4035313ca69245d.zip |
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.
Diffstat (limited to 'src/backend/postmaster/fork_process.c')
-rw-r--r-- | src/backend/postmaster/fork_process.c | 80 |
1 files changed, 80 insertions, 0 deletions
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 <unistd.h> + +/* + * 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; +} |