diff --git a/src/port/kill.c b/src/port/kill.c index cc1429c0a58..80b4cdc5613 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.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)) + 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++) { - 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) - { - 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