OSDN Git Service

Loop calling CallNamedPipe() several times in case it fails,
authorMagnus Hagander <magnus@hagander.net>
Sun, 15 Feb 2009 13:58:18 +0000 (13:58 +0000)
committerMagnus Hagander <magnus@hagander.net>
Sun, 15 Feb 2009 13:58:18 +0000 (13:58 +0000)
since it can be transient failures, causing kill() to not
properly send signals.

Original patch from Steve Marshall, modified by me.

src/port/kill.c

index ea71f75..1ec5ee5 100644 (file)
@@ -9,7 +9,7 @@
  *     signals that the backend can recognize.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/port/kill.c,v 1.11 2009/01/01 17:24:04 momjian Exp $
+ *       $PostgreSQL: pgsql/src/port/kill.c,v 1.12 2009/02/15 13:58:18 mha Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,7 @@ pgkill(int pid, int sig)
        BYTE            sigData = sig;
        BYTE            sigRet = 0;
        DWORD           bytes;
+       int                     pipe_tries;
 
        /* we allow signal 0 here, but it will be ignored in pg_queue_signal */
        if (sig >= PG_SIGNAL_COUNT || sig < 0)
@@ -39,23 +40,33 @@ pgkill(int pid, int sig)
                return -1;
        }
        snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", pid);
-       if (!CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000))
-       {
-               if (GetLastError() == ERROR_FILE_NOT_FOUND)
-                       errno = ESRCH;
-               else if (GetLastError() == ERROR_ACCESS_DENIED)
-                       errno = EPERM;
-               else
-                       errno = EINVAL;
-               return -1;
-       }
-       if (bytes != 1 || sigRet != sig)
+
+       /*
+        * Writing data to the named pipe can fail for transient reasons.
+        * Therefore, it is useful to retry if it fails.  The maximum number of
+        * calls to make was empirically determined from a 90-hour notification
+        * stress test.
+        */
+       for (pipe_tries = 0; pipe_tries < 3; pipe_tries++)
        {
-               errno = ESRCH;
-               return -1;
+               if (CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000))
+               {
+                       if (bytes != 1 || sigRet != sig)
+                       {
+                               errno = ESRCH;
+                               return -1;
+                       }
+                       return 0;
+               }
        }
 
-       return 0;
+       if (GetLastError() == ERROR_FILE_NOT_FOUND)
+               errno = ESRCH;
+       else if (GetLastError() == ERROR_ACCESS_DENIED)
+               errno = EPERM;
+       else
+               errno = EINVAL;
+       return -1;
 }
 
 #endif