Обсуждение: PQinSend question
From fe-secure.c:
> /*
> * Indicates whether the current thread is in send()
> * For use by SIGPIPE signal handlers; they should
> * ignore SIGPIPE when libpq is in send(). This means
> * that the backend has died unexpectedly.
> */
> pqbool
> PQinSend(void)
> {
> #ifdef ENABLE_THREAD_SAFETY
> return (pthread_getspecific(thread_in_send) /* has it been
> set? */ &&
> *(char *)pthread_getspecific(thread_in_send)
> == 't') ? true : false;
> #else
> return false; /* No threading, so we can't be in send() */
Why not? Signal delivery can interrupt send() even with single-threaded
users.
I really like the openssl interface: what about something like
typedef void (*pgsigpipehandler_t)(bool enable);
void PQregisterSignalCallback(pgsigpipehandler_t new);
The callback is global, and called around the send() calls.
The default handler uses the sigaction code from 7.4. The current
autodetection code is less flexible than a callback, and it's not 100%
backward compatible.
-- Manfred
Manfred Spraul <manfred@colorfullife.com> writes:
>> return false; /* No threading, so we can't be in send() */
> Why not? Signal delivery can interrupt send() even with single-threaded
> users.
It looks like Bruce left the old logic in place for unthreaded
implementations: we just replace the signal handler during every send().
So there's no need for PQinSend() to do anything useful.
regards, tom lane
Tom Lane wrote: > Manfred Spraul <manfred@colorfullife.com> writes: > >> return false; /* No threading, so we can't be in send() */ > > > Why not? Signal delivery can interrupt send() even with single-threaded > > users. > > It looks like Bruce left the old logic in place for unthreaded > implementations: we just replace the signal handler during every send(). > So there's no need for PQinSend() to do anything useful. I have updated the CVS comments to more clearly explain this. -- 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, Pennsylvania19073
Manfred Spraul wrote:
> From fe-secure.c:
>
> > /*
> > * Indicates whether the current thread is in send()
> > * For use by SIGPIPE signal handlers; they should
> > * ignore SIGPIPE when libpq is in send(). This means
> > * that the backend has died unexpectedly.
> > */
> > pqbool
> > PQinSend(void)
> > {
> > #ifdef ENABLE_THREAD_SAFETY
> > return (pthread_getspecific(thread_in_send) /* has it been
> > set? */ &&
> > *(char *)pthread_getspecific(thread_in_send)
> > == 't') ? true : false;
> > #else
> > return false; /* No threading, so we can't be in send() */
>
> Why not? Signal delivery can interrupt send() even with single-threaded
> users.
[ Sorry I am late replying to this.]
I have added the attached comment to CVS to more clearly describe why we
are returning false from PQinSend().
> I really like the openssl interface: what about something like
>
> typedef void (*pgsigpipehandler_t)(bool enable);
>
> void PQregisterSignalCallback(pgsigpipehandler_t new);
>
> The callback is global, and called around the send() calls.
> The default handler uses the sigaction code from 7.4. The current
> autodetection code is less flexible than a callback, and it's not 100%
> backward compatible.
I think I addressed this and it is backward compatible (thread-local
storage), and requires no user application changes.
--
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: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.36
diff -c -c -r1.36 fe-secure.c
*** src/interfaces/libpq/fe-secure.c 9 Jan 2004 02:17:15 -0000 1.36
--- src/interfaces/libpq/fe-secure.c 10 Feb 2004 15:16:51 -0000
***************
*** 1122,1127 ****
return (pthread_getspecific(thread_in_send) /* has it been set? */ &&
*(char *)pthread_getspecific(thread_in_send) == 't') ? true : false;
#else
! return false; /* No threading, so we can't be in send() */
#endif
}
--- 1122,1132 ----
return (pthread_getspecific(thread_in_send) /* has it been set? */ &&
*(char *)pthread_getspecific(thread_in_send) == 't') ? true : false;
#else
! /*
! * No threading: our code ignores SIGPIPE around send().
! * Therefore, we can't be in send() if we are checking
! * from a SIGPIPE signal handler.
! */
! return false;
#endif
}