|
142 | 142 | #include "miscadmin.h"
|
143 | 143 | #include "storage/ipc.h"
|
144 | 144 | #include "storage/lmgr.h"
|
| 145 | +#include "storage/proc.h" |
145 | 146 | #include "storage/procsignal.h"
|
146 | 147 | #include "tcop/tcopprot.h"
|
147 | 148 | #include "utils/builtins.h"
|
@@ -1719,13 +1720,25 @@ SignalBackends(void)
|
1719 | 1720 | else
|
1720 | 1721 | {
|
1721 | 1722 | /*
|
1722 |
| - * Note: assuming things aren't broken, a signal failure here could |
1723 |
| - * only occur if the target backend exited since we released |
1724 |
| - * NotifyQueueLock; which is unlikely but certainly possible. So we |
1725 |
| - * just log a low-level debug message if it happens. |
| 1723 | + * Get the target backend's PGPROC and set its latch. |
| 1724 | + * |
| 1725 | + * Note: The target backend might exit after we released |
| 1726 | + * NotifyQueueLock but before we set the latch. We need to |
| 1727 | + * handle the race condition where the PGPROC slot might be |
| 1728 | + * recycled by a new process with a different PID. |
1726 | 1729 | */
|
1727 |
| - if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, procno) < 0) |
1728 |
| - elog(DEBUG3, "could not signal backend with PID %d: %m", pid); |
| 1730 | + PGPROC *proc = GetPGProcByNumber(procno); |
| 1731 | + |
| 1732 | + /* Verify the PID hasn't changed (backend hasn't exited) */ |
| 1733 | + if (proc->pid == pid) |
| 1734 | + { |
| 1735 | + SetLatch(&proc->procLatch); |
| 1736 | + } |
| 1737 | + else |
| 1738 | + { |
| 1739 | + /* Backend exited and slot was recycled */ |
| 1740 | + elog(DEBUG3, "could not signal backend with PID %d: process no longer exists", pid); |
| 1741 | + } |
1729 | 1742 | }
|
1730 | 1743 | }
|
1731 | 1744 | }
|
|
0 commit comments