mirror of
https://github.com/postgres/postgres.git
synced 2025-06-01 00:01:20 -04:00
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">
|
<chapter id="libpq">
|
||||||
@ -3738,8 +3738,7 @@ When <productname>PostgreSQL</> is configured without
|
|||||||
<function>send()</> call and restores the original signal handler after
|
<function>send()</> call and restores the original signal handler after
|
||||||
completion. When <literal>--enable-thread-safety</> is used,
|
completion. When <literal>--enable-thread-safety</> is used,
|
||||||
<application>libpq</> installs its own <literal>SIGPIPE</> handler
|
<application>libpq</> installs its own <literal>SIGPIPE</> handler
|
||||||
before the first database connection if no custom <literal>SIGPIPE</>
|
before the first database connection. This handler uses thread-local
|
||||||
handler has been installed previously. This handler uses thread-local
|
|
||||||
storage to determine if a <literal>SIGPIPE</> signal has been generated
|
storage to determine if a <literal>SIGPIPE</> signal has been generated
|
||||||
by a libpq <function>send()</>. If an application wants to install
|
by a libpq <function>send()</>. If an application wants to install
|
||||||
its own <literal>SIGPIPE</> signal handler, it should call
|
its own <literal>SIGPIPE</> signal handler, it should call
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* The client *requires* a valid server certificate. Since
|
* The client *requires* a valid server certificate. Since
|
||||||
@ -152,7 +152,8 @@ static SSL_CTX *SSL_context = NULL;
|
|||||||
|
|
||||||
#ifdef ENABLE_THREAD_SAFETY
|
#ifdef ENABLE_THREAD_SAFETY
|
||||||
static void sigpipe_handler_ignore_send(int signo);
|
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
|
#endif
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@ -1190,23 +1191,12 @@ PQgetssl(PGconn *conn)
|
|||||||
void
|
void
|
||||||
pq_check_sigpipe_handler(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
|
* Find current pipe handler and chain on to it.
|
||||||
* that ignores SIGPIPE on libpq send() and does SIG_DFL
|
|
||||||
* for other SIGPIPE cases.
|
|
||||||
*/
|
*/
|
||||||
pipehandler = pqsignalinquire(SIGPIPE);
|
pq_pipe_handler = pqsignalinquire(SIGPIPE);
|
||||||
if (pipehandler == SIG_DFL) /* not set by application */
|
pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1216,12 +1206,18 @@ void
|
|||||||
sigpipe_handler_ignore_send(int signo)
|
sigpipe_handler_ignore_send(int signo)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If we have gotten a SIGPIPE outside send(), exit.
|
* If we have gotten a SIGPIPE outside send(), chain or
|
||||||
* Synchronous signals are delivered to the thread
|
* exit if we are at the end of the chain.
|
||||||
* that caused the signal.
|
* Synchronous signals are delivered to the thread that
|
||||||
|
* caused the signal.
|
||||||
*/
|
*/
|
||||||
if (!PQinSend())
|
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
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user