diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-03-27 18:10:40 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-03-27 18:10:40 +0200 |
commit | 7800a71291690dcc34eb3b7aab18750b5a7ebe2c (patch) | |
tree | ce2832159c7f6486c12faff5191b114339ee8065 /src/bin/pg_dump/dumputils.c | |
parent | 1cea9bbb21e9e90dc7085ce605d9160e7161fa58 (diff) | |
download | postgresql-7800a71291690dcc34eb3b7aab18750b5a7ebe2c.tar.gz postgresql-7800a71291690dcc34eb3b7aab18750b5a7ebe2c.zip |
Move some pg_dump function around.
Move functions used only by pg_dump and pg_restore from dumputils.c to a new
file, pg_backup_utils.c. dumputils.c is linked into psql and some programs
in bin/scripts, so it seems good to keep it slim. The parallel functionality
is moved to parallel.c, as is exit_horribly, because the interesting code in
exit_horribly is parallel-related.
This refactoring gets rid of the on_exit_msg_func function pointer. It was
problematic, because a modern gcc version with -Wmissing-format-attribute
complained if it wasn't marked with PF_PRINTF_ATTRIBUTE, but the ancient gcc
version that Tom Lane's old HP-UX box has didn't accept that attribute on a
function pointer, and gave an error. We still use a similar function pointer
trick for getLocalPQBuffer() function, to use a thread-local version of that
in parallel mode on Windows, but that dodges the problem because it doesn't
take printf-like arguments.
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r-- | src/bin/pg_dump/dumputils.c | 208 |
1 files changed, 14 insertions, 194 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 31e56ef7fb5..9c55147c816 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -25,21 +25,6 @@ extern const ScanKeyword FEScanKeywords[]; extern const int NumFEScanKeywords; -/* Globals exported by this file */ -int quote_all_identifiers = 0; -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; -void (*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap) = vwrite_msg; - #define supports_grant_options(version) ((version) >= 70400) static bool parseAclItem(const char *item, const char *type, @@ -49,68 +34,24 @@ static bool parseAclItem(const char *item, const char *type, static char *copyAclUserName(PQExpBuffer output, char *input); static void AddAcl(PQExpBuffer aclbuf, const char *keyword, const char *subname); -static PQExpBuffer getThreadLocalPQExpBuffer(void); - -#ifdef WIN32 -static void shutdown_parallel_dump_utils(int code, void *unused); -static bool parallel_init_done = false; -static DWORD tls_index; -static DWORD mainThreadId; +static PQExpBuffer defaultGetLocalPQExpBuffer(void); -static void -shutdown_parallel_dump_utils(int code, void *unused) -{ - /* Call the cleanup function only from the main thread */ - if (mainThreadId == GetCurrentThreadId()) - WSACleanup(); -} -#endif - -void -init_parallel_dump_utils(void) -{ -#ifdef WIN32 - if (!parallel_init_done) - { - WSADATA wsaData; - int err; - - tls_index = TlsAlloc(); - mainThreadId = GetCurrentThreadId(); - err = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (err != 0) - { - fprintf(stderr, _("WSAStartup failed: %d\n"), err); - exit_nicely(1); - } - on_exit_nicely(shutdown_parallel_dump_utils, NULL); - parallel_init_done = true; - } -#endif -} +/* Globals exported by this file */ +int quote_all_identifiers = 0; +PQExpBuffer (*getLocalPQExpBuffer) (void) = defaultGetLocalPQExpBuffer; /* - * Non-reentrant but reduces memory leakage. (On Windows the memory leakage - * will be one buffer per thread, which is at least better than one per call). + * Returns a temporary PQExpBuffer, valid until the next call to the function. + * This is used by fmtId and fmtQualifiedId. + * + * Non-reentrant and non-thread-safe but reduces memory leakage. You can + * replace this with a custom version by setting the getLocalPQExpBuffer + * function pointer. */ static PQExpBuffer -getThreadLocalPQExpBuffer(void) +defaultGetLocalPQExpBuffer(void) { - /* - * The Tls code goes awry if we use a static var, so we provide for both - * static and auto, and omit any use of the static var when using Tls. - */ - static PQExpBuffer s_id_return = NULL; - PQExpBuffer id_return; - -#ifdef WIN32 - if (parallel_init_done) - id_return = (PQExpBuffer) TlsGetValue(tls_index); /* 0 when not set */ - else - id_return = s_id_return; -#else - id_return = s_id_return; -#endif + static PQExpBuffer id_return = NULL; if (id_return) /* first time through? */ { @@ -121,15 +62,6 @@ getThreadLocalPQExpBuffer(void) { /* new buffer */ id_return = createPQExpBuffer(); -#ifdef WIN32 - if (parallel_init_done) - TlsSetValue(tls_index, id_return); - else - s_id_return = id_return; -#else - s_id_return = id_return; -#endif - } return id_return; @@ -144,7 +76,7 @@ getThreadLocalPQExpBuffer(void) const char * fmtId(const char *rawid) { - PQExpBuffer id_return = getThreadLocalPQExpBuffer(); + PQExpBuffer id_return = getLocalPQExpBuffer(); const char *cp; bool need_quotes = false; @@ -238,7 +170,7 @@ fmtQualifiedId(int remoteVersion, const char *schema, const char *id) } appendPQExpBuffer(lcl_pqexp, "%s", fmtId(id)); - id_return = getThreadLocalPQExpBuffer(); + id_return = getLocalPQExpBuffer(); appendPQExpBuffer(id_return, "%s", lcl_pqexp->data); destroyPQExpBuffer(lcl_pqexp); @@ -1278,118 +1210,6 @@ emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, } -/* - * Parse a --section=foo command line argument. - * - * Set or update the bitmask in *dumpSections according to arg. - * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and - * pg_restore so they can know if this has even been called. - */ -void -set_dump_section(const char *arg, int *dumpSections) -{ - /* if this is the first call, clear all the bits */ - if (*dumpSections == DUMP_UNSECTIONED) - *dumpSections = 0; - - if (strcmp(arg, "pre-data") == 0) - *dumpSections |= DUMP_PRE_DATA; - else if (strcmp(arg, "data") == 0) - *dumpSections |= DUMP_DATA; - else if (strcmp(arg, "post-data") == 0) - *dumpSections |= DUMP_POST_DATA; - else - { - fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"), - progname, arg); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), - progname); - exit_nicely(1); - } -} - - -/* - * Write a printf-style message to stderr. - * - * The program name is prepended, if "progname" has been set. - * Also, if modulename isn't NULL, that's included too. - * Note that we'll try to translate the modulename and the fmt string. - */ -void -write_msg(const char *modulename, const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - vwrite_msg(modulename, fmt, ap); - va_end(ap); -} - -/* - * As write_msg, but pass a va_list not variable arguments. - */ -void -vwrite_msg(const char *modulename, const char *fmt, va_list ap) -{ - if (progname) - { - if (modulename) - fprintf(stderr, "%s: [%s] ", progname, _(modulename)); - else - fprintf(stderr, "%s: ", progname); - } - vfprintf(stderr, _(fmt), ap); -} - - -/* - * Fail and die, with a message to stderr. Parameters as for write_msg. - */ -void -exit_horribly(const char *modulename, const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - on_exit_msg_func(modulename, fmt, ap); - va_end(ap); - - 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) - exit_horribly(NULL, "out of on_exit_nicely slots\n"); - 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 - * quietly. This needs to be thread-safe. - */ -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) - ExitThread(code); -#endif - - exit(code); -} - void simple_string_list_append(SimpleStringList *list, const char *val) { |