*** pgsql/src/port/kill.c 2009/01/01 17:24:04 1.11 --- pgsql/src/port/kill.c 2009/02/15 13:58:18 1.12 *************** *** 9,15 **** * signals that the backend can recognize. * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/port/kill.c,v 1.10 2008/01/01 19:46:00 momjian Exp $ * *------------------------------------------------------------------------- */ --- 9,15 ---- * signals that the backend can recognize. * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/port/kill.c,v 1.11 2009/01/01 17:24:04 momjian Exp $ * *------------------------------------------------------------------------- */ *************** pgkill(int pid, int sig) *** 25,30 **** --- 25,31 ---- 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) *************** pgkill(int pid, int sig) *** 39,61 **** 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) { ! errno = ESRCH; ! return -1; } ! return 0; } #endif --- 40,72 ---- return -1; } 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 (CallNamedPipe(pipename, &sigData, 1, &sigRet, 1, &bytes, 1000)) ! { ! if (bytes != 1 || sigRet != sig) ! { ! errno = ESRCH; ! return -1; ! } ! return 0; ! } } ! if (GetLastError() == ERROR_FILE_NOT_FOUND) ! errno = ESRCH; ! else if (GetLastError() == ERROR_ACCESS_DENIED) ! errno = EPERM; ! else ! errno = EINVAL; ! return -1; } #endif