Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0028b55

Browse files
committed
Clean up Windows-specific mutex code in libpq and ecpglib.
Fix pthread-win32.h and pthread-win32.c to provide a more completeemulation of POSIX pthread mutexes: define PTHREAD_MUTEX_INITIALIZERand make sure that pthread_mutex_lock() can operate on a mutexobject that's been initialized that way. Then we don't need theduplicative platform-specific logic in default_threadlock() andpgtls_init(), which we'd otherwise need yet a third copy of foran upcoming bug fix.Also, since default_threadlock() supposes that pthread_mutex_lock()cannot fail, try to ensure that that's actually true, by gettingrid of the malloc call that was formerly involved in initializingan emulated mutex. We can define an extra state for the spinlockfield instead.Also, replace the similar code in ecpglib/misc.c with this version.While ecpglib's version at least had a POSIX-compliant API, italso had the potential of failing during mutex init (but here,because of CreateMutex failure rather than malloc failure). Sinceall of misc.c's callers ignore failures, it seems like a wise ideato avoid failures here too.A further improvement in this area could be to unify libpq's andecpglib's implementations into a src/port/pthread-win32.c file.But that doesn't seem like a bug fix, so I'll desist for now.In preparation for the aforementioned bug fix, back-patch to allsupported branches.Discussion:https://postgr.es/m/264860.1707163416@sss.pgh.pa.us
1 parent5c7038d commit0028b55

File tree

6 files changed

+63
-69
lines changed

6 files changed

+63
-69
lines changed

‎src/interfaces/ecpg/ecpglib/misc.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,17 +407,38 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
407407

408408
#ifdefWIN32
409409

410-
void
411-
win32_pthread_mutex(volatilepthread_mutex_t*mutex)
410+
int
411+
pthread_mutex_init(pthread_mutex_t*mp,void*attr)
412+
{
413+
mp->initstate=0;
414+
return0;
415+
}
416+
417+
int
418+
pthread_mutex_lock(pthread_mutex_t*mp)
412419
{
413-
if (mutex->handle==NULL)
420+
/* Initialize the csection if not already done */
421+
if (mp->initstate!=1)
414422
{
415-
while (InterlockedExchange((LONG*)&mutex->initlock,1)==1)
416-
Sleep(0);
417-
if (mutex->handle==NULL)
418-
mutex->handle=CreateMutex(NULL, FALSE,NULL);
419-
InterlockedExchange((LONG*)&mutex->initlock,0);
423+
LONGistate;
424+
425+
while ((istate=InterlockedExchange(&mp->initstate,2))==2)
426+
Sleep(0);/* wait, another thread is doing this */
427+
if (istate!=1)
428+
InitializeCriticalSection(&mp->csection);
429+
InterlockedExchange(&mp->initstate,1);
420430
}
431+
EnterCriticalSection(&mp->csection);
432+
return0;
433+
}
434+
435+
int
436+
pthread_mutex_unlock(pthread_mutex_t*mp)
437+
{
438+
if (mp->initstate!=1)
439+
returnEINVAL;
440+
LeaveCriticalSection(&mp->csection);
441+
return0;
421442
}
422443

423444
staticpthread_mutex_twin32_pthread_once_lock=PTHREAD_MUTEX_INITIALIZER;

‎src/interfaces/ecpg/include/ecpg-pthread-win32.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,22 @@
1212

1313
typedefstructpthread_mutex_t
1414
{
15-
HANDLEhandle;
16-
LONGinitlock;
15+
/* initstate = 0: not initialized; 1: init done; 2: init in progress */
16+
LONGinitstate;
17+
CRITICAL_SECTIONcsection;
1718
}pthread_mutex_t;
1819

1920
typedefDWORDpthread_key_t;
2021
typedefboolpthread_once_t;
2122

22-
#definePTHREAD_MUTEX_INITIALIZER{NULL,0 }
23+
#definePTHREAD_MUTEX_INITIALIZER{ 0 }
2324
#definePTHREAD_ONCE_INITfalse
2425

25-
voidwin32_pthread_mutex(volatilepthread_mutex_t*mutex);
26-
voidwin32_pthread_once(volatilepthread_once_t*once,void (*fn) (void));
26+
intpthread_mutex_init(pthread_mutex_t*,void*attr);
27+
intpthread_mutex_lock(pthread_mutex_t*);
28+
intpthread_mutex_unlock(pthread_mutex_t*);
2729

28-
#definepthread_mutex_lock(mutex) \
29-
do { \
30-
if ((mutex)->handle == NULL) \
31-
win32_pthread_mutex((mutex)); \
32-
WaitForSingleObject((mutex)->handle, INFINITE); \
33-
} while(0)
34-
35-
#definepthread_mutex_unlock(mutex) \
36-
ReleaseMutex((mutex)->handle)
30+
voidwin32_pthread_once(volatilepthread_once_t*once,void (*fn) (void));
3731

3832
#definepthread_getspecific(key) \
3933
TlsGetValue((key))

‎src/interfaces/libpq/fe-connect.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7426,24 +7426,8 @@ pqParseIntParam(const char *value, int *result, PGconn *conn,
74267426
staticvoid
74277427
default_threadlock(intacquire)
74287428
{
7429-
#ifndefWIN32
74307429
staticpthread_mutex_tsinglethread_lock=PTHREAD_MUTEX_INITIALIZER;
7431-
#else
7432-
staticpthread_mutex_tsinglethread_lock=NULL;
7433-
staticlongmutex_initlock=0;
74347430

7435-
if (singlethread_lock==NULL)
7436-
{
7437-
while (InterlockedExchange(&mutex_initlock,1)==1)
7438-
/* loop, another thread own the lock */ ;
7439-
if (singlethread_lock==NULL)
7440-
{
7441-
if (pthread_mutex_init(&singlethread_lock,NULL))
7442-
Assert(false);
7443-
}
7444-
InterlockedExchange(&mutex_initlock,0);
7445-
}
7446-
#endif
74477431
if (acquire)
74487432
{
74497433
if (pthread_mutex_lock(&singlethread_lock))

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,7 @@ static bool ssl_lib_initialized = false;
9191

9292
staticlongcrypto_open_connections=0;
9393

94-
#ifndefWIN32
9594
staticpthread_mutex_tssl_config_mutex=PTHREAD_MUTEX_INITIALIZER;
96-
#else
97-
staticpthread_mutex_tssl_config_mutex=NULL;
98-
staticlongwin32_ssl_create_mutex=0;
99-
#endif
10095

10196
staticPQsslKeyPassHook_OpenSSL_typePQsslKeyPassHook=NULL;
10297
staticintssl_protocol_version_to_openssl(constchar*protocol);
@@ -773,20 +768,6 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
773768
int
774769
pgtls_init(PGconn*conn,booldo_ssl,booldo_crypto)
775770
{
776-
#ifdefWIN32
777-
/* Also see similar code in fe-connect.c, default_threadlock() */
778-
if (ssl_config_mutex==NULL)
779-
{
780-
while (InterlockedExchange(&win32_ssl_create_mutex,1)==1)
781-
/* loop, another thread own the lock */ ;
782-
if (ssl_config_mutex==NULL)
783-
{
784-
if (pthread_mutex_init(&ssl_config_mutex,NULL))
785-
return-1;
786-
}
787-
InterlockedExchange(&win32_ssl_create_mutex,0);
788-
}
789-
#endif
790771
if (pthread_mutex_lock(&ssl_config_mutex))
791772
return-1;
792773

@@ -874,7 +855,6 @@ static void
874855
destroy_ssl_system(void)
875856
{
876857
#if defined(HAVE_CRYPTO_LOCK)
877-
/* Mutex is created in pgtls_init() */
878858
if (pthread_mutex_lock(&ssl_config_mutex))
879859
return;
880860

‎src/interfaces/libpq/pthread-win32.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,33 @@ pthread_getspecific(pthread_key_t key)
3434
int
3535
pthread_mutex_init(pthread_mutex_t*mp,void*attr)
3636
{
37-
*mp= (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
38-
if (!*mp)
39-
return1;
40-
InitializeCriticalSection(*mp);
37+
mp->initstate=0;
4138
return0;
4239
}
4340

4441
int
4542
pthread_mutex_lock(pthread_mutex_t*mp)
4643
{
47-
if (!*mp)
48-
return1;
49-
EnterCriticalSection(*mp);
44+
/* Initialize the csection if not already done */
45+
if (mp->initstate!=1)
46+
{
47+
LONGistate;
48+
49+
while ((istate=InterlockedExchange(&mp->initstate,2))==2)
50+
Sleep(0);/* wait, another thread is doing this */
51+
if (istate!=1)
52+
InitializeCriticalSection(&mp->csection);
53+
InterlockedExchange(&mp->initstate,1);
54+
}
55+
EnterCriticalSection(&mp->csection);
5056
return0;
5157
}
5258

5359
int
5460
pthread_mutex_unlock(pthread_mutex_t*mp)
5561
{
56-
if (!*mp)
57-
return1;
58-
LeaveCriticalSection(*mp);
62+
if (mp->initstate!=1)
63+
returnEINVAL;
64+
LeaveCriticalSection(&mp->csection);
5965
return0;
6066
}

‎src/port/pthread-win32.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@
55
#define__PTHREAD_H
66

77
typedefULONGpthread_key_t;
8-
typedefCRITICAL_SECTION*pthread_mutex_t;
8+
9+
typedefstructpthread_mutex_t
10+
{
11+
/* initstate = 0: not initialized; 1: init done; 2: init in progress */
12+
LONGinitstate;
13+
CRITICAL_SECTIONcsection;
14+
}pthread_mutex_t;
15+
16+
#definePTHREAD_MUTEX_INITIALIZER{ 0 }
17+
918
typedefintpthread_once_t;
1019

1120
DWORDpthread_self(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp