On 2023-08-08 10:05, Michael Paquier wrote:
On Tue, Aug 08, 2023 at 09:39:02AM +0900, Masahiro Ikeda wrote:
I am thinking a bit that we also need another hash where the key
is a custom string. For extensions that have no dependencies
with shared_preload_libraries, I think we need to avoid that
WaitEventExtensionNew() is called repeatedly and a new eventId
is issued each time.

So, is it better to have another hash where the key is
a custom string and uniqueness is identified by it to determine
if a new eventId should be issued?

Yeah, I was also considering if something like that is really
necessary, but I cannot stop worrying about adding more contention to
the hash table lookup each time an extention needs to retrieve an
event ID to use for WaitLatch() or such.  The results of the hash
table lookups could be cached in each backend, still it creates an
extra cost when combined with queries running in parallel on
pg_stat_activity that do the opposite lookup event_id -> event_name.

My suggestion adds more load to AddinShmemInitLock instead.
Hence, I was just thinking about relying on AddinShmemInitLock to
insert new entries in the hash table, only if its shmem state is not
found when calling ShmemInitStruct().  Or perhaps it is just OK to not
care about the impact event_name -> event_id lookup for fresh
connections, and just bite the bullet with two lookup keys instead of
relying on AddinShmemInitLock for the addition of new entries in the
hash table?  Hmm, perhaps you're right with your approach here, at the
end.

For the first idea, I agree that if a lot of new connections come in,
it is easy to leads many conflicts. The only solution I can think of
is to use connection pooling now.

IIUC, the second idea is based on the premise of allocating their shared
memory for each extension. In that case, the cons of the first idea can
be solved because the wait event infos are saved in their shared memory and
they don't need call WaitEventExtensionNew() anymore. Is that right?

Regards,
--
Masahiro Ikeda
NTT DATA CORPORATION
From 0e3ccc6474bfcc51114d9363b7819b68f37fcad3 Mon Sep 17 00:00:00 2001
From: Masahiro Ikeda <mshr.ik...@ntt.com>
Date: Tue, 8 Aug 2023 19:24:32 +0900
Subject: [PATCH] Change to manage custom wait events in shared hash

Currently, names of the custom wait event must be
registered per backends. This patch relaxes the
constraints to store the wait events and their names
in the dynamic shared hashtable. So, all backends can
look up the wait event names on pg_stat_activity view
without additional processing by extensions.
---
 doc/src/sgml/monitoring.sgml                  |   7 +-
 doc/src/sgml/xfunc.sgml                       |  10 +-
 src/backend/storage/ipc/ipci.c                |   6 +
 src/backend/storage/lmgr/lwlock.c             |   2 +
 src/backend/utils/activity/wait_event.c       | 275 ++++++++++++------
 src/backend/utils/init/postinit.c             |   3 +
 src/include/storage/lwlock.h                  |   2 +
 src/include/utils/wait_event.h                |  17 +-
 .../modules/worker_spi/t/001_worker_spi.pl    |  18 +-
 src/test/modules/worker_spi/worker_spi.c      |   6 +-
 src/tools/pgindent/typedefs.list              |   2 +-
 11 files changed, 216 insertions(+), 132 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index f4fc5d814f..19181832d7 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1121,10 +1121,9 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
      <literal>LWLock</literal> types
      to the list shown in <xref linkend="wait-event-extension-table"/> and
      <xref linkend="wait-event-lwlock-table"/>. In some cases, the name
-     assigned by an extension will not be available in all server processes;
-     so an <literal>Extension</literal> or <literal>LWLock</literal> wait
-     event might be reported as just
-     <quote><literal>extension</literal></quote> rather than the
+     of <literal>LWLock</literal> assigned by an extension will not be
+     available in all server processes; so an wait event might be reported
+     as just <quote><literal>extension</literal></quote> rather than the
      extension-assigned name.
     </para>
    </note>
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index d6345a775b..7fec034db4 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -3470,17 +3470,13 @@ void RequestAddinShmemSpace(int size)
 </programlisting>
     </para>
     <para>
-     <literal>shmem_startup_hook</literal> can allocate in shared memory
+     <literal>shmem_startup_hook</literal> can allocate in dynamic shared memory
      custom wait events by calling while holding the LWLock
      <function>AddinShmemInitLock</function> to avoid any race conditions:
 <programlisting>
-uint32 WaitEventExtensionNew(void)
-</programlisting>
-     Next, each process needs to associate the wait event allocated previously
-     to a user-facing custom string, which is something done by calling:
-<programlisting>
-void WaitEventExtensionRegisterName(uint32 wait_event_info, const char *wait_event_name)
+uint32 WaitEventExtensionNew(const char *wait_event_name)
 </programlisting>
+     The wait event is associated to a user-facing custom string.
      An example can be found in <filename>src/test/modules/worker_spi</filename>
      in the PostgreSQL source tree.
     </para>
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 5551afffc0..b3d2a0b252 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -323,6 +323,12 @@ CreateSharedMemoryAndSemaphores(void)
 	 */
 	if (shmem_startup_hook)
 		shmem_startup_hook();
+
+	/*
+	 * Detach from the dynamic shared hash because postmaster will never
+	 * access these again
+	 */
+	WaitEventExtensionDetachShmem();
 }
 
 /*
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 315a78cda9..cf1bdbed85 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -190,6 +190,8 @@ static const char *const BuiltinTrancheNames[] = {
 	"LogicalRepLauncherDSA",
 	/* LWTRANCHE_LAUNCHER_HASH: */
 	"LogicalRepLauncherHash",
+	"LWTRANCHE_WAITEVENTEXTENSION_DSA",
+	"LWTRANCHE_WAITEVENTEXTENSION_HASH",
 };
 
 StaticAssertDecl(lengthof(BuiltinTrancheNames) ==
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index b3596ece80..dbdf681110 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -22,6 +22,7 @@
  */
 #include "postgres.h"
 
+#include "lib/dshash.h"
 #include "miscadmin.h"
 #include "port/pg_bitutils.h"
 #include "storage/lmgr.h"		/* for GetLockNameFromTagType */
@@ -45,141 +46,235 @@ uint32	   *my_wait_event_info = &local_my_wait_event_info;
 #define WAIT_EVENT_CLASS_MASK	0xFF000000
 #define WAIT_EVENT_ID_MASK		0x0000FFFF
 
-/* dynamic allocation counter for custom wait events in extensions */
-typedef struct WaitEventExtensionCounterData
+/* hash table entry for finding the custom wait event name for a key */
+#define MAX_WAIT_EVENT_EXTENSION_NAME		256
+typedef struct WaitEventExtensionNameEntry
 {
-	int			nextId;			/* next ID to assign */
-	slock_t		mutex;			/* protects the counter */
-} WaitEventExtensionCounterData;
+	uint16	event_id;	/* hash key */
+	uint32	status;		/* hash status */
+	char	wait_event_name[MAX_WAIT_EVENT_EXTENSION_NAME]; /* custom wait event name */
+} WaitEventExtensionNameEntry;
+
+/* for references to shared custom wait event entries */
+#define SH_PREFIX		wait_event_extension_name_hash
+#define SH_ELEMENT_TYPE	WaitEventExtensionNameEntry
+#define SH_KEY_TYPE		uint16
+#define	SH_KEY			event_id
+#define SH_HASH_KEY(tb, key)	dshash_memhash(&key, sizeof(uint16), NULL)
+#define SH_EQUAL(tb, a, b)		dshash_memcmp(&a, &b, sizeof(uint16), NULL) == 0
+#define	SH_SCOPE		static inline
+#define SH_DECLARE
+#define SH_DEFINE
+#include "lib/simplehash.h"
+
+/* parameter for the shared hash */
+static const dshash_parameters dsh_params = {
+	sizeof(uint16),
+	sizeof(WaitEventExtensionNameEntry),
+	dshash_memcmp,
+	dshash_memhash,
+	LWTRANCHE_WAITEVENTEXTENSION_HASH
+};
+
+/*
+ * Shared state information for custom wait events in extensions.
+ * This manages a dynamic shared hash and a dynamic allocation counter.
+ */
+typedef struct WaitEventExtensionSharedState
+{
+	/*
+	 * Custom wait event names are registered in shared custom wait event hash.
+	 * Other backends can look up them without additional processing per backend
+	 * like LWLockRegisterTranche().
+	 */
+	void		*raw_dsa_area;
+	dshash_table_handle hash_handle;
+
+	int			nextId;					/* next event ID to assign */
+	slock_t		mutex;					/* protects the counter */
+} WaitEventExtensionSharedState;
 
 /* pointer to the shared memory */
-static WaitEventExtensionCounterData *WaitEventExtensionCounter;
+static WaitEventExtensionSharedState *wee_state;
+
+/* backend-local state to manage dynamic shared hash */
+typedef struct WaitEventExtension_LocalState
+{
+	dsa_area   *dsa;
+	dshash_table *dsh;
+} WaitEventExtension_LocalState;
+
+static WaitEventExtension_LocalState wee_localstate;
 
 /* first event ID of custom wait events for extensions */
 #define NUM_BUILTIN_WAIT_EVENT_EXTENSION	\
 	(WAIT_EVENT_EXTENSION_FIRST_USER_DEFINED - WAIT_EVENT_EXTENSION)
 
+static const char *GetWaitEventExtensionIdentifier(uint16 eventId);
+
 /*
- * This is indexed by event ID minus NUM_BUILTIN_WAIT_EVENT_EXTENSION, and
- * stores the names of all dynamically-created event IDs known to the current
- * process.  Any unused entries in the array will contain NULL.
+ * The size of the shared memory allocation for custom wait events stored in
+ * the shared hash table. This allocation will be done as part of the main shared
+ * memory, rather than dynamic shared memory, allowing it to be initialized in
+ * postmaster.
  */
-static const char **WaitEventExtensionNames = NULL;
-static int	WaitEventExtensionNamesAllocated = 0;
+static Size
+wait_event_extension_dsa_init_size(void)
+{
+	Size		sz;
 
-static const char *GetWaitEventExtensionIdentifier(uint16 eventId);
+	/* Same size as pgstat_dsa_init_size() for dshash */
+	sz = 256 * 1024;
+	Assert(dsa_minimum_size() <= sz);
+	return MAXALIGN(sz);
+}
 
 /*
- *  Return the space for dynamic allocation counter.
+ *  Return the space for dynamic shared hash and dynamic allocation counter.
  */
 Size
 WaitEventExtensionShmemSize(void)
 {
-	return sizeof(WaitEventExtensionCounterData);
+	Size	sz;
+	sz = MAXALIGN(sizeof(WaitEventExtensionSharedState));
+	sz = add_size(sz, wait_event_extension_dsa_init_size());
+	return sz;
 }
 
 /*
- * Allocate shmem space for dynamic allocation counter.
+ * Allocate shmem space for dynamic shared hash and dynamic allocation counter.
  */
 void
 WaitEventExtensionShmemInit(void)
 {
 	bool		found;
 
-	WaitEventExtensionCounter = (WaitEventExtensionCounterData *)
-		ShmemInitStruct("WaitEventExtensionCounterData",
+	wee_state = (WaitEventExtensionSharedState *)
+		ShmemInitStruct("WaitEventExtensionSharedState",
 						WaitEventExtensionShmemSize(), &found);
 
 	if (!found)
 	{
+		char	*p = (char *) wee_state;
+
 		/* initialize the allocation counter and its spinlock. */
-		WaitEventExtensionCounter->nextId = NUM_BUILTIN_WAIT_EVENT_EXTENSION;
-		SpinLockInit(&WaitEventExtensionCounter->mutex);
+		wee_state->nextId = NUM_BUILTIN_WAIT_EVENT_EXTENSION;
+		SpinLockInit(&wee_state->mutex);
+
+		/* initialize dsa and dshash */
+		p += (MAXALIGN(sizeof(WaitEventExtensionSharedState)));
+		wee_state->raw_dsa_area = (void *) p;
+		p += MAXALIGN(wait_event_extension_dsa_init_size());
+		wee_localstate.dsa = dsa_create_in_place(wee_state->raw_dsa_area,
+								  wait_event_extension_dsa_init_size(),
+								  LWTRANCHE_WAITEVENTEXTENSION_DSA,
+								  0);
+		dsa_pin(wee_localstate.dsa);
+
+		/*
+		 * To ensure dshash is created in "plain" shared memory, temporarily
+		 * limit size of dsa to the initial size of the dsa.
+		 */
+		dsa_set_size_limit(wee_localstate.dsa, wait_event_extension_dsa_init_size());
+
+		/*
+		 * With the limit in place, create the dshash table. XXX: It'd be nice
+		 * if there were dshash_create_in_place().
+		 */
+		wee_localstate.dsh = dshash_create(wee_localstate.dsa, &dsh_params, 0);
+		wee_state->hash_handle = dshash_get_hash_table_handle(wee_localstate.dsh);
+
+		dsa_set_size_limit(wee_localstate.dsa, -1);
+
+		/*
+		 * Don't detach from a shared hash table because postmaster can access
+		 * these again via shmem_startup_hooks by extensions.
+		 */
+		Assert(wee_localstate.dsh != NULL);
 	}
 }
 
 /*
- * Allocate a new event ID and return the wait event.
+ * Detach from the dynamic shared hash.
  */
-uint32
-WaitEventExtensionNew(void)
+void
+WaitEventExtensionDetachShmem(void)
 {
-	uint16		eventId;
+	Assert(wee_localstate.dsa);
 
-	Assert(LWLockHeldByMeInMode(AddinShmemInitLock, LW_EXCLUSIVE));
+	dshash_detach(wee_localstate.dsh);
+	wee_localstate.dsh = NULL;
 
-	SpinLockAcquire(&WaitEventExtensionCounter->mutex);
+	dsa_detach(wee_localstate.dsa);
+	wee_localstate.dsa = NULL;
+}
 
-	if (WaitEventExtensionCounter->nextId > PG_UINT16_MAX)
-	{
-		SpinLockRelease(&WaitEventExtensionCounter->mutex);
-		ereport(ERROR,
-				errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				errmsg("too many wait events for extensions"));
-	}
+/*
+ * Attach the dynamic shared hash for backends. Called From BaseInit().
+ */
+void
+WaitEventExtensionAttachShmem(void)
+{
+	MemoryContext oldcontext;
 
-	eventId = WaitEventExtensionCounter->nextId++;
+	Assert(wee_localstate.dsa == NULL);
 
-	SpinLockRelease(&WaitEventExtensionCounter->mutex);
+	oldcontext = MemoryContextSwitchTo(TopMemoryContext);
 
-	return PG_WAIT_EXTENSION | eventId;
+	wee_localstate.dsa =
+			dsa_attach_in_place(wee_state->raw_dsa_area,
+								  NULL);
+	dsa_pin_mapping(wee_localstate.dsa);
+
+	wee_localstate.dsh =
+			dshash_attach(wee_localstate.dsa, &dsh_params,
+							wee_state->hash_handle, NULL);
+
+	MemoryContextSwitchTo(oldcontext);
 }
 
 /*
- * Register a dynamic wait event name for extension in the lookup table
- * of the current process.
- *
- * This routine will save a pointer to the wait event name passed as an argument,
- * so the name should be allocated in a backend-lifetime context
- * (shared memory, TopMemoryContext, static constant, or similar).
- *
- * The "wait_event_name" will be user-visible as a wait event name, so try to
- * use a name that fits the style for those.
+ * Allocate a new event ID and return the wait event info.
  */
-void
-WaitEventExtensionRegisterName(uint32 wait_event_info,
-							   const char *wait_event_name)
+uint32
+WaitEventExtensionNew(const char *wait_event_name)
 {
-	uint32		classId;
 	uint16		eventId;
+	bool		found;
+	WaitEventExtensionNameEntry	*entry;
 
-	classId = wait_event_info & WAIT_EVENT_CLASS_MASK;
-	eventId = wait_event_info & WAIT_EVENT_ID_MASK;
+	Assert(LWLockHeldByMeInMode(AddinShmemInitLock, LW_EXCLUSIVE));
+	Assert(wee_localstate.dsh != NULL);
 
-	/* Check the wait event class. */
-	if (classId != PG_WAIT_EXTENSION)
+	/* Check the limit of the length of the event name */
+	if (strlen(wait_event_name) >= MAX_WAIT_EVENT_EXTENSION_NAME)
 		ereport(ERROR,
-				errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				errmsg("invalid wait event class %u", classId));
-
-	/* This should only be called for user-defined wait event. */
-	if (eventId < NUM_BUILTIN_WAIT_EVENT_EXTENSION)
-		ereport(ERROR,
-				errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				errmsg("invalid wait event ID %u", eventId));
+				errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				errmsg("wait event name is too long"));
 
-	/* Convert to array index. */
-	eventId -= NUM_BUILTIN_WAIT_EVENT_EXTENSION;
+	/* Allocate a new event Id */
+	SpinLockAcquire(&wee_state->mutex);
 
-	/* If necessary, create or enlarge array. */
-	if (eventId >= WaitEventExtensionNamesAllocated)
+	if (wee_state->nextId > PG_UINT16_MAX)
 	{
-		uint32		newalloc;
-
-		newalloc = pg_nextpower2_32(Max(8, eventId + 1));
-
-		if (WaitEventExtensionNames == NULL)
-			WaitEventExtensionNames = (const char **)
-				MemoryContextAllocZero(TopMemoryContext,
-									   newalloc * sizeof(char *));
-		else
-			WaitEventExtensionNames =
-				repalloc0_array(WaitEventExtensionNames, const char *,
-								WaitEventExtensionNamesAllocated, newalloc);
-		WaitEventExtensionNamesAllocated = newalloc;
+		SpinLockRelease(&wee_state->mutex);
+		ereport(ERROR,
+				errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				errmsg("too many wait events for extensions"));
 	}
 
-	WaitEventExtensionNames[eventId] = wait_event_name;
+	eventId = wee_state->nextId++;
+
+	SpinLockRelease(&wee_state->mutex);
+
+	/* Register a new custom wait event in the shared hash */
+	entry = dshash_find_or_insert(wee_localstate.dsh,
+									&eventId, &found);
+	Assert(!found);
+	strlcpy(entry->wait_event_name, wait_event_name, sizeof(entry->wait_event_name));
+	dshash_release_lock(wee_localstate.dsh, entry);
+
+	return PG_WAIT_EXTENSION | eventId;
 }
 
 /*
@@ -188,23 +283,23 @@ WaitEventExtensionRegisterName(uint32 wait_event_info,
 static const char *
 GetWaitEventExtensionIdentifier(uint16 eventId)
 {
+	WaitEventExtensionNameEntry	*entry;
+
 	/* Built-in event? */
 	if (eventId < NUM_BUILTIN_WAIT_EVENT_EXTENSION)
 		return "Extension";
 
-	/*
-	 * It is a user-defined wait event, so look at WaitEventExtensionNames[].
-	 * However, it is possible that the name has never been registered by
-	 * calling WaitEventExtensionRegisterName() in the current process, in
-	 * which case give up and return "extension".
-	 */
-	eventId -= NUM_BUILTIN_WAIT_EVENT_EXTENSION;
-
-	if (eventId >= WaitEventExtensionNamesAllocated ||
-		WaitEventExtensionNames[eventId] == NULL)
-		return "extension";
+	/* It is a user-defined wait event, so look at the dynamic shared hash */
+	entry = dshash_find(wee_localstate.dsh,
+						&eventId,
+						false);
+	if (entry)
+		dshash_release_lock(wee_localstate.dsh, entry);
+	else
+		ereport(ERROR,
+				errmsg("could not find the name for custom wait event ID %u", eventId));
 
-	return WaitEventExtensionNames[eventId];
+	return entry->wait_event_name;
 }
 
 
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index f31b85c013..3dea5afd8f 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -671,6 +671,9 @@ BaseInit(void)
 	 * drop ephemeral slots, which in turn triggers stats reporting.
 	 */
 	ReplicationSlotInitialize();
+
+    /* Attach the dynamic shared hash for custom wait events */
+	WaitEventExtensionAttachShmem();
 }
 
 
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index d77410bdea..451c406e47 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -207,6 +207,8 @@ typedef enum BuiltinTrancheIds
 	LWTRANCHE_PGSTATS_DATA,
 	LWTRANCHE_LAUNCHER_DSA,
 	LWTRANCHE_LAUNCHER_HASH,
+	LWTRANCHE_WAITEVENTEXTENSION_DSA,
+	LWTRANCHE_WAITEVENTEXTENSION_HASH,
 	LWTRANCHE_FIRST_USER_DEFINED
 }			BuiltinTrancheIds;
 
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index aad8bc08fa..4c2aa25b78 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -44,12 +44,11 @@ extern PGDLLIMPORT uint32 *my_wait_event_info;
  * Use this category when the server process is waiting for some condition
  * defined by an extension module.
  *
- * Extensions can define their own wait events in this category.  First,
- * they should call WaitEventExtensionNew() to get one or more wait event
- * IDs that are allocated from a shared counter.  These can be used directly
- * with pgstat_report_wait_start() or equivalent.  Next, each individual
- * process should call WaitEventExtensionRegisterName() to associate a wait
- * event string to the number allocated previously.
+ * Extensions can define their own wait events in this category. They should
+ * call WaitEventExtensionNew() with a wait event string. It will get one wait
+ * event ID that is allocated from a shared counter, associate the string to
+ * the number in the shared dynamic hash and return the wait event info. It
+ * can be used directly with pgstat_report_wait_start() or equivalent.
  */
 typedef enum
 {
@@ -59,10 +58,10 @@ typedef enum
 
 extern void WaitEventExtensionShmemInit(void);
 extern Size WaitEventExtensionShmemSize(void);
+extern void WaitEventExtensionDetachShmem(void);
+extern void WaitEventExtensionAttachShmem(void);
 
-extern uint32 WaitEventExtensionNew(void);
-extern void WaitEventExtensionRegisterName(uint32 wait_event_info,
-										   const char *wait_event_name);
+extern uint32 WaitEventExtensionNew(const char *wait_event_name);
 
 /* ----------
  * pgstat_report_wait_start() -
diff --git a/src/test/modules/worker_spi/t/001_worker_spi.pl b/src/test/modules/worker_spi/t/001_worker_spi.pl
index c3e7f5fbe6..26b8a49bec 100644
--- a/src/test/modules/worker_spi/t/001_worker_spi.pl
+++ b/src/test/modules/worker_spi/t/001_worker_spi.pl
@@ -39,25 +39,11 @@ $node->poll_query_until('postgres',
 $result = $node->safe_psql('postgres', 'SELECT * FROM schema4.counted;');
 is($result, qq(total|1), 'dynamic bgworker correctly consumed tuple data');
 
-# Check the wait event used by the dynamic bgworker.  For a session without
-# the state in shared memory known, the default of "extension" is the value
-# waited on.
+# Check the wait event used by the dynamic bgworker.
 $result = $node->poll_query_until(
 	'postgres',
 	qq[SELECT wait_event FROM pg_stat_activity WHERE backend_type ~ 'worker_spi';],
-	'extension');
-is($result, 1, 'dynamic bgworker has reported "extension" as wait event');
-
-# If the shared memory state is loaded (here with worker_spi_init within
-# the same connection as the one querying pg_stat_activity), the wait
-# event is the custom one.
-# The expected result is a special pattern here with a newline coming from the
-# first query where the shared memory state is set.
-$result = $node->poll_query_until(
-	'postgres',
-	qq[SELECT worker_spi_init(); SELECT wait_event FROM pg_stat_activity WHERE backend_type ~ 'worker_spi';],
-	qq[
-worker_spi_main]);
+	qq[worker_spi_main]);
 is($result, 1,
 	'dynamic bgworker has reported "worker_spi_main" as wait event');
 
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index c4317351ce..90a762b5e4 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -124,14 +124,10 @@ worker_spi_shmem_init(void)
 
 	/* Define a new wait event */
 	if (!found)
-		wsstate->wait_event = WaitEventExtensionNew();
+		wsstate->wait_event = WaitEventExtensionNew("worker_spi_main");
 
 	LWLockRelease(AddinShmemInitLock);
 
-	/*
-	 * Register the wait event in the lookup table of the current process.
-	 */
-	WaitEventExtensionRegisterName(wsstate->wait_event, "worker_spi_main");
 	return;
 }
 
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 66823bc2a7..0809a28b8f 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -2991,7 +2991,7 @@ WaitEventActivity
 WaitEventBufferPin
 WaitEventClient
 WaitEventExtension
-WaitEventExtensionCounterData
+WaitEventExtensionSharedState
 WaitEventIO
 WaitEventIPC
 WaitEventSet
-- 
2.25.1

Reply via email to