Re: libpq and psql not on same page about SIGPIPE

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Manfred Spraul <manfred(at)colorfullife(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: libpq and psql not on same page about SIGPIPE
Date: 2004-12-01 15:41:59
Message-ID: 200412011541.iB1FfxK28146@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

Manfred Spraul wrote:
> Bruce Momjian wrote:
>
> >Comments? This seems like our only solution.
> >
> >
> >
> This would be a transparent solution. Another approach would be:
> - Use the old 7.3 approach by default. This means perfect backward
> compatibility for single-threaded apps and broken multithreaded apps.
> - Add a new PQinitDB(int disableSigpipeHandler) initialization function.
> Document that multithreaded apps must call the function with
> disableSigpipeHandle=1 and handle SIGPIPE for libpq. Perhaps with a
> reference implementation in libpq (i.e. a sigpipeMode with 0 for old
> approach, 1 for do nothing, 2 for install our own handler).
>
> It would prefer that approach:
> It means that the multithreaded libpq apps must be updated [are there
> any?], but the solution is simpler and less fragile than calling 4
> signal handling function in a row to selectively block SIGPIPE per-thread.

I think we can get away with three function calls because we can check
errno for EPIPE from the send() call. We already have two function
calls in there so I don't see a third as a huge problem and not worth an
API change unless someone tells us it is a performance hit.

One thing I know from the broken 7.4 code is that calling signal() from
inside a thread is very slow on Linux, like a 20% performance hit
because I assume it has to adjust all the threads signal stacks or
something. Anyway, I assume thread_sigmask() and sigpending() are not
huge hits.

In fact, by checking EPIPE from send() we don't need sigpending at all.
We just block and (if EPIPE) clear using sigwait(), then unblock. I
think we can document that if you are blocking SIGPIPE in your
application and wait to handle it later, you can't keep the pending
signal through a libpq call. I think that is a much easier requirement
than adding a new API call. The most common case of SIG_IGN/SIG_DFL is
not affected by this, only cases where they define their own signal
handler, block it, and then trying to keep a call active across a libpq
call.

Manfred, glad you are around to discuss this. After much research I
came up with a method and then found your description that matched it so
I felt I was on the right track.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Treat 2004-12-01 16:05:15 Re: Error handling in plperl and pltcl
Previous Message Robert Treat 2004-12-01 15:41:05 Re: Increasing the length of

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2004-12-01 17:23:44 Re: Developer's FAQ update
Previous Message Gavin Sherry 2004-12-01 07:37:51 Re: Developer's FAQ update