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