Re: libpq problem - Mailing list pgsql-hackers

From Andreas Pflug
Subject Re: libpq problem
Date
Msg-id 411A3429.4000107@pse-consulting.de
Whole thread Raw
In response to libpq problem  (Andreas Pflug <pgadmin@pse-consulting.de>)
List pgsql-hackers
Andreas Pflug wrote:
> Some recent change in libpq seems to interfere with gtk.
>
> After I tested a new pgadmin3 version on linuy yesterday, I found that
> the GUI is hanging after PQconnectdb was called. After the call, the db
> connection is fully functional, but the GUI mouse will show "waiting"
> and the program doesn't react to mouse clicks any more; screen updates
> are not performed either.
>
> When I replace the 8.0 libpq.so* version with an older saved version
> (7.4.3 from debian installation) it works ok.

OK, I found out. Seems I didn't run make distclean for a longer time, so
I didn't realize earlier.

The reason is the sigpipe handling code. If the app (in this case: some
gtk internals) already installed a SIGPIPE handler, the thread_in_send
key is not created. pthread_setspecific calls will thus use an invalid
key, which screws up gtk.

The attached patch will implement two features:
1) unconditionally create thread_in_send
2) Always register our own SIGPIPE handler, chain to a previously
registered handler when the signal is thrown while not sending.

Regards,
Andreas
Index: fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.45
diff -u -r1.45 fe-secure.c
--- fe-secure.c    12 Jul 2004 14:23:28 -0000    1.45
+++ fe-secure.c    11 Aug 2004 12:49:35 -0000
@@ -153,6 +153,7 @@
 #ifdef ENABLE_THREAD_SAFETY
 static void sigpipe_handler_ignore_send(int signo);
 pthread_key_t thread_in_send;
+static pqsigfunc pipehandler;
 #endif

 /* ------------------------------------------------------------ */
@@ -1190,23 +1191,14 @@
 void
 check_sigpipe_handler(void)
 {
-    pqsigfunc pipehandler;
-
     /*
      *    If the app hasn't set a SIGPIPE handler, define our own
      *    that ignores SIGPIPE on libpq send() and does SIG_DFL
      *    for other SIGPIPE cases.
      */
+    pthread_key_create(&thread_in_send, NULL);
     pipehandler = pqsignalinquire(SIGPIPE);
-    if (pipehandler == SIG_DFL)    /* not set by application */
-    {
-        /*
-         *    Create key first because the signal handler might be called
-         *    right after being installed.
-         */
-        pthread_key_create(&thread_in_send, NULL);
-        pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
-    }
+    pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
 }

 /*
@@ -1221,7 +1213,12 @@
      *    that caused the signal.
      */
     if (!PQinSend())
-        exit(128 + SIGPIPE);    /* typical return value for SIG_DFL */
+    {
+        if (pipehandler == SIG_DFL)    /* not set by application */
+            exit(128 + SIGPIPE);    /* typical return value for SIG_DFL */
+        else
+            (*pipehandler)(signo);      /* call original handler */
+    }
 }
 #endif
 #endif

pgsql-hackers by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: Missing French backend translations in the HEAD
Next
From: pgsql@mohawksoft.com
Date:
Subject: fsync, fdatasync, open_sync, and open_datasync, -- Linux insanity