Hello, simplly inhibit set retry flag when ProcDiePending in my_sock_write seems enough.
But it returns with SSL_ERROR_SYSCALL not SSL_ERROR_WANT_WRITE so I modified the patch 4 as the attached patch. Finally, the attached patch works as expected with Andres's patch 1-3. regards, -- Kyotaro Horiguchi NTT Open Source Software Center
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 6fc6903..2288fe2 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -750,7 +750,8 @@ my_sock_write(BIO *h, const char *buf, int size) BIO_clear_retry_flags(h); if (res <= 0) { - if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) + if (!ProcDiePending && + (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)) { BIO_set_retry_write(h); } diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index 7b5b30f..ab9e122 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -199,6 +199,7 @@ secure_write(Port *port, void *ptr, size_t len) { ssize_t n; +retry: #ifdef USE_SSL if (port->ssl_in_use) { @@ -210,7 +211,26 @@ secure_write(Port *port, void *ptr, size_t len) n = secure_raw_write(port, ptr, len); } - /* XXX: We likely will want to process some interrupts here */ + /* + * We only want to process the interrupt here if socket writes are + * blocking to increase the chance to get an error message to the + * client. If we're not blocked there'll soon be a + * CHECK_FOR_INTERRUPTS(). But if we're blocked we'll never get out of + * that situation if the client has died. + */ + if (ProcDiePending && !port->noblock && n < 0) + { + /* + * We're dying. It's safe (and sane) to handle that now. + */ + CHECK_FOR_INTERRUPTS(); + } + + /* retry after processing interrupts */ + if (n < 0 && errno == EINTR) + { + goto retry; + } return n; } @@ -236,10 +256,19 @@ wloop: * don't do anything while (possibly) inside a ssl library. */ w = WaitLatchOrSocket(&MyProc->procLatch, - WL_SOCKET_WRITEABLE, + WL_LATCH_SET | WL_SOCKET_WRITEABLE, port->sock, 0); - if (w & WL_SOCKET_WRITEABLE) + if (w & WL_LATCH_SET) + { + ResetLatch(&MyProc->procLatch); + /* + * Force a return, so interrupts can be processed when not + * (possibly) underneath a ssl library. + */ + errno = EINTR; + } + else if (w & WL_SOCKET_WRITEABLE) { goto wloop; } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3a6aa1c..61390aa 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -520,6 +520,13 @@ ProcessClientReadInterrupt(void) errno = save_errno; } + else if (ProcDiePending) + { + /* + * We're dying. It's safe (and sane) to handle that now. + */ + CHECK_FOR_INTERRUPTS(); + } }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers