@@ -35,6 +35,9 @@ bool interrupted = false;
35
35
bool in_cleanup = false;
36
36
bool in_password = false;
37
37
38
+ /* critical section when adding disconnect callbackups */
39
+ static pthread_mutex_t atexit_callback_disconnect_mutex = PTHREAD_MUTEX_INITIALIZER ;
40
+
38
41
/* Connection routines */
39
42
static void init_cancel_handler (void );
40
43
static void on_before_exec (PGconn * conn , PGcancel * thread_cancel_conn );
@@ -48,6 +51,7 @@ static void pgut_pgfnames_cleanup(char **filenames);
48
51
49
52
void discard_response (PGconn * conn );
50
53
54
+ /* Note that atexit handlers always called on the main thread */
51
55
void
52
56
pgut_init (void )
53
57
{
@@ -237,7 +241,9 @@ pgut_connect(const char *host, const char *port,
237
241
238
242
if (PQstatus (conn ) == CONNECTION_OK )
239
243
{
244
+ pthread_lock (& atexit_callback_disconnect_mutex );
240
245
pgut_atexit_push (pgut_disconnect_callback , conn );
246
+ pthread_mutex_unlock (& atexit_callback_disconnect_mutex );
241
247
return conn ;
242
248
}
243
249
@@ -365,7 +371,10 @@ pgut_disconnect(PGconn *conn)
365
371
{
366
372
if (conn )
367
373
PQfinish (conn );
374
+
375
+ pthread_lock (& atexit_callback_disconnect_mutex );
368
376
pgut_atexit_pop (pgut_disconnect_callback , conn );
377
+ pthread_mutex_unlock (& atexit_callback_disconnect_mutex );
369
378
}
370
379
371
380
@@ -840,7 +849,9 @@ call_atexit_callbacks(bool fatal)
840
849
{
841
850
pgut_atexit_item * item ;
842
851
pgut_atexit_item * next ;
843
- for (item = pgut_atexit_stack ; item ; item = next ){
852
+
853
+ for (item = pgut_atexit_stack ; item ; item = next )
854
+ {
844
855
next = item -> next ;
845
856
item -> callback (fatal , item -> userdata );
846
857
}
0 commit comments