]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Loop calling CallNamedPipe() several times in case it fails,
authorMagnus Hagander <magnus@hagander.net>
Sun, 15 Feb 2009 13:58:20 +0000 (13:58 +0000)
committerMagnus Hagander <magnus@hagander.net>
Sun, 15 Feb 2009 13:58:20 +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 cc1429c0a5858b3ac7d682227e9dd0fcf101b0a7..80b4cdc5613a3c9a46bc2a3ec00e1232e41988f5 100644 (file)
@@ -9,7 +9,7 @@
  *     signals that the backend can recognize.
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/port/kill.c,v 1.7 2006/03/05 15:59:10 momjian Exp $
+ *       $PostgreSQL: pgsql/src/port/kill.c,v 1.7.2.1 2009/02/15 13:58:20 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)
@@ -38,24 +39,34 @@ pgkill(int pid, int sig)
                errno = EINVAL;
                return -1;
        }
-       wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%i", 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)
+       snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", pid);
+
+       /*
+        * 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