Re: Escaping from blocked send() reprised. - Mailing list pgsql-hackers

From Kyotaro HORIGUCHI
Subject Re: Escaping from blocked send() reprised.
Date
Msg-id 20141009.140635.18322240.horiguchi.kyotaro@lab.ntt.co.jp
Whole thread Raw
In response to Re: Escaping from blocked send() reprised.  (Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>)
Responses Re: Escaping from blocked send() reprised.
List pgsql-hackers
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();
+    }}

pgsql-hackers by date:

Previous
From:
Date:
Subject: Re: pg_receivexlog --status-interval add fsync feedback
Next
From: Simon Riggs
Date:
Subject: Re: INSERT ... ON CONFLICT {UPDATE | IGNORE}