From b4a3769891e3669c2b6e5c4b0db757f70fff6d84 Mon Sep 17 00:00:00 2001
From: Mark Dilger <mark.dilger@enterprisedb.com>
Date: Wed, 30 Dec 2020 12:50:41 -0800
Subject: [PATCH v32 1/9] Moving exit_nicely and fatal into fe_utils

In preparation for moving other pg_dump functionality into fe_utils,
moving the functions "on_exit_nicely" and "exit_nicely", and the
macro "fatal" from pg_dump into fe_utils.

Various frontend executables in src/bin, src/bin/scripts, and
contrib/ have logic for logging and exiting under error conditions.
The logging code itself is already under common/, but executables
differ in their calls to exit() vs.  exit_nicely(), with
exit_nicely() not uniformly defined, and sometimes all of this
wrapped up under a macro named fatal(), the definition of that macro
also not uniformly defined.  This makes it harder to move code out
of these executables into a shared library under fe_utils/.
Standardizing all executables to define these things the same way or
to use a single fe_utils/ library is beyond the scope of this patch,
but this patch should get the ball rolling in that direction.
---
 src/bin/pg_dump/pg_backup_archiver.h |  1 +
 src/bin/pg_dump/pg_backup_utils.c    | 59 -----------------------
 src/bin/pg_dump/pg_backup_utils.h    |  8 ----
 src/fe_utils/Makefile                |  1 +
 src/fe_utils/exit_utils.c            | 71 ++++++++++++++++++++++++++++
 src/include/fe_utils/exit_utils.h    | 25 ++++++++++
 6 files changed, 98 insertions(+), 67 deletions(-)
 create mode 100644 src/fe_utils/exit_utils.c
 create mode 100644 src/include/fe_utils/exit_utils.h

diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index a8ea5c7eae..37d157b7ad 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -26,6 +26,7 @@
 
 #include <time.h>
 
+#include "fe_utils/exit_utils.h"
 #include "libpq-fe.h"
 #include "pg_backup.h"
 #include "pqexpbuffer.h"
diff --git a/src/bin/pg_dump/pg_backup_utils.c b/src/bin/pg_dump/pg_backup_utils.c
index c709a40e06..631e88f7db 100644
--- a/src/bin/pg_dump/pg_backup_utils.c
+++ b/src/bin/pg_dump/pg_backup_utils.c
@@ -19,16 +19,6 @@
 /* Globals exported by this file */
 const char *progname = NULL;
 
-#define MAX_ON_EXIT_NICELY				20
-
-static struct
-{
-	on_exit_nicely_callback function;
-	void	   *arg;
-}			on_exit_nicely_list[MAX_ON_EXIT_NICELY];
-
-static int	on_exit_nicely_index;
-
 /*
  * Parse a --section=foo command line argument.
  *
@@ -57,52 +47,3 @@ set_dump_section(const char *arg, int *dumpSections)
 		exit_nicely(1);
 	}
 }
-
-
-/* Register a callback to be run when exit_nicely is invoked. */
-void
-on_exit_nicely(on_exit_nicely_callback function, void *arg)
-{
-	if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
-	{
-		pg_log_fatal("out of on_exit_nicely slots");
-		exit_nicely(1);
-	}
-	on_exit_nicely_list[on_exit_nicely_index].function = function;
-	on_exit_nicely_list[on_exit_nicely_index].arg = arg;
-	on_exit_nicely_index++;
-}
-
-/*
- * Run accumulated on_exit_nicely callbacks in reverse order and then exit
- * without printing any message.
- *
- * If running in a parallel worker thread on Windows, we only exit the thread,
- * not the whole process.
- *
- * Note that in parallel operation on Windows, the callback(s) will be run
- * by each thread since the list state is necessarily shared by all threads;
- * each callback must contain logic to ensure it does only what's appropriate
- * for its thread.  On Unix, callbacks are also run by each process, but only
- * for callbacks established before we fork off the child processes.  (It'd
- * be cleaner to reset the list after fork(), and let each child establish
- * its own callbacks; but then the behavior would be completely inconsistent
- * between Windows and Unix.  For now, just be sure to establish callbacks
- * before forking to avoid inconsistency.)
- */
-void
-exit_nicely(int code)
-{
-	int			i;
-
-	for (i = on_exit_nicely_index - 1; i >= 0; i--)
-		on_exit_nicely_list[i].function(code,
-										on_exit_nicely_list[i].arg);
-
-#ifdef WIN32
-	if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
-		_endthreadex(code);
-#endif
-
-	exit(code);
-}
diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h
index 306798f9ac..ee4409c274 100644
--- a/src/bin/pg_dump/pg_backup_utils.h
+++ b/src/bin/pg_dump/pg_backup_utils.h
@@ -15,22 +15,14 @@
 #ifndef PG_BACKUP_UTILS_H
 #define PG_BACKUP_UTILS_H
 
-#include "common/logging.h"
-
 /* bits returned by set_dump_section */
 #define DUMP_PRE_DATA		0x01
 #define DUMP_DATA			0x02
 #define DUMP_POST_DATA		0x04
 #define DUMP_UNSECTIONED	0xff
 
-typedef void (*on_exit_nicely_callback) (int code, void *arg);
-
 extern const char *progname;
 
 extern void set_dump_section(const char *arg, int *dumpSections);
-extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
-extern void exit_nicely(int code) pg_attribute_noreturn();
-
-#define fatal(...) do { pg_log_error(__VA_ARGS__); exit_nicely(1); } while(0)
 
 #endif							/* PG_BACKUP_UTILS_H */
diff --git a/src/fe_utils/Makefile b/src/fe_utils/Makefile
index 10d6838cf9..d6c328faf1 100644
--- a/src/fe_utils/Makefile
+++ b/src/fe_utils/Makefile
@@ -23,6 +23,7 @@ OBJS = \
 	archive.o \
 	cancel.o \
 	conditional.o \
+	exit_utils.o \
 	mbprint.o \
 	print.o \
 	psqlscan.o \
diff --git a/src/fe_utils/exit_utils.c b/src/fe_utils/exit_utils.c
new file mode 100644
index 0000000000..e61bd438fc
--- /dev/null
+++ b/src/fe_utils/exit_utils.c
@@ -0,0 +1,71 @@
+/*-------------------------------------------------------------------------
+ *
+ * Exiting with cleanup callback facilities for frontend code
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/fe_utils/exit_utils.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "fe_utils/exit_utils.h"
+
+#define MAX_ON_EXIT_NICELY				20
+
+static struct
+{
+	on_exit_nicely_callback function;
+	void	   *arg;
+}			on_exit_nicely_list[MAX_ON_EXIT_NICELY];
+
+static int	on_exit_nicely_index;
+
+/* Register a callback to be run when exit_nicely is invoked. */
+void
+on_exit_nicely(on_exit_nicely_callback function, void *arg)
+{
+	if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
+	{
+		pg_log_fatal("out of on_exit_nicely slots");
+		exit_nicely(1);
+	}
+	on_exit_nicely_list[on_exit_nicely_index].function = function;
+	on_exit_nicely_list[on_exit_nicely_index].arg = arg;
+	on_exit_nicely_index++;
+}
+
+/*
+ * Run accumulated on_exit_nicely callbacks in reverse order and then exit
+ * without printing any message.
+ *
+ * If running in a parallel worker thread on Windows, we only exit the thread,
+ * not the whole process.
+ *
+ * Note that in parallel operation on Windows, the callback(s) will be run
+ * by each thread since the list state is necessarily shared by all threads;
+ * each callback must contain logic to ensure it does only what's appropriate
+ * for its thread.  On Unix, callbacks are also run by each process, but only
+ * for callbacks established before we fork off the child processes.  (It'd
+ * be cleaner to reset the list after fork(), and let each child establish
+ * its own callbacks; but then the behavior would be completely inconsistent
+ * between Windows and Unix.  For now, just be sure to establish callbacks
+ * before forking to avoid inconsistency.)
+ */
+void
+exit_nicely(int code)
+{
+	int			i;
+
+	for (i = on_exit_nicely_index - 1; i >= 0; i--)
+		on_exit_nicely_list[i].function(code,
+										on_exit_nicely_list[i].arg);
+
+#ifdef WIN32
+	if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
+		_endthreadex(code);
+#endif
+
+	exit(code);
+}
diff --git a/src/include/fe_utils/exit_utils.h b/src/include/fe_utils/exit_utils.h
new file mode 100644
index 0000000000..948d2fdb51
--- /dev/null
+++ b/src/include/fe_utils/exit_utils.h
@@ -0,0 +1,25 @@
+/*-------------------------------------------------------------------------
+ *
+ * Exiting with cleanup callback facilities for frontend code
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/fe_utils/exit_utils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef EXIT_UTILS_H
+#define EXIT_UTILS_H
+
+#include "postgres_fe.h"
+#include "common/logging.h"
+
+typedef void (*on_exit_nicely_callback) (int code, void *arg);
+
+extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
+extern void exit_nicely(int code) pg_attribute_noreturn();
+
+#define fatal(...) do { pg_log_error(__VA_ARGS__); exit_nicely(1); } while(0)
+
+#endif							/* EXIT_UTILS_H */
-- 
2.21.1 (Apple Git-122.3)

