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

Commit9440d23

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 parente3e05ad commit9440d23

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
@@ -453,17 +453,38 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
453453
#ifdefWIN32
454454
#ifdefENABLE_THREAD_SAFETY
455455

456-
void
457-
win32_pthread_mutex(volatilepthread_mutex_t*mutex)
456+
int
457+
pthread_mutex_init(pthread_mutex_t*mp,void*attr)
458+
{
459+
mp->initstate=0;
460+
return0;
461+
}
462+
463+
int
464+
pthread_mutex_lock(pthread_mutex_t*mp)
458465
{
459-
if (mutex->handle==NULL)
466+
/* Initialize the csection if not already done */
467+
if (mp->initstate!=1)
460468
{
461-
while (InterlockedExchange((LONG*)&mutex->initlock,1)==1)
462-
Sleep(0);
463-
if (mutex->handle==NULL)
464-
mutex->handle=CreateMutex(NULL, FALSE,NULL);
465-
InterlockedExchange((LONG*)&mutex->initlock,0);
469+
LONGistate;
470+
471+
while ((istate=InterlockedExchange(&mp->initstate,2))==2)
472+
Sleep(0);/* wait, another thread is doing this */
473+
if (istate!=1)
474+
InitializeCriticalSection(&mp->csection);
475+
InterlockedExchange(&mp->initstate,1);
466476
}
477+
EnterCriticalSection(&mp->csection);
478+
return0;
479+
}
480+
481+
int
482+
pthread_mutex_unlock(pthread_mutex_t*mp)
483+
{
484+
if (mp->initstate!=1)
485+
returnEINVAL;
486+
LeaveCriticalSection(&mp->csection);
487+
return0;
467488
}
468489

469490
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
@@ -14,28 +14,22 @@
1414

1515
typedefstructpthread_mutex_t
1616
{
17-
HANDLEhandle;
18-
LONGinitlock;
17+
/* initstate = 0: not initialized; 1: init done; 2: init in progress */
18+
LONGinitstate;
19+
CRITICAL_SECTIONcsection;
1920
}pthread_mutex_t;
2021

2122
typedefDWORDpthread_key_t;
2223
typedefboolpthread_once_t;
2324

24-
#definePTHREAD_MUTEX_INITIALIZER{NULL,0 }
25+
#definePTHREAD_MUTEX_INITIALIZER{ 0 }
2526
#definePTHREAD_ONCE_INITfalse
2627

27-
voidwin32_pthread_mutex(volatilepthread_mutex_t*mutex);
28-
voidwin32_pthread_once(volatilepthread_once_t*once,void (*fn) (void));
28+
intpthread_mutex_init(pthread_mutex_t*,void*attr);
29+
intpthread_mutex_lock(pthread_mutex_t*);
30+
intpthread_mutex_unlock(pthread_mutex_t*);
2931

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

4034
#definepthread_getspecific(key) \
4135
TlsGetValue((key))

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

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7785,24 +7785,8 @@ static void
77857785
default_threadlock(intacquire)
77867786
{
77877787
#ifdefENABLE_THREAD_SAFETY
7788-
#ifndefWIN32
77897788
staticpthread_mutex_tsinglethread_lock=PTHREAD_MUTEX_INITIALIZER;
7790-
#else
7791-
staticpthread_mutex_tsinglethread_lock=NULL;
7792-
staticlongmutex_initlock=0;
77937789

7794-
if (singlethread_lock==NULL)
7795-
{
7796-
while (InterlockedExchange(&mutex_initlock,1)==1)
7797-
/* loop, another thread own the lock */ ;
7798-
if (singlethread_lock==NULL)
7799-
{
7800-
if (pthread_mutex_init(&singlethread_lock,NULL))
7801-
Assert(false);
7802-
}
7803-
InterlockedExchange(&mutex_initlock,0);
7804-
}
7805-
#endif
78067790
if (acquire)
78077791
{
78087792
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
@@ -94,12 +94,7 @@ static bool ssl_lib_initialized = false;
9494
#ifdefENABLE_THREAD_SAFETY
9595
staticlongcrypto_open_connections=0;
9696

97-
#ifndefWIN32
9897
staticpthread_mutex_tssl_config_mutex=PTHREAD_MUTEX_INITIALIZER;
99-
#else
100-
staticpthread_mutex_tssl_config_mutex=NULL;
101-
staticlongwin32_ssl_create_mutex=0;
102-
#endif
10398
#endif/* ENABLE_THREAD_SAFETY */
10499

105100
staticPQsslKeyPassHook_OpenSSL_typePQsslKeyPassHook=NULL;
@@ -783,20 +778,6 @@ int
783778
pgtls_init(PGconn*conn,booldo_ssl,booldo_crypto)
784779
{
785780
#ifdefENABLE_THREAD_SAFETY
786-
#ifdefWIN32
787-
/* Also see similar code in fe-connect.c, default_threadlock() */
788-
if (ssl_config_mutex==NULL)
789-
{
790-
while (InterlockedExchange(&win32_ssl_create_mutex,1)==1)
791-
/* loop, another thread own the lock */ ;
792-
if (ssl_config_mutex==NULL)
793-
{
794-
if (pthread_mutex_init(&ssl_config_mutex,NULL))
795-
return-1;
796-
}
797-
InterlockedExchange(&win32_ssl_create_mutex,0);
798-
}
799-
#endif
800781
if (pthread_mutex_lock(&ssl_config_mutex))
801782
return-1;
802783

@@ -887,7 +868,6 @@ static void
887868
destroy_ssl_system(void)
888869
{
889870
#if defined(ENABLE_THREAD_SAFETY)&& defined(HAVE_CRYPTO_LOCK)
890-
/* Mutex is created in pgtls_init() */
891871
if (pthread_mutex_lock(&ssl_config_mutex))
892872
return;
893873

‎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