Chain on to SIGPIPE handler rather than just do action on default.
Always create thread-specific variable.
This commit is contained in:
parent
0d4aa039ac
commit
3f0fa93cfc
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.159 2004/08/16 02:12:29 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.160 2004/08/17 16:54:46 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpq">
|
||||
@ -3738,8 +3738,7 @@ When <productname>PostgreSQL</> is configured without
|
||||
<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
|
||||
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
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.46 2004/08/17 04:24:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.47 2004/08/17 16:54:47 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The client *requires* a valid server certificate. Since
|
||||
@ -152,7 +152,8 @@ static SSL_CTX *SSL_context = NULL;
|
||||
|
||||
#ifdef ENABLE_THREAD_SAFETY
|
||||
static void sigpipe_handler_ignore_send(int signo);
|
||||
pthread_key_t pq_thread_in_send = 0;
|
||||
pthread_key_t pq_thread_in_send = 0; /* initializer needed on Darwin */
|
||||
static pqsigfunc pq_pipe_handler;
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -1190,23 +1191,12 @@ PQgetssl(PGconn *conn)
|
||||
void
|
||||
pq_check_sigpipe_handler(void)
|
||||
{
|
||||
pqsigfunc pipehandler;
|
||||
|
||||
pthread_key_create(&pq_thread_in_send, NULL);
|
||||
/*
|
||||
* 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.
|
||||
* Find current pipe handler and chain on to it.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
pq_pipe_handler = pqsignalinquire(SIGPIPE);
|
||||
pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1216,12 +1206,18 @@ void
|
||||
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 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())
|
||||
exit(128 + SIGPIPE); /* typical return value for SIG_DFL */
|
||||
{
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user