Skip to content

Commit aaddf6b

Browse files
committed
Remove libpq's use of abort(3) to handle mutex failure cases.
Doing an abort() seems all right in development builds, but not in production builds of general-purpose libraries. However, the functions that were doing this lack any way to report a failure back up to their callers. It seems like we can just get away with ignoring failures in production builds, since (a) no such failures have been reported in the dozen years that the code's been like this, and (b) failure to enforce mutual exclusion during fe-auth.c operations would likely not cause any problems anyway in most cases. (The OpenSSL callbacks that use this macro are obsolete, so even less likely to cause interesting problems.) Possibly a better answer would be to break compatibility of the pgthreadlock_t callback API, but in the absence of field problem reports, it doesn't really seem worth the trouble. Discussion: https://postgr.es/m/3131385.1624746109@sss.pgh.pa.us
1 parent 48cb244 commit aaddf6b

File tree

3 files changed

+15
-12
lines changed

3 files changed

+15
-12
lines changed

src/interfaces/libpq/fe-connect.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7254,6 +7254,11 @@ pqGetHomeDirectory(char *buf, int bufsize)
72547254
/*
72557255
* To keep the API consistent, the locking stubs are always provided, even
72567256
* if they are not required.
7257+
*
7258+
* Since we neglected to provide any error-return convention in the
7259+
* pgthreadlock_t API, we can't do much except Assert upon failure of any
7260+
* mutex primitive. Fortunately, such failures appear to be nonexistent in
7261+
* the field.
72577262
*/
72587263

72597264
static void
@@ -7273,20 +7278,20 @@ default_threadlock(int acquire)
72737278
if (singlethread_lock == NULL)
72747279
{
72757280
if (pthread_mutex_init(&singlethread_lock, NULL))
7276-
PGTHREAD_ERROR("failed to initialize mutex");
7281+
Assert(false);
72777282
}
72787283
InterlockedExchange(&mutex_initlock, 0);
72797284
}
72807285
#endif
72817286
if (acquire)
72827287
{
72837288
if (pthread_mutex_lock(&singlethread_lock))
7284-
PGTHREAD_ERROR("failed to lock mutex");
7289+
Assert(false);
72857290
}
72867291
else
72877292
{
72887293
if (pthread_mutex_unlock(&singlethread_lock))
7289-
PGTHREAD_ERROR("failed to unlock mutex");
7294+
Assert(false);
72907295
}
72917296
#endif
72927297
}

src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,15 +611,20 @@ static pthread_mutex_t *pq_lockarray;
611611
static void
612612
pq_lockingcallback(int mode, int n, const char *file, int line)
613613
{
614+
/*
615+
* There's no way to report a mutex-primitive failure, so we just Assert
616+
* in development builds, and ignore any errors otherwise. Fortunately
617+
* this is all obsolete in modern OpenSSL.
618+
*/
614619
if (mode & CRYPTO_LOCK)
615620
{
616621
if (pthread_mutex_lock(&pq_lockarray[n]))
617-
PGTHREAD_ERROR("failed to lock mutex");
622+
Assert(false);
618623
}
619624
else
620625
{
621626
if (pthread_mutex_unlock(&pq_lockarray[n]))
622-
PGTHREAD_ERROR("failed to unlock mutex");
627+
Assert(false);
623628
}
624629
}
625630
#endif /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */

src/interfaces/libpq/libpq-int.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,13 +626,6 @@ extern bool pqGetHomeDirectory(char *buf, int bufsize);
626626
#ifdef ENABLE_THREAD_SAFETY
627627
extern pgthreadlock_t pg_g_threadlock;
628628

629-
#define PGTHREAD_ERROR(msg) \
630-
do { \
631-
fprintf(stderr, "%s\n", msg); \
632-
abort(); \
633-
} while (0)
634-
635-
636629
#define pglock_thread() pg_g_threadlock(true)
637630
#define pgunlock_thread() pg_g_threadlock(false)
638631
#else

0 commit comments

Comments
 (0)