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

Commit7d7cc7f

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 parent1838829 commit7d7cc7f

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

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

470491
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
@@ -7327,24 +7327,8 @@ static void
73277327
default_threadlock(intacquire)
73287328
{
73297329
#ifdefENABLE_THREAD_SAFETY
7330-
#ifndefWIN32
73317330
staticpthread_mutex_tsinglethread_lock=PTHREAD_MUTEX_INITIALIZER;
7332-
#else
7333-
staticpthread_mutex_tsinglethread_lock=NULL;
7334-
staticlongmutex_initlock=0;
73357331

7336-
if (singlethread_lock==NULL)
7337-
{
7338-
while (InterlockedExchange(&mutex_initlock,1)==1)
7339-
/* loop, another thread own the lock */ ;
7340-
if (singlethread_lock==NULL)
7341-
{
7342-
if (pthread_mutex_init(&singlethread_lock,NULL))
7343-
PGTHREAD_ERROR("failed to initialize mutex");
7344-
}
7345-
InterlockedExchange(&mutex_initlock,0);
7346-
}
7347-
#endif
73487332
if (acquire)
73497333
{
73507334
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
@@ -87,12 +87,7 @@ static bool ssl_lib_initialized = false;
8787
#ifdefENABLE_THREAD_SAFETY
8888
staticlongcrypto_open_connections=0;
8989

90-
#ifndefWIN32
9190
staticpthread_mutex_tssl_config_mutex=PTHREAD_MUTEX_INITIALIZER;
92-
#else
93-
staticpthread_mutex_tssl_config_mutex=NULL;
94-
staticlongwin32_ssl_create_mutex=0;
95-
#endif
9691
#endif/* ENABLE_THREAD_SAFETY */
9792

9893
staticPQsslKeyPassHook_OpenSSL_typePQsslKeyPassHook=NULL;
@@ -649,20 +644,6 @@ int
649644
pgtls_init(PGconn*conn,booldo_ssl,booldo_crypto)
650645
{
651646
#ifdefENABLE_THREAD_SAFETY
652-
#ifdefWIN32
653-
/* Also see similar code in fe-connect.c, default_threadlock() */
654-
if (ssl_config_mutex==NULL)
655-
{
656-
while (InterlockedExchange(&win32_ssl_create_mutex,1)==1)
657-
/* loop, another thread own the lock */ ;
658-
if (ssl_config_mutex==NULL)
659-
{
660-
if (pthread_mutex_init(&ssl_config_mutex,NULL))
661-
return-1;
662-
}
663-
InterlockedExchange(&win32_ssl_create_mutex,0);
664-
}
665-
#endif
666647
if (pthread_mutex_lock(&ssl_config_mutex))
667648
return-1;
668649

@@ -753,7 +734,6 @@ static void
753734
destroy_ssl_system(void)
754735
{
755736
#if defined(ENABLE_THREAD_SAFETY)&& defined(HAVE_CRYPTO_LOCK)
756-
/* Mutex is created in pgtls_init() */
757737
if (pthread_mutex_lock(&ssl_config_mutex))
758738
return;
759739

‎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