From 35c8d78ac50fac511ff8805a1aad34369a6abb86 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Wed, 25 Feb 2026 18:04:13 +0300
Subject: [PATCH v2 3/5] Use custom SLRU IO error msg for an asynchronous
 notification

---
 src/backend/commands/async.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index a347996b373..302f7c52a9f 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -569,6 +569,7 @@ bool		Trace_notify = false;
 int			max_notify_queue_pages = 1048576;
 
 /* local function prototypes */
+static inline char *asyncQueueIoErrorMsg(const void *opaque_data);
 static inline int64 asyncQueuePageDiff(int64 p, int64 q);
 static inline bool asyncQueuePagePrecedes(int64 p, int64 q);
 static inline void GlobalChannelKeyInit(GlobalChannelKey *key, Oid dboid,
@@ -609,6 +610,17 @@ static uint32 notification_hash(const void *key, Size keysize);
 static int	notification_match(const void *key1, const void *key2, Size keysize);
 static void ClearPendingActionsAndNotifies(void);
 
+static inline char *
+asyncQueueIoErrorMsg(const void *opaque_data)
+{
+	const QueuePosition *position = opaque_data;
+
+	Assert(position != NULL);
+
+	return psprintf("could not access status of async queue position (page=%" PRId64", offset=%d)",
+					position->page, position->offset);
+}
+
 /*
  * Compute the difference between two queue page numbers.
  * Previously this function accounted for a wraparound.
@@ -829,7 +841,7 @@ AsyncShmemInit(void)
 	 * names are used in order to avoid wraparound.
 	 */
 	NotifyCtl->PagePrecedes = asyncQueuePagePrecedes;
-	NotifyCtl->IoErrorMsg = TransactionIdIoErrorMsg;
+	NotifyCtl->IoErrorMsg = asyncQueueIoErrorMsg;
 	SimpleLruInit(NotifyCtl, "notify", notify_buffers, 0,
 				  "pg_notify", LWTRANCHE_NOTIFY_BUFFER, LWTRANCHE_NOTIFY_SLRU,
 				  SYNC_HANDLER_NONE, true);
@@ -2068,7 +2080,7 @@ asyncQueueAddEntries(ListCell *nextNotify)
 	if (QUEUE_POS_IS_ZERO(queue_head))
 		slotno = SimpleLruZeroPage(NotifyCtl, pageno);
 	else
-		slotno = SimpleLruReadPage(NotifyCtl, pageno, true, NULL);
+		slotno = SimpleLruReadPage(NotifyCtl, pageno, true, &queue_head);
 
 	/* Note we mark the page dirty before writing in it */
 	NotifyCtl->shared->page_dirty[slotno] = true;
@@ -2738,7 +2750,7 @@ asyncQueueProcessPageEntries(QueuePosition *current,
 	alignas(AsyncQueueEntry) char local_buf[QUEUE_PAGESIZE];
 	char	   *local_buf_end = local_buf;
 
-	slotno = SimpleLruReadPage_ReadOnly(NotifyCtl, curpage, NULL);
+	slotno = SimpleLruReadPage_ReadOnly(NotifyCtl, curpage, current);
 	page_buffer = NotifyCtl->shared->page_buffer[slotno];
 
 	do
@@ -2996,7 +3008,7 @@ AsyncNotifyFreezeXids(TransactionId newFrozenXid)
 
 			lock = SimpleLruGetBankLock(NotifyCtl, pageno);
 			LWLockAcquire(lock, LW_EXCLUSIVE);
-			slotno = SimpleLruReadPage(NotifyCtl, pageno, true, NULL);
+			slotno = SimpleLruReadPage(NotifyCtl, pageno, true, &pos);
 			page_buffer = NotifyCtl->shared->page_buffer[slotno];
 			curpage = pageno;
 		}
-- 
2.50.1 (Apple Git-155)

