summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hagander2008-05-16 18:30:53 +0000
committerMagnus Hagander2008-05-16 18:30:53 +0000
commit597d980796e21d7cb62adb8d2c35a50aadcc6e8e (patch)
tree669eb88b012b038b93c767efce95ae0242261d86
parent38b1d832cb88a80f19ee21a52a3886823317c3f4 (diff)
Implement error checking for pthreads calls in thread-safe mode. They really
should always succeed, but in the likely event of a failure we would previously fall through *without locking* - the new code will exit(1). Printing the error message on stderr will not work for all applications, but it's better than nothing at all - and our API doesn't provide a way to return the error to the caller.
-rw-r--r--src/interfaces/libpq/fe-connect.c15
-rw-r--r--src/interfaces/libpq/fe-secure.c26
-rw-r--r--src/interfaces/libpq/libpq-int.h7
-rw-r--r--src/interfaces/libpq/pthread-win32.c17
4 files changed, 52 insertions, 13 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 375f7084b6..55f9b2ffc7 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3835,14 +3835,23 @@ default_threadlock(int acquire)
while (InterlockedExchange(&mutex_initlock, 1) == 1)
/* loop, another thread own the lock */ ;
if (singlethread_lock == NULL)
- pthread_mutex_init(&singlethread_lock, NULL);
+ {
+ if (pthread_mutex_init(&singlethread_lock, NULL))
+ PGTHREAD_ERROR("failed to initialize mutex");
+ }
InterlockedExchange(&mutex_initlock, 0);
}
#endif
if (acquire)
- pthread_mutex_lock(&singlethread_lock);
+ {
+ if (pthread_mutex_lock(&singlethread_lock))
+ PGTHREAD_ERROR("failed to lock mutex");
+ }
else
- pthread_mutex_unlock(&singlethread_lock);
+ {
+ if (pthread_mutex_unlock(&singlethread_lock))
+ PGTHREAD_ERROR("failed to unlock mutex");
+ }
#endif
}
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 9e6ad64e62..a61dbfb65c 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -796,12 +796,21 @@ static void
pq_lockingcallback(int mode, int n, const char *file, int line)
{
if (mode & CRYPTO_LOCK)
- pthread_mutex_lock(&pq_lockarray[n]);
+ {
+ if (pthread_mutex_lock(&pq_lockarray[n]))
+ PGTHREAD_ERROR("failed to lock mutex");
+ }
else
- pthread_mutex_unlock(&pq_lockarray[n]);
+ {
+ if (pthread_mutex_unlock(&pq_lockarray[n]))
+ PGTHREAD_ERROR("failed to unlock mutex");
+ }
}
#endif /* ENABLE_THREAD_SAFETY */
+/*
+ * Also see similar code in fe-connect.c, default_threadlock()
+ */
static int
init_ssl_system(PGconn *conn)
{
@@ -817,11 +826,15 @@ init_ssl_system(PGconn *conn)
while (InterlockedExchange(&mutex_initlock, 1) == 1)
/* loop, another thread own the lock */ ;
if (init_mutex == NULL)
- pthread_mutex_init(&init_mutex, NULL);
+ {
+ if (pthread_mutex_init(&init_mutex, NULL))
+ return -1;
+ }
InterlockedExchange(&mutex_initlock, 0);
}
#endif
- pthread_mutex_lock(&init_mutex);
+ if (pthread_mutex_lock(&init_mutex))
+ return -1;
if (pq_initssllib && pq_lockarray == NULL)
{
@@ -836,7 +849,10 @@ init_ssl_system(PGconn *conn)
return -1;
}
for (i = 0; i < CRYPTO_num_locks(); i++)
- pthread_mutex_init(&pq_lockarray[i], NULL);
+ {
+ if (pthread_mutex_init(&pq_lockarray[i], NULL))
+ return -1;
+ }
CRYPTO_set_locking_callback(pq_lockingcallback);
}
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index b96ad275cd..38c06d4bb7 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -439,6 +439,13 @@ extern bool pqGetHomeDirectory(char *buf, int bufsize);
#ifdef ENABLE_THREAD_SAFETY
extern pgthreadlock_t pg_g_threadlock;
+#define PGTHREAD_ERROR(msg) \
+ do { \
+ fprintf(stderr, "%s\n", msg); \
+ exit(1); \
+ } while (0)
+
+
#define pglock_thread() pg_g_threadlock(true)
#define pgunlock_thread() pg_g_threadlock(false)
#else
diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c
index 4f7d9c75d8..08629ca957 100644
--- a/src/interfaces/libpq/pthread-win32.c
+++ b/src/interfaces/libpq/pthread-win32.c
@@ -32,20 +32,27 @@ pthread_getspecific(pthread_key_t key)
return NULL;
}
-void
+int
pthread_mutex_init(pthread_mutex_t *mp, void *attr)
{
*mp = CreateMutex(0, 0, 0);
+ if (*mp == NULL)
+ return 1;
+ return 0;
}
-void
+int
pthread_mutex_lock(pthread_mutex_t *mp)
{
- WaitForSingleObject(*mp, INFINITE);
+ if (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0)
+ return 1;
+ return 0;
}
-void
+int
pthread_mutex_unlock(pthread_mutex_t *mp)
{
- ReleaseMutex(*mp);
+ if (!ReleaseMutex(*mp))
+ return 1;
+ return 0;
}