aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/ecpg/ecpglib/misc.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 8b9aefcd9cd..2ae989e3e5d 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -60,7 +60,7 @@ static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-static int simple_debug = 0;
+static volatile int simple_debug = 0;
static FILE *debugstream = NULL;
void
@@ -203,8 +203,12 @@ ECPGtrans(int lineno, const char *connection_name, const char *transaction)
void
ECPGdebug(int n, FILE *dbgs)
{
+ /* Interlock against concurrent executions of ECPGdebug() */
pthread_mutex_lock(&debug_init_mutex);
+ /* Prevent ecpg_log() from printing while we change settings */
+ pthread_mutex_lock(&debug_mutex);
+
if (n > 100)
{
ecpg_internal_regression_mode = true;
@@ -215,6 +219,10 @@ ECPGdebug(int n, FILE *dbgs)
debugstream = dbgs;
+ /* We must release debug_mutex before invoking ecpg_log() ... */
+ pthread_mutex_unlock(&debug_mutex);
+
+ /* ... but keep holding debug_init_mutex to avoid racy printout */
ecpg_log("ECPGdebug: set to %d\n", simple_debug);
pthread_mutex_unlock(&debug_init_mutex);
@@ -229,6 +237,11 @@ ecpg_log(const char *format,...)
int bufsize;
char *fmt;
+ /*
+ * For performance reasons, inspect simple_debug without taking the mutex.
+ * This could be problematic if fetching an int isn't atomic, but we
+ * assume that it is in many other places too.
+ */
if (!simple_debug)
return;
@@ -251,18 +264,22 @@ ecpg_log(const char *format,...)
pthread_mutex_lock(&debug_mutex);
- va_start(ap, format);
- vfprintf(debugstream, fmt, ap);
- va_end(ap);
-
- /* dump out internal sqlca variables */
- if (ecpg_internal_regression_mode && sqlca != NULL)
+ /* Now that we hold the mutex, recheck simple_debug */
+ if (simple_debug)
{
- fprintf(debugstream, "[NO_PID]: sqlca: code: %ld, state: %s\n",
- sqlca->sqlcode, sqlca->sqlstate);
- }
+ va_start(ap, format);
+ vfprintf(debugstream, fmt, ap);
+ va_end(ap);
+
+ /* dump out internal sqlca variables */
+ if (ecpg_internal_regression_mode && sqlca != NULL)
+ {
+ fprintf(debugstream, "[NO_PID]: sqlca: code: %ld, state: %s\n",
+ sqlca->sqlcode, sqlca->sqlstate);
+ }
- fflush(debugstream);
+ fflush(debugstream);
+ }
pthread_mutex_unlock(&debug_mutex);