summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Hagander2009-02-15 13:58:18 +0000
committerMagnus Hagander2009-02-15 13:58:18 +0000
commit2e371183ee8c766d6d166f71060858e14d181220 (patch)
treeaef86bf9edc22d82d4727bdce2dc0c3e82ef1040
parent3f7626e9f2821ba084f3c31fddd9777ba7be6018 (diff)
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.
-rw-r--r--src/port/kill.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/port/kill.c b/src/port/kill.c
index ea71f75c3e..1ec5ee5b78 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