Re: [HACKERS] libpq problem - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: [HACKERS] libpq problem |
Date | |
Msg-id | 200408171653.i7HGrue05863@candle.pha.pa.us Whole thread Raw |
In response to | Re: [HACKERS] libpq problem (Andreas Pflug <pgadmin@pse-consulting.de>) |
Responses |
Re: [HACKERS] libpq problem
|
List | pgsql-patches |
OK, I like your idea of chaining on to any existing SIGPIPE handler rather than just do it if none is installed. I also see your fix for the uninitialized thread-specific variable. I added some comments to the patch, renamed the pipeheader variable so it was pg_* to avoid namespace conflicts, and updated the documentation. Patch attached and applied. --------------------------------------------------------------------------- Andreas Pflug wrote: > 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 > > ---------------------------(end of broadcast)--------------------------- > TIP 9: the planner will ignore your desire to choose an index scan if your > joining column's datatypes do not match -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: doc/src/sgml/libpq.sgml =================================================================== RCS file: /cvsroot/pgsql-server/doc/src/sgml/libpq.sgml,v retrieving revision 1.159 diff -c -c -r1.159 libpq.sgml *** doc/src/sgml/libpq.sgml 16 Aug 2004 02:12:29 -0000 1.159 --- doc/src/sgml/libpq.sgml 17 Aug 2004 16:43:10 -0000 *************** *** 3738,3745 **** <function>send()</> call and restores the original signal handler after completion. When <literal>--enable-thread-safety</> is used, <application>libpq</> installs its own <literal>SIGPIPE</> handler ! before the first database connection if no custom <literal>SIGPIPE</> ! handler has been installed previously. This handler uses thread-local storage to determine if a <literal>SIGPIPE</> signal has been generated by a libpq <function>send()</>. If an application wants to install its own <literal>SIGPIPE</> signal handler, it should call --- 3738,3744 ---- <function>send()</> call and restores the original signal handler after completion. When <literal>--enable-thread-safety</> is used, <application>libpq</> installs its own <literal>SIGPIPE</> handler ! before the first database connection. This handler uses thread-local storage to determine if a <literal>SIGPIPE</> signal has been generated by a libpq <function>send()</>. If an application wants to install its own <literal>SIGPIPE</> signal handler, it should call Index: src/interfaces/libpq/fe-secure.c =================================================================== RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v retrieving revision 1.46 diff -c -c -r1.46 fe-secure.c *** src/interfaces/libpq/fe-secure.c 17 Aug 2004 04:24:23 -0000 1.46 --- src/interfaces/libpq/fe-secure.c 17 Aug 2004 16:43:19 -0000 *************** *** 152,158 **** #ifdef ENABLE_THREAD_SAFETY static void sigpipe_handler_ignore_send(int signo); ! pthread_key_t pq_thread_in_send = 0; #endif /* ------------------------------------------------------------ */ --- 152,159 ---- #ifdef ENABLE_THREAD_SAFETY static void sigpipe_handler_ignore_send(int signo); ! pthread_key_t pq_thread_in_send = 0; /* initializer needed on Darwin */ ! static pqsigfunc pq_pipe_handler; #endif /* ------------------------------------------------------------ */ *************** *** 1190,1212 **** void pq_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. */ ! 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(&pq_thread_in_send, NULL); ! pqsignal(SIGPIPE, sigpipe_handler_ignore_send); ! } } /* --- 1191,1202 ---- void pq_check_sigpipe_handler(void) { ! pthread_key_create(&pq_thread_in_send, NULL); /* ! * Find current pipe handler and chain on to it. */ ! pq_pipe_handler = pqsignalinquire(SIGPIPE); ! pqsignal(SIGPIPE, sigpipe_handler_ignore_send); } /* *************** *** 1216,1227 **** sigpipe_handler_ignore_send(int signo) { /* ! * If we have gotten a SIGPIPE outside send(), exit. ! * Synchronous signals are delivered to the thread ! * that caused the signal. */ if (!PQinSend()) ! exit(128 + SIGPIPE); /* typical return value for SIG_DFL */ } #endif #endif --- 1206,1223 ---- sigpipe_handler_ignore_send(int signo) { /* ! * If we have gotten a SIGPIPE outside send(), chain or ! * exit if we are at the end of the chain. ! * Synchronous signals are delivered to the thread that ! * caused the signal. */ if (!PQinSend()) ! { ! if (pq_pipe_handler == SIG_DFL) /* not set by application */ ! exit(128 + SIGPIPE); /* typical return value for SIG_DFL */ ! else ! (*pq_pipe_handler)(signo); /* call original handler */ ! } } #endif #endif
pgsql-patches by date: