[PATCH] fix libpq mutex initialization for multithreaded win32 libs - Mailing list pgsql-patches
| From | Manfred Spraul |
|---|---|
| Subject | [PATCH] fix libpq mutex initialization for multithreaded win32 libs |
| Date | |
| Msg-id | 40E2F746.3020801@colorfullife.com Whole thread Raw |
| Responses |
Re: [PATCH] fix libpq mutex initialization for multithreaded
|
| List | pgsql-patches |
Hi,
win32 doesn't support a static initializer for mutexes, thus the first
user must initialize the lock. The problem are concurrent "first" users
- the pthread_mutex_t initialization must be synchronized.
The current implementation is broken, the attached patches fixes that:
mutex_initlock is a spinlock. If the pthread_mutex_t mutex is not
initialized, then the spinlock is acquired, if the pthread_mutex_t is
initialized if it's not yet initialized and then the spinlock is dropped.
Again untested due to lack of Visual C++.
--
Manfre
? GNUmakefile
? config.log
? config.status
? src/Makefile.global
? src/include/pg_config.h
? src/include/stamp-h
? src/port/pg_config_paths.h
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.275
diff -c -r1.275 fe-connect.c
*** src/interfaces/libpq/fe-connect.c 19 Jun 2004 04:22:17 -0000 1.275
--- src/interfaces/libpq/fe-connect.c 20 Jun 2004 16:38:38 -0000
***************
*** 3193,3202 ****
#ifndef WIN32
static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
#else
! static pthread_mutex_t singlethread_lock;
! static long mutex_initialized = 0;
! if (!InterlockedExchange(&mutex_initialized, 1L))
! pthread_mutex_init(&singlethread_lock, NULL);
#endif
if (acquire)
pthread_mutex_lock(&singlethread_lock);
--- 3193,3208 ----
#ifndef WIN32
static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
#else
! static pthread_mutex_t singlethread_lock = NULL;
! static long mutex_initlock = 0;
!
! if (singlethread_lock == NULL) {
! 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);
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.42
diff -c -r1.42 fe-secure.c
*** src/interfaces/libpq/fe-secure.c 19 Jun 2004 04:22:17 -0000 1.42
--- src/interfaces/libpq/fe-secure.c 20 Jun 2004 16:38:39 -0000
***************
*** 867,876 ****
#ifndef WIN32
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
#else
! static pthread_mutex_t init_mutex;
! static long mutex_initialized = 0L;
! if (!InterlockedExchange(&mutex_initialized, 1L))
! pthread_mutex_init(&init_mutex, NULL);
#endif
pthread_mutex_lock(&init_mutex);
--- 867,882 ----
#ifndef WIN32
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
#else
! static pthread_mutex_t init_mutex = NULL;
! static long mutex_initlock = 0;
!
! if (init_mutex == NULL) {
! 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);
pgsql-patches by date: