From 2e371183ee8c766d6d166f71060858e14d181220 Mon Sep 17 00:00:00 2001 From: Magnus Hagander <magnus@hagander.net> Date: Sun, 15 Feb 2009 13:58:18 +0000 Subject: [PATCH] Loop calling CallNamedPipe() several times in case it fails, 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 | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/port/kill.c b/src/port/kill.c index ea71f75c3e9..1ec5ee5b783 100644 --- a/src/port/kill.c +++ b/src/port/kill.c @@ -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 -- GitLab