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

Commit95e960e

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 parentd44060c commit95e960e

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
@@ -459,17 +459,38 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr)
459459
#ifdefWIN32
460460
#ifdefENABLE_THREAD_SAFETY
461461

462-
void
463-
win32_pthread_mutex(volatilepthread_mutex_t*mutex)
462+
int
463+
pthread_mutex_init(pthread_mutex_t*mp,void*attr)
464+
{
465+
mp->initstate=0;
466+
return0;
467+
}
468+
469+
int
470+
pthread_mutex_lock(pthread_mutex_t*mp)
464471
{
465-
if (mutex->handle==NULL)
472+
/* Initialize the csection if not already done */
473+
if (mp->initstate!=1)
466474
{
467-
while (InterlockedExchange((LONG*)&mutex->initlock,1)==1)
468-
Sleep(0);
469-
if (mutex->handle==NULL)
470-
mutex->handle=CreateMutex(NULL, FALSE,NULL);
471-
InterlockedExchange((LONG*)&mutex->initlock,0);
475+
LONGistate;
476+
477+
while ((istate=InterlockedExchange(&mp->initstate,2))==2)
478+
Sleep(0);/* wait, another thread is doing this */
479+
if (istate!=1)
480+
InitializeCriticalSection(&mp->csection);
481+
InterlockedExchange(&mp->initstate,1);
472482
}
483+
EnterCriticalSection(&mp->csection);
484+
return0;
485+
}
486+
487+
int
488+
pthread_mutex_unlock(pthread_mutex_t*mp)
489+
{
490+
if (mp->initstate!=1)
491+
returnEINVAL;
492+
LeaveCriticalSection(&mp->csection);
493+
return0;
473494
}
474495

475496
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
@@ -7112,24 +7112,8 @@ static void
71127112
default_threadlock(intacquire)
71137113
{
71147114
#ifdefENABLE_THREAD_SAFETY
7115-
#ifndefWIN32
71167115
staticpthread_mutex_tsinglethread_lock=PTHREAD_MUTEX_INITIALIZER;
7117-
#else
7118-
staticpthread_mutex_tsinglethread_lock=NULL;
7119-
staticlongmutex_initlock=0;
71207116

7121-
if (singlethread_lock==NULL)
7122-
{
7123-
while (InterlockedExchange(&mutex_initlock,1)==1)
7124-
/* loop, another thread own the lock */ ;
7125-
if (singlethread_lock==NULL)
7126-
{
7127-
if (pthread_mutex_init(&singlethread_lock,NULL))
7128-
PGTHREAD_ERROR("failed to initialize mutex");
7129-
}
7130-
InterlockedExchange(&mutex_initlock,0);
7131-
}
7132-
#endif
71337117
if (acquire)
71347118
{
71357119
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
@@ -85,12 +85,7 @@ static bool ssl_lib_initialized = false;
8585
#ifdefENABLE_THREAD_SAFETY
8686
staticlongssl_open_connections=0;
8787

88-
#ifndefWIN32
8988
staticpthread_mutex_tssl_config_mutex=PTHREAD_MUTEX_INITIALIZER;
90-
#else
91-
staticpthread_mutex_tssl_config_mutex=NULL;
92-
staticlongwin32_ssl_create_mutex=0;
93-
#endif
9489
#endif/* ENABLE_THREAD_SAFETY */
9590

9691

@@ -649,20 +644,6 @@ int
649644
pgtls_init(PGconn*conn)
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

@@ -747,7 +728,6 @@ static void
747728
destroy_ssl_system(void)
748729
{
749730
#if defined(ENABLE_THREAD_SAFETY)&& defined(HAVE_CRYPTO_LOCK)
750-
/* Mutex is created in pgtls_init() */
751731
if (pthread_mutex_lock(&ssl_config_mutex))
752732
return;
753733

‎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