Skip to content
Snippets Groups Projects
Commit 3f0fa93c authored by Bruce Momjian's avatar Bruce Momjian
Browse files

Chain on to SIGPIPE handler rather than just do action on default.

Always create thread-specific variable.
parent 0d4aa039
No related branches found
No related tags found
No related merge requests found
<!--
$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,24 +1191,13 @@ PQgetssl(PGconn *conn)
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 */
{
pthread_key_create(&pq_thread_in_send, NULL);
/*
* Create key first because the signal handler might be called
* right after being installed.
* Find current pipe handler and chain on to it.
*/
pthread_key_create(&pq_thread_in_send, NULL);
pq_pipe_handler = pqsignalinquire(SIGPIPE);
pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
}
}
/*
* Threaded SIGPIPE signal handler
......@@ -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())
{
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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment