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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches