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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers