[patch] helps fe-connect.c handle -EINTR more gracefully

Поиск
Список
Период
Сортировка
От David Ford
Тема [patch] helps fe-connect.c handle -EINTR more gracefully
Дата
Msg-id 3BD87F49.5050903@blue-labs.org
обсуждение исходный текст
Ответы Re: [patch] helps fe-connect.c handle -EINTR more gracefully  (Brent Verner <brent@rcfile.org>)
Список pgsql-hackers
I'm fresh in the code, but this has solved my issues with PQconnect*
failing when interrupted by signals.  Some of it is sloppy and not to my
liking yet, but I'm still digging through to see if anything else needs
touched.  Comments appreciated.

Honestly, I'm a bit surprised that this issue hasn't been encountered
before.

Summary:
    * changes to connect() sections to handle errno=EINTR.  this solves
libpq PQconnect* family problems if the connect is interrupted by a
signal such as SIGALRM.
    * not all read/recv/write/send calls have been updated

David

--- src/interfaces/libpq/fe-connect.c.orig    Wed Oct 24 17:43:52 2001
+++ src/interfaces/libpq/fe-connect.c    Wed Oct 24 17:43:54 2001
@@ -912,21 +912,35 @@
      * Thus, we have to make arrangements for all eventualities.
      * ----------
      */
+
+    retry_socket:
     if (connect(conn->sock, &conn->raddr.sa, conn->raddr_len) < 0)
     {
-        if (SOCK_ERRNO == EINPROGRESS || SOCK_ERRNO == EWOULDBLOCK || SOCK_ERRNO == 0)
-        {
-            /*
-             * This is fine - we're in non-blocking mode, and the
-             * connection is in progress.
-             */
-            conn->status = CONNECTION_STARTED;
-        }
-        else
-        {
-            /* Something's gone wrong */
-            connectFailureMessage(conn, SOCK_ERRNO);
-            goto connect_errReturn;
+        switch (SOCK_ERRNO) {
+            case EINTR:
+                /*
+                 * interrupted by signal, keep trying
+                 */
+                 goto retry_socket;
+                 break;
+
+            case 0:
+            case EINPROGRESS:
+            case EWOULDBLOCK:
+                /*
+                 * This is fine - we're in non-blocking mode, and the
+                 * connection is in progress.
+                 */
+                conn->status = CONNECTION_STARTED;
+                break;
+
+            default:
+                /*
+                 * Something's gone wrong
+                 */
+                connectFailureMessage(conn, SOCK_ERRNO);
+                goto connect_errReturn;
+                break;
         }
     }
     else
@@ -2132,8 +2146,13 @@
                "PQrequestCancel() -- socket() failed: ");
         goto cancel_errReturn;
     }
-    if (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
+    while (connect(tmpsock, &conn->raddr.sa, conn->raddr_len) < 0)
     {
+        /*
+         * interrupted by a signal
+         */
+        if(errno==EINTR)
+            continue;
         strcpy(conn->errorMessage.data,
                "PQrequestCancel() -- connect() failed: ");
         goto cancel_errReturn;

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Mikhail Terekhov
Дата:
Сообщение: LOCK SEQUENCE
Следующее
От: Tom Lane
Дата:
Сообщение: Re: LOCK SEQUENCE