Attached patch adds some error checking to the thread locking stuff in libpq. Previously, if thread locking failed for some reason, we would just fall through and do things without locking. This patch makes us abort() instead. It's not the greatest thing probably, but our API doesn't let us pass back return values...
Comments? //Magnus
Index: src/interfaces/libpq/fe-connect.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v retrieving revision 1.357 diff -c -r1.357 fe-connect.c *** src/interfaces/libpq/fe-connect.c 31 Mar 2008 02:43:14 -0000 1.357 --- src/interfaces/libpq/fe-connect.c 7 May 2008 19:17:39 -0000 *************** *** 3835,3848 **** while (InterlockedExchange(&mutex_initlock, 1) == 1) /* loop, another thread own the lock */ ; if (singlethread_lock == NULL) ! pthread_mutex_init(&singlethread_lock, NULL); InterlockedExchange(&mutex_initlock, 0); } #endif if (acquire) ! pthread_mutex_lock(&singlethread_lock); else ! pthread_mutex_unlock(&singlethread_lock); #endif } --- 3835,3867 ---- while (InterlockedExchange(&mutex_initlock, 1) == 1) /* loop, another thread own the lock */ ; if (singlethread_lock == NULL) ! { ! if (pthread_mutex_init(&singlethread_lock, NULL)) ! /* ! * We have no way to pass back error values, but we don't want to ! * proceed without having any locking. abort() seems to be the least ! * evil thing to do here. ! */ ! abort(); ! } InterlockedExchange(&mutex_initlock, 0); } #endif if (acquire) ! { ! if (pthread_mutex_lock(&singlethread_lock)) ! /* ! * We have no way to pass back error values, but we don't want to proceed ! * without having any locking. abort() seems to be the least evil thing ! * to do here. ! */ ! abort(); ! } else ! { ! if (pthread_mutex_unlock(&singlethread_lock)) ! abort(); ! } #endif } Index: src/interfaces/libpq/fe-secure.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v retrieving revision 1.104 diff -c -r1.104 fe-secure.c *** src/interfaces/libpq/fe-secure.c 31 Mar 2008 02:43:14 -0000 1.104 --- src/interfaces/libpq/fe-secure.c 7 May 2008 19:17:39 -0000 *************** *** 796,807 **** pq_lockingcallback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) ! pthread_mutex_lock(&pq_lockarray[n]); else ! pthread_mutex_unlock(&pq_lockarray[n]); } #endif /* ENABLE_THREAD_SAFETY */ static int init_ssl_system(PGconn *conn) { --- 796,816 ---- pq_lockingcallback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) ! { ! if (pthread_mutex_lock(&pq_lockarray[n])) ! abort(); ! } else ! { ! if (pthread_mutex_unlock(&pq_lockarray[n])) ! abort(); ! } } #endif /* ENABLE_THREAD_SAFETY */ + /* + * Also see similar code in fe-connect.c, default_threadlock() + */ static int init_ssl_system(PGconn *conn) { *************** *** 817,827 **** while (InterlockedExchange(&mutex_initlock, 1) == 1) /* loop, another thread own the lock */ ; if (init_mutex == NULL) ! pthread_mutex_init(&init_mutex, NULL); InterlockedExchange(&mutex_initlock, 0); } #endif ! pthread_mutex_lock(&init_mutex); if (pq_initssllib && pq_lockarray == NULL) { --- 826,840 ---- while (InterlockedExchange(&mutex_initlock, 1) == 1) /* loop, another thread own the lock */ ; if (init_mutex == NULL) ! { ! if (pthread_mutex_init(&init_mutex, NULL)) ! return -1; ! } InterlockedExchange(&mutex_initlock, 0); } #endif ! if (pthread_mutex_lock(&init_mutex)) ! return -1; if (pq_initssllib && pq_lockarray == NULL) { *************** *** 836,842 **** return -1; } for (i = 0; i < CRYPTO_num_locks(); i++) ! pthread_mutex_init(&pq_lockarray[i], NULL); CRYPTO_set_locking_callback(pq_lockingcallback); } --- 849,858 ---- return -1; } for (i = 0; i < CRYPTO_num_locks(); i++) ! { ! if (pthread_mutex_init(&pq_lockarray[i], NULL)) ! return -1; ! } CRYPTO_set_locking_callback(pq_lockingcallback); } Index: src/interfaces/libpq/pthread-win32.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/libpq/pthread-win32.c,v retrieving revision 1.15 diff -c -r1.15 pthread-win32.c *** src/interfaces/libpq/pthread-win32.c 1 Jan 2008 19:46:00 -0000 1.15 --- src/interfaces/libpq/pthread-win32.c 7 May 2008 19:17:39 -0000 *************** *** 32,51 **** return NULL; } ! void pthread_mutex_init(pthread_mutex_t *mp, void *attr) { *mp = CreateMutex(0, 0, 0); } ! void pthread_mutex_lock(pthread_mutex_t *mp) { ! WaitForSingleObject(*mp, INFINITE); } ! void pthread_mutex_unlock(pthread_mutex_t *mp) { ! ReleaseMutex(*mp); } --- 32,58 ---- return NULL; } ! int pthread_mutex_init(pthread_mutex_t *mp, void *attr) { *mp = CreateMutex(0, 0, 0); + if (*mp == NULL) + return 1; + return 0; } ! int pthread_mutex_lock(pthread_mutex_t *mp) { ! if (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0) ! return 1; ! return 0; } ! int pthread_mutex_unlock(pthread_mutex_t *mp) { ! if (!ReleaseMutex(*mp)) ! return 1; ! return 0; } Index: src/port/pthread-win32.h =================================================================== RCS file: /cvsroot/pgsql/src/port/pthread-win32.h,v retrieving revision 1.2 diff -c -r1.2 pthread-win32.h *** src/port/pthread-win32.h 18 Apr 2007 08:32:40 -0000 1.2 --- src/port/pthread-win32.h 7 May 2008 19:17:39 -0000 *************** *** 10,19 **** void pthread_setspecific(pthread_key_t, void *); void *pthread_getspecific(pthread_key_t); ! void pthread_mutex_init(pthread_mutex_t *, void *attr); ! void pthread_mutex_lock(pthread_mutex_t *); /* blocking */ ! void pthread_mutex_unlock(pthread_mutex_t *); #endif --- 10,19 ---- void pthread_setspecific(pthread_key_t, void *); void *pthread_getspecific(pthread_key_t); ! int pthread_mutex_init(pthread_mutex_t *, void *attr); ! int pthread_mutex_lock(pthread_mutex_t *); /* blocking */ ! int pthread_mutex_unlock(pthread_mutex_t *); #endif
-- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches