On ons, 2012-01-18 at 21:21 +0200, Peter Eisentraut wrote: > On lör, 2012-01-07 at 16:41 -0500, Tom Lane wrote: > > Peter Eisentraut <pete...@gmx.net> writes: > > > I suggest that we change PostgresMain(), PostmasterMain(), BackendRun(), > > > WalSenderMain(), and WalSndLoop() to return void as well. > > > > I agree this code is not very consistent or useful, but one question: > > what should the callers do if one of these functions *does* return? > > I was thinking of a two-pronged approach: First, add > __attribute__((noreturn)) to the functions. This will cause a suitable > compiler to verify on a source-code level that nothing actually returns > from the function. And second, at the call site, put an abort(); /* > not reached */. Together, this will make the code cleaner and more > consistent, and will also help the compiler out a bit about the control > flow.
Patch for 9.3 attached.
diff --git a/src/backend/main/main.c b/src/backend/main/main.c index c7d48e9..33c5a0a 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -173,7 +173,7 @@ #ifdef EXEC_BACKEND if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0) - exit(SubPostmasterMain(argc, argv)); + SubPostmasterMain(argc, argv); /* does not return */ #endif #ifdef WIN32 @@ -189,14 +189,13 @@ if (argc > 1 && strcmp(argv[1], "--boot") == 0) AuxiliaryProcessMain(argc, argv); /* does not return */ - - if (argc > 1 && strcmp(argv[1], "--describe-config") == 0) - exit(GucInfoMain()); - - if (argc > 1 && strcmp(argv[1], "--single") == 0) - exit(PostgresMain(argc, argv, get_current_username(progname))); - - exit(PostmasterMain(argc, argv)); + else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0) + GucInfoMain(); /* does not return */ + else if (argc > 1 && strcmp(argv[1], "--single") == 0) + PostgresMain(argc, argv, get_current_username(progname)); /* does not return */ + else + PostmasterMain(argc, argv); /* does not return */ + abort(); /* should not get here */ } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index eeea933..0f8af3a 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -343,8 +343,8 @@ static void LogChildExit(int lev, const char *procname, int pid, int exitstatus); static void PostmasterStateMachine(void); static void BackendInitialize(Port *port); -static int BackendRun(Port *port); -static void ExitPostmaster(int status); +static void BackendRun(Port *port) __attribute__((noreturn)); +static void ExitPostmaster(int status) __attribute__((noreturn)); static int ServerLoop(void); static int BackendStartup(Port *port); static int ProcessStartupPacket(Port *port, bool SSLdone); @@ -491,7 +491,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, /* * Postmaster main entry point */ -int +void PostmasterMain(int argc, char *argv[]) { int opt; @@ -1125,7 +1125,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, */ ExitPostmaster(status != STATUS_OK); - return 0; /* not reached */ + abort(); /* not reached */ } @@ -3295,7 +3295,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, BackendInitialize(port); /* And run the backend */ - proc_exit(BackendRun(port)); + BackendRun(port); } #endif /* EXEC_BACKEND */ @@ -3539,7 +3539,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, * Shouldn't return at all. * If PostgresMain() fails, return status. */ -static int +static void BackendRun(Port *port) { char **av; @@ -3610,7 +3610,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, */ MemoryContextSwitchTo(TopMemoryContext); - return (PostgresMain(ac, av, port->user_name)); + PostgresMain(ac, av, port->user_name); } @@ -3960,7 +3960,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, * have been inherited by fork() on Unix. Remaining arguments go to the * subprocess FooMain() routine. */ -int +void SubPostmasterMain(int argc, char *argv[]) { Port port; @@ -4195,7 +4195,7 @@ static bool save_backend_variables(BackendParameters *param, Port *port, proc_exit(0); } - return 1; /* shouldn't get here */ + abort(); /* shouldn't get here */ } #endif /* EXEC_BACKEND */ diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 45a3b2e..a9a8689 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -121,7 +121,7 @@ /* Prototypes for private functions */ static bool HandleReplicationCommand(const char *cmd_string); -static int WalSndLoop(void); +static void WalSndLoop(void) __attribute__((noreturn)); static void InitWalSnd(void); static void WalSndHandshake(void); static void WalSndKill(int code, Datum arg); @@ -136,7 +136,7 @@ /* Main entry point for walsender process */ -int +void WalSenderMain(void) { MemoryContext walsnd_context; @@ -193,7 +193,7 @@ SyncRepInitConfig(); /* Main loop of walsender */ - return WalSndLoop(); + WalSndLoop(); } /* @@ -708,7 +708,7 @@ } /* Main loop of walsender process */ -static int +static void WalSndLoop(void) { char *output_message; @@ -884,7 +884,7 @@ whereToSendOutput = DestNone; proc_exit(0); - return 1; /* keep the compiler quiet */ + abort(); /* keep the compiler quiet */ } /* Initialize a per-walsender data structure for this walsender process */ diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 51b6df5..9a5438f 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3507,7 +3507,7 @@ * for the session. * ---------------------------------------------------------------- */ -int +void PostgresMain(int argc, char *argv[], const char *username) { const char *dbname; @@ -3721,7 +3721,10 @@ /* If this is a WAL sender process, we're done with initialization. */ if (am_walsender) - proc_exit(WalSenderMain()); + { + WalSenderMain(); /* does not return */ + abort(); + } /* * process any libraries that should be preloaded at backend start (this @@ -4199,7 +4202,7 @@ /* can't get here because the above loop never exits */ Assert(false); - return 1; /* keep compiler quiet */ + abort(); /* keep compiler quiet */ } diff --git a/src/backend/utils/misc/help_config.c b/src/backend/utils/misc/help_config.c index 5f772f9..386ec98 100644 --- a/src/backend/utils/misc/help_config.c +++ b/src/backend/utils/misc/help_config.c @@ -43,7 +43,7 @@ static bool displayStruct(mixedStruct *structToDisplay); -int +void GucInfoMain(void) { struct config_generic **guc_vars; @@ -64,7 +64,7 @@ printMixedStruct(var); } - return 0; + exit(0); } diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index e966a73..b31bca9 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -40,7 +40,7 @@ extern Form_pg_attribute attrtypes[MAXATTR]; extern int numattr; -extern void AuxiliaryProcessMain(int argc, char *argv[]); +extern void AuxiliaryProcessMain(int argc, char *argv[]) __attribute__((noreturn)); extern void err_out(void); diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h index f46d4ad..996065c 100644 --- a/src/include/postmaster/bgwriter.h +++ b/src/include/postmaster/bgwriter.h @@ -25,8 +25,8 @@ extern int CheckPointTimeout; extern int CheckPointWarning; extern double CheckPointCompletionTarget; -extern void BackgroundWriterMain(void); -extern void CheckpointerMain(void); +extern void BackgroundWriterMain(void) __attribute__((noreturn)); +extern void CheckpointerMain(void) __attribute__((noreturn)); extern void RequestCheckpoint(int flags); extern void CheckpointWriteDelay(int flags, double progress); diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 683ce3c..72c1423 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -46,7 +46,7 @@ extern int postmaster_alive_fds[2]; extern const char *progname; -extern int PostmasterMain(int argc, char *argv[]); +extern void PostmasterMain(int argc, char *argv[]) __attribute__((noreturn)); extern void ClosePostmasterPorts(bool am_syslogger); extern int MaxLivePostmasterChildren(void); diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h index 3ec6950..54400b5 100644 --- a/src/include/postmaster/startup.h +++ b/src/include/postmaster/startup.h @@ -13,7 +13,7 @@ #define _STARTUP_H extern void HandleStartupProcInterrupts(void); -extern void StartupProcessMain(void); +extern void StartupProcessMain(void) __attribute__((noreturn)); extern void PreRestoreCommand(void); extern void PostRestoreCommand(void); extern bool IsPromoteTriggered(void); diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h index 41c539a..922142a 100644 --- a/src/include/postmaster/walwriter.h +++ b/src/include/postmaster/walwriter.h @@ -15,6 +15,6 @@ /* GUC options */ extern int WalWriterDelay; -extern void WalWriterMain(void); +extern void WalWriterMain(void) __attribute__((noreturn)); #endif /* _WALWRITER_H */ diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index d21ec94..31449d2 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -109,7 +109,7 @@ typedef void (*walrcv_disconnect_type) (void); extern PGDLLIMPORT walrcv_disconnect_type walrcv_disconnect; /* prototypes for functions in walreceiver.c */ -extern void WalReceiverMain(void); +extern void WalReceiverMain(void) __attribute__((noreturn)); /* prototypes for functions in walreceiverfuncs.c */ extern Size WalRcvShmemSize(void); diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h index 128d2db..38b6e8e 100644 --- a/src/include/replication/walsender.h +++ b/src/include/replication/walsender.h @@ -26,7 +26,7 @@ extern volatile sig_atomic_t walsender_ready_to_stop; extern int max_wal_senders; extern int replication_timeout; -extern int WalSenderMain(void); +extern void WalSenderMain(void) __attribute__((noreturn)); extern void WalSndSignals(void); extern Size WalSndShmemSize(void); extern void WalSndShmemInit(void); diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 16025c3..3bc2e58 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -64,7 +64,7 @@ typedef void (*shmem_startup_hook_type) (void); /* ipc.c */ extern bool proc_exit_inprogress; -extern void proc_exit(int code); +extern void proc_exit(int code) __attribute__((noreturn)); extern void shmem_exit(int code); extern void on_proc_exit(pg_on_exit_callback function, Datum arg); extern void on_shmem_exit(pg_on_exit_callback function, Datum arg); diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 964dd19..ccd2b89 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -61,7 +61,7 @@ extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); extern void assign_max_stack_depth(int newval, void *extra); extern void die(SIGNAL_ARGS); -extern void quickdie(SIGNAL_ARGS); +extern void quickdie(SIGNAL_ARGS) __attribute__((noreturn)); extern void StatementCancelHandler(SIGNAL_ARGS); extern void FloatExceptionHandler(SIGNAL_ARGS); extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1 @@ -70,7 +70,7 @@ extern void prepare_for_client_read(void); extern void client_read_ended(void); extern const char *process_postgres_switches(int argc, char *argv[], GucContext ctx); -extern int PostgresMain(int argc, char *argv[], const char *username); +extern void PostgresMain(int argc, char *argv[], const char *username) __attribute__((noreturn)); extern long get_stack_depth_rlimit(void); extern void ResetUsage(void); extern void ShowUsage(const char *title); diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h index b569a4e..62d7e49 100644 --- a/src/include/utils/help_config.h +++ b/src/include/utils/help_config.h @@ -12,6 +12,6 @@ #ifndef HELP_CONFIG_H #define HELP_CONFIG_H 1 -extern int GucInfoMain(void); +extern void GucInfoMain(void) __attribute__((noreturn)); #endif
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers