From 2ce08465c5dcaf131fefc543d8a55fca25798e13 Mon Sep 17 00:00:00 2001
From: Sagar Shedge <sagar.shedge92@gmail.com>
Date: Tue, 25 Aug 2026 17:53:30 +0530
Subject: [PATCH] Report specific wait events for libpq cancel requests

libpqsrv_cancel() previously always reported the generic PG_WAIT_CLIENT
wait event while waiting for a cancel request to be acknowledged by the
remote server, regardless of which caller invoked it.  Add a
wait_event_info parameter so each caller can report a wait event
specific to its own operation, matching the pattern already used for
connection and query-result waits.

postgres_fdw now reports PostgresFdwCancel, and dblink now reports
DblinkCancel, both allocated lazily via WaitEventExtensionNew() like
their sibling wait events for connect/get-result.  Document the new
wait events in postgres-fdw.sgml and dblink.sgml.
---
 contrib/dblink/dblink.c                 |  8 +++++++-
 contrib/postgres_fdw/connection.c       | 10 ++++++++--
 doc/src/sgml/dblink.sgml                |  9 +++++++++
 doc/src/sgml/postgres-fdw.sgml          |  9 +++++++++
 src/include/libpq/libpq-be-fe-helpers.h |  7 ++++---
 5 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 9613f881985..a8462a257e9 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -145,6 +145,7 @@ static remoteConn *pconn = NULL;
 static HTAB *remoteConnHash = NULL;
 
 /* custom wait event values, retrieved from shared memory */
+static uint32 dblink_we_cancel = 0;
 static uint32 dblink_we_connect = 0;
 static uint32 dblink_we_get_conn = 0;
 static uint32 dblink_we_get_result = 0;
@@ -1350,7 +1351,12 @@ dblink_cancel_query(PG_FUNCTION_ARGS)
 	conn = dblink_get_named_conn(text_to_cstring(PG_GETARG_TEXT_PP(0)));
 	endtime = TimestampTzPlusMilliseconds(GetCurrentTimestamp(),
 										  30000);
-	msg = libpqsrv_cancel(conn, endtime);
+
+	/* first time, allocate or get the custom wait event */
+	if (dblink_we_cancel == 0)
+		dblink_we_cancel = WaitEventExtensionNew("DblinkCancel");
+
+	msg = libpqsrv_cancel(conn, endtime, dblink_we_cancel);
 	if (msg == NULL)
 		msg = "OK";
 
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index b5d4cf3dccc..1872414ee34 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -95,6 +95,7 @@ static int	read_only_level = 0;
 
 /* custom wait event values, retrieved from shared memory */
 static uint32 pgfdw_we_cleanup_result = 0;
+static uint32 pgfdw_we_cancel = 0;
 static uint32 pgfdw_we_connect = 0;
 static uint32 pgfdw_we_get_result = 0;
 
@@ -1606,7 +1607,12 @@ pgfdw_cancel_query(PGconn *conn)
 static bool
 pgfdw_cancel_query_begin(PGconn *conn, TimestampTz endtime)
 {
-	const char *errormsg = libpqsrv_cancel(conn, endtime);
+	const char *errormsg;
+
+	if (pgfdw_we_cancel == 0)
+		pgfdw_we_cancel = WaitEventExtensionNew("PostgresFdwCancel");
+
+	errormsg = libpqsrv_cancel(conn, endtime, pgfdw_we_cancel);
 
 	if (errormsg != NULL)
 		ereport(WARNING,
@@ -1802,7 +1808,7 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime,
 			if (now >= retrycanceltime)
 			{
 				/* We ignore failure to issue the repeated request. */
-				(void) libpqsrv_cancel(conn, endtime);
+				(void) libpqsrv_cancel(conn, endtime, pgfdw_we_cancel);
 
 				/* Recompute "now" in case that took measurable time. */
 				now = GetCurrentTimestamp();
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
index fc496b74288..d2b34b94bde 100644
--- a/doc/src/sgml/dblink.sgml
+++ b/doc/src/sgml/dblink.sgml
@@ -19,6 +19,15 @@
  </para>
 
  <variablelist>
+  <varlistentry>
+   <term><literal>DblinkCancel</literal></term>
+   <listitem>
+    <para>
+     Waiting for a remote server to acknowledge a query cancellation request.
+    </para>
+   </listitem>
+  </varlistentry>
+
   <varlistentry>
    <term><literal>DblinkConnect</literal></term>
    <listitem>
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
index 87b1433aacb..fa265335cc2 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -1319,6 +1319,15 @@ CREATE SUBSCRIPTION my_subscription SERVER subscription_server PUBLICATION testp
   </para>
 
   <variablelist>
+   <varlistentry>
+    <term><literal>PostgresFdwCancel</literal></term>
+    <listitem>
+     <para>
+      Waiting for a remote server to acknowledge a query cancellation request.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><literal>PostgresFdwCleanupResult</literal></term>
     <listitem>
diff --git a/src/include/libpq/libpq-be-fe-helpers.h b/src/include/libpq/libpq-be-fe-helpers.h
index cff68cd1c37..d520db741a0 100644
--- a/src/include/libpq/libpq-be-fe-helpers.h
+++ b/src/include/libpq/libpq-be-fe-helpers.h
@@ -379,7 +379,8 @@ libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
 
 /*
  * Submit a cancel request to the given connection, waiting only until
- * the given time.
+ * the given time.  wait_event_info identifies the wait event to report while
+ * waiting for the server.
  *
  * We sleep interruptibly until we receive confirmation that the cancel
  * request has been accepted, and if it is, return NULL; if the cancel
@@ -393,7 +394,7 @@ libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
  * libpq errors.  Make sure to call it in a transient memory context.
  */
 static inline const char *
-libpqsrv_cancel(PGconn *conn, TimestampTz endtime)
+libpqsrv_cancel(PGconn *conn, TimestampTz endtime, uint32 wait_event_info)
 {
 	PGcancelConn *cancel_conn;
 	const char *error = NULL;
@@ -447,7 +448,7 @@ libpqsrv_cancel(PGconn *conn, TimestampTz endtime)
 
 			/* Sleep until there's something to do */
 			WaitLatchOrSocket(MyLatch, waitEvents, PQcancelSocket(cancel_conn),
-							  cur_timeout, PG_WAIT_CLIENT);
+							  cur_timeout, wait_event_info);
 
 			ResetLatch(MyLatch);
 
-- 
2.50.1 (Apple Git-155)

