 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


Sun, 11 Jan 2004 16:34:34 +0100
Manfred Spraul <manfred@colorfullife.com>
PQinSend question
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

Sun, 11 Jan 2004 12:28:53 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: PQinSend question 
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
  }
Tue, 10 Feb 2004 10:20:59 -0500 (EST)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: PQinSend question
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, Pennsylvania 19073

Tue, 10 Feb 2004 10:21:42 -0500 (EST)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: PQinSend question