Hi,
I updated the patches to handle the warning mentioned
by PostgreSQL Patch Tester, and removed unnecessary spaces.
Regards,
--
Masahiro Ikeda
NTT DATA CORPORATION
From 1bb78fa2cbe6b030cea7a570bec88bd4d68f314a Mon Sep 17 00:00:00 2001
From: Masahiro Ikeda <masahiro.ikeda...@hco.ntt.co.jp>
Date: Fri, 23 Jun 2023 17:38:38 +0900
Subject: [PATCH 2/2] Add test codes for custom wait events
---
src/test/modules/Makefile | 1 +
src/test/modules/meson.build | 1 +
.../test_custom_wait_events/.gitignore | 2 +
.../modules/test_custom_wait_events/Makefile | 23 +++
.../test_custom_wait_events/meson.build | 33 ++++
.../test_custom_wait_events/t/001_basic.pl | 34 ++++
.../test_custom_wait_events--1.0.sql | 14 ++
.../test_custom_wait_events.c | 182 ++++++++++++++++++
.../test_custom_wait_events.control | 3 +
9 files changed, 293 insertions(+)
create mode 100644 src/test/modules/test_custom_wait_events/.gitignore
create mode 100644 src/test/modules/test_custom_wait_events/Makefile
create mode 100644 src/test/modules/test_custom_wait_events/meson.build
create mode 100644 src/test/modules/test_custom_wait_events/t/001_basic.pl
create mode 100644 src/test/modules/test_custom_wait_events/test_custom_wait_events--1.0.sql
create mode 100644 src/test/modules/test_custom_wait_events/test_custom_wait_events.c
create mode 100644 src/test/modules/test_custom_wait_events/test_custom_wait_events.control
diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile
index 6331c976dc..84312b7e57 100644
--- a/src/test/modules/Makefile
+++ b/src/test/modules/Makefile
@@ -17,6 +17,7 @@ SUBDIRS = \
test_bloomfilter \
test_copy_callbacks \
test_custom_rmgrs \
+ test_custom_wait_events \
test_ddl_deparse \
test_extensions \
test_ginpostinglist \
diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build
index 17d369e378..83a1d8fd19 100644
--- a/src/test/modules/meson.build
+++ b/src/test/modules/meson.build
@@ -14,6 +14,7 @@ subdir('ssl_passphrase_callback')
subdir('test_bloomfilter')
subdir('test_copy_callbacks')
subdir('test_custom_rmgrs')
+subdir('test_custom_wait_events')
subdir('test_ddl_deparse')
subdir('test_extensions')
subdir('test_ginpostinglist')
diff --git a/src/test/modules/test_custom_wait_events/.gitignore b/src/test/modules/test_custom_wait_events/.gitignore
new file mode 100644
index 0000000000..716e17f5a2
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/.gitignore
@@ -0,0 +1,2 @@
+# Generated subdirectories
+/tmp_check/
diff --git a/src/test/modules/test_custom_wait_events/Makefile b/src/test/modules/test_custom_wait_events/Makefile
new file mode 100644
index 0000000000..dda365d523
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/Makefile
@@ -0,0 +1,23 @@
+# src/test/modules/test_custom_wait_events/Makefile
+
+MODULE_big = test_custom_wait_events
+OBJS = \
+ $(WIN32RES) \
+ test_custom_wait_events.o
+PGFILEDESC = "test_custom_wait_events - test custom wait events"
+
+EXTENSION = test_custom_wait_events
+DATA = test_custom_wait_events--1.0.sql
+
+TAP_TESTS = 1
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_custom_wait_events
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_custom_wait_events/meson.build b/src/test/modules/test_custom_wait_events/meson.build
new file mode 100644
index 0000000000..8ad073e577
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/meson.build
@@ -0,0 +1,33 @@
+# Copyright (c) PostgreSQL Global Development Group
+
+test_custom_wait_events = files(
+ 'test_custom_wait_events.c',
+)
+
+if host_system == 'windows'
+ test_custom_wait_events += rc_lib_gen.process(win32ver_rc, extra_args: [
+ '--NAME', 'test_custom_wait_events',
+ '--FILEDESC', 'test_custom_wait_events - test custom wait events',])
+endif
+
+test_custom_wait_events = shared_module('test_custom_wait_events',
+ test_custom_wait_events,
+ kwargs: pg_test_mod_args,
+)
+test_install_libs += test_custom_wait_events
+
+test_install_data += files(
+ 'test_custom_wait_events.control',
+ 'test_custom_wait_events--1.0.sql',
+)
+
+tests += {
+ 'name': 'test_custom_wait_events',
+ 'sd': meson.current_source_dir(),
+ 'bd': meson.current_build_dir(),
+ 'tap': {
+ 'tests': [
+ 't/001_basic.pl',
+ ],
+ },
+}
diff --git a/src/test/modules/test_custom_wait_events/t/001_basic.pl b/src/test/modules/test_custom_wait_events/t/001_basic.pl
new file mode 100644
index 0000000000..b43c82a713
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/t/001_basic.pl
@@ -0,0 +1,34 @@
+# Copyright (c) 2023, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+
+$node->init;
+$node->append_conf(
+ 'postgresql.conf',
+ "shared_preload_libraries = 'test_custom_wait_events'"
+);
+$node->start;
+
+# setup
+$node->safe_psql('postgres', 'CREATE EXTENSION test_custom_wait_events;');
+
+$node->safe_psql('postgres', 'SELECT wait_worker_launch();');
+
+ok($node->poll_query_until('postgres',
+ qq[SELECT
+ (SELECT count(*) FROM pg_stat_activity
+ WHERE backend_type = 'test_custom_wait_events'
+ AND wait_event_type = 'Extension'
+ AND wait_event = 'custom_wait_event'
+ ) > 0;])
+) or die "Timed out waiting the custom wait event to be showed up";
+
+$node->stop;
+done_testing();
\ No newline at end of file
diff --git a/src/test/modules/test_custom_wait_events/test_custom_wait_events--1.0.sql b/src/test/modules/test_custom_wait_events/test_custom_wait_events--1.0.sql
new file mode 100644
index 0000000000..1fc2130f84
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/test_custom_wait_events--1.0.sql
@@ -0,0 +1,14 @@
+/* src/test/modules/test_custom_wait_events/test_custom_wait_events--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION test_custom_wait_events" to load this file. \quit
+
+--
+-- wait_worker_launch()
+--
+-- Launch a background worker to wait forever with a custom wait event.
+--
+CREATE FUNCTION wait_worker_launch()
+RETURNS int
+AS 'MODULE_PATHNAME', 'wait_worker_launch'
+LANGUAGE C STRICT PARALLEL SAFE;
diff --git a/src/test/modules/test_custom_wait_events/test_custom_wait_events.c b/src/test/modules/test_custom_wait_events/test_custom_wait_events.c
new file mode 100644
index 0000000000..6a47665524
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/test_custom_wait_events.c
@@ -0,0 +1,182 @@
+/*--------------------------------------------------------------------------
+ *
+ * test_custom_wait_events.c
+ * Code for testing custom wait events
+ *
+ * This code initializes a custom wait event in shmem_request_hook() and
+ * provide a function to launch a background worker waiting forever
+ * with the custom wait event.
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/test/modules/test_custom_wait_events/test_custom_wait_events.c
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "miscadmin.h"
+#include "postmaster/bgworker.h"
+#include "postmaster/interrupt.h"
+#include "storage/ipc.h"
+#include "storage/latch.h"
+#include "storage/lwlock.h"
+#include "storage/proc.h"
+#include "storage/shmem.h"
+#include "tcop/utility.h"
+#include "utils/wait_event.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(wait_worker_launch);
+
+PGDLLEXPORT void worker_main(Datum main_arg);
+
+/* GUC variables */
+typedef struct state
+{
+ uint32 wait_event_info; /* a allocated wait event */
+} state;
+
+static shmem_request_hook_type prev_shmem_request_hook = NULL;
+static shmem_request_hook_type prev_shmem_startup_hook = NULL;
+
+static char * worker_database = "postgres"; /* connected by a background worker */
+static state * ss = NULL;
+
+static void shmem_request(void);
+static void shmem_startup(void);
+static Size memsize(void);
+
+void
+_PG_init(void)
+{
+ if (!process_shared_preload_libraries_in_progress)
+ return;
+
+ prev_shmem_request_hook = shmem_request_hook;
+ shmem_request_hook = shmem_request;
+ prev_shmem_startup_hook = shmem_startup_hook;
+ shmem_startup_hook = shmem_startup;
+}
+
+static void
+shmem_request(void)
+{
+ if (prev_shmem_request_hook)
+ prev_shmem_request_hook();
+
+ RequestAddinShmemSpace(memsize());
+}
+
+static Size
+memsize(void)
+{
+ return sizeof(state);
+}
+
+/*
+ * Allocate and register a new wait event.
+ *
+ * This routine allocate a wait event id when it's called first time.
+ * After that, the name of the wait event is associated with the id. It's
+ * registered in the lookup table of each processes dynamically.
+ */
+static void
+shmem_startup(void)
+{
+ bool found;
+
+ if (prev_shmem_startup_hook)
+ prev_shmem_startup_hook();
+
+ ss = NULL;
+
+ /* Create or attach to the shared memory state */
+ LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
+ ss = ShmemInitStruct("custom_wait_event",
+ sizeof(state),
+ &found);
+
+ /* Allocate a new wait event. */
+ if (!found)
+ ss->wait_event_info = ExtensionWaitEventNewTranche();
+
+ LWLockRelease(AddinShmemInitLock);
+
+ /*
+ * Register the wait event in the lookup table of the current process.
+ */
+ ExtensionWaitEventRegisterTranche(ss->wait_event_info, "custom_wait_event");
+
+ return;
+}
+
+/*
+ * Connect to the database and wait forever with the custom wait event
+ */
+void
+worker_main(Datum main_arg)
+{
+ pqsignal(SIGTERM, SignalHandlerForShutdownRequest);
+ BackgroundWorkerUnblockSignals();
+
+ /* Connect to our database to show up a wait event in pg_stat_activity */
+ BackgroundWorkerInitializeConnection(worker_database, NULL, 0);
+
+ /* Wait forever with the custom wait event */
+ while (!ShutdownRequestPending)
+ {
+ (void) WaitLatch(MyLatch,
+ WL_LATCH_SET | WL_EXIT_ON_PM_DEATH,
+ -1L,
+ ss->wait_event_info); /* the custom wait event */
+ ResetLatch(MyLatch);
+ }
+}
+
+/*
+ * Dynamically launch a background worker waiting forever
+ */
+Datum
+wait_worker_launch(PG_FUNCTION_ARGS)
+{
+ BackgroundWorker worker;
+ BackgroundWorkerHandle *handle;
+ BgwHandleStatus status;
+ pid_t pid;
+
+ memset(&worker, 0, sizeof(worker));
+ worker.bgw_flags = BGWORKER_SHMEM_ACCESS |
+ BGWORKER_BACKEND_DATABASE_CONNECTION;
+ worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
+ worker.bgw_restart_time = BGW_NEVER_RESTART;
+ sprintf(worker.bgw_function_name, "worker_main");
+ sprintf(worker.bgw_library_name, "test_custom_wait_events");
+ snprintf(worker.bgw_name, BGW_MAXLEN, "test_custom_wait_events worker");
+ snprintf(worker.bgw_type, BGW_MAXLEN, "test_custom_wait_events");
+ worker.bgw_notify_pid = MyProcPid;
+
+ if (!RegisterDynamicBackgroundWorker(&worker, &handle))
+ PG_RETURN_NULL();
+
+ status = WaitForBackgroundWorkerStartup(handle, &pid);
+
+ if (status == BGWH_STOPPED)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ errmsg("could not start background process"),
+ errhint("More details may be available in the server log.")));
+ if (status == BGWH_POSTMASTER_DIED)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ errmsg("cannot start background processes without postmaster"),
+ errhint("Kill all remaining database processes and restart the database.")));
+ Assert(status == BGWH_STARTED);
+
+ PG_RETURN_INT32(pid);
+}
diff --git a/src/test/modules/test_custom_wait_events/test_custom_wait_events.control b/src/test/modules/test_custom_wait_events/test_custom_wait_events.control
new file mode 100644
index 0000000000..8dd875a252
--- /dev/null
+++ b/src/test/modules/test_custom_wait_events/test_custom_wait_events.control
@@ -0,0 +1,3 @@
+comment = 'Test code for custom wait events'
+default_version = '1.0'
+module_pathname = '$libdir/test_custom_wait_events'
--
2.25.1
From 8cf1f026fc04633412f03ace94f24dd4692d7310 Mon Sep 17 00:00:00 2001
From: Masahiro Ikeda <masahiro.ikeda...@hco.ntt.co.jp>
Date: Fri, 16 Jun 2023 11:53:29 +0900
Subject: [PATCH 1/2] Support custom wait events for extensions.
To support custom wait events, it add 2 APIs to allocate
new wait events dynamically.
The APIs are
* ExtensionWaitEventNewTranche()
* ExtensionWaitEventRegisterTranche()
They similar to existing LWLockNewTrancheId() and
LWLockRegisterTranche().
First, extension calls ExtensionWaitEventNewTranche()
just once to obtain a new wait event tranche; The ID is
allocated from a shared counter. Next, each individual
process using the tranche should call
ExtensionWaitEventRegisterTranche() to associate that
wait event with a name.
---
src/backend/storage/ipc/ipci.c | 3 +
src/backend/storage/ipc/shmem.c | 3 +-
src/backend/utils/activity/wait_event.c | 138 +++++++++++++++++++++++-
src/include/utils/wait_event.h | 29 +++++
4 files changed, 171 insertions(+), 2 deletions(-)
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 8f1ded7338..ed05121fa3 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -49,6 +49,7 @@
#include "storage/spin.h"
#include "utils/guc.h"
#include "utils/snapmgr.h"
+#include "utils/wait_event.h"
/* GUCs */
int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
@@ -142,6 +143,7 @@ CalculateShmemSize(int *num_semaphores)
size = add_size(size, SyncScanShmemSize());
size = add_size(size, AsyncShmemSize());
size = add_size(size, StatsShmemSize());
+ size = add_size(size, WaitEventShmemSize());
#ifdef EXEC_BACKEND
size = add_size(size, ShmemBackendArraySize());
#endif
@@ -294,6 +296,7 @@ CreateSharedMemoryAndSemaphores(void)
SyncScanShmemInit();
AsyncShmemInit();
StatsShmemInit();
+ WaitEventShmemInit();
#ifdef EXEC_BACKEND
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index 5465fa1964..02c72ebbb1 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -85,7 +85,8 @@ static void *ShmemBase; /* start address of shared memory */
static void *ShmemEnd; /* end+1 address of shared memory */
-slock_t *ShmemLock; /* spinlock for shared memory and LWLock
+slock_t *ShmemLock; /* spinlock for shared memory, LWLock
+ * allocation, and named extension wait event
* allocation */
static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index 7940d64639..078bb221b8 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -22,11 +22,18 @@
*/
#include "postgres.h"
+#include "miscadmin.h"
+#include "port/pg_bitutils.h"
#include "storage/lmgr.h" /* for GetLockNameFromTagType */
#include "storage/lwlock.h" /* for GetLWLockIdentifier */
+#include "storage/spin.h"
+#include "utils/memutils.h"
#include "utils/wait_event.h"
+/* We use the ShmemLock spinlock to protect ExtensionWaitEventCounter */
+extern slock_t *ShmemLock;
+
static const char *pgstat_get_wait_activity(WaitEventActivity w);
static const char *pgstat_get_wait_client(WaitEventClient w);
static const char *pgstat_get_wait_ipc(WaitEventIPC w);
@@ -38,6 +45,23 @@ static uint32 local_my_wait_event_info;
uint32 *my_wait_event_info = &local_my_wait_event_info;
+/* dynamic allocation counter in shared memory */
+static uint16 *ExtensionWaitEventCounter;
+
+/* first event ID for named extension wait event tranche */
+#define NUM_BUILTIN_WAIT_EVENT_EXTENSION \
+ (WAIT_EVENT_EXTENSION_FIRST_USER_DEFINED - WAIT_EVENT_EXTENSION)
+
+/*
+ * This is indexed by event ID minus NUM_BUILTIN_WAIT_EVENT_EXTENSION, and
+ * stores the names of all dynamically-created event ID known to the current
+ * process. Any unused entries in the array will contain NULL.
+ */
+static const char **ExtensionWaitEventTrancheNames = NULL;
+static int ExtensionWaitEventTrancheNamesAllocated = 0;
+
+static const char *GetExtensionWaitEventIdentifier(uint16 eventId);
+
/*
* Configure wait event reporting to report wait events to *wait_event_info.
* *wait_event_info needs to be valid until pgstat_reset_wait_event_storage()
@@ -165,7 +189,7 @@ pgstat_get_wait_event(uint32 wait_event_info)
break;
}
case PG_WAIT_EXTENSION:
- event_name = "Extension";
+ event_name = GetExtensionWaitEventIdentifier(eventId);
break;
case PG_WAIT_IPC:
{
@@ -762,3 +786,115 @@ pgstat_get_wait_io(WaitEventIO w)
return event_name;
}
+
+/*
+ * Return the space for dynamic allocation counter.
+ */
+Size
+WaitEventShmemSize(void)
+{
+ return sizeof(*ExtensionWaitEventCounter);
+}
+
+/*
+ * Allocate shmem space for dynamic allocation counter.
+ */
+void
+WaitEventShmemInit(void)
+{
+ if (!IsUnderPostmaster)
+ {
+ Size space = WaitEventShmemSize();
+
+ /* Initialize the dynamic-allocation counter */
+ ExtensionWaitEventCounter = (uint16 *) ShmemAlloc(space);
+ *ExtensionWaitEventCounter = NUM_BUILTIN_WAIT_EVENT_EXTENSION;
+ }
+}
+
+/*
+ * Allocate a new event ID and return the wait event info.
+ */
+uint32
+ExtensionWaitEventNewTranche(void)
+{
+ uint16 eventId;
+
+ SpinLockAcquire(ShmemLock);
+ eventId = (*ExtensionWaitEventCounter)++;
+ SpinLockRelease(ShmemLock);
+
+ return PG_WAIT_EXTENSION | eventId;
+}
+
+/*
+ * Register a dynamic tranche name in the lookup table of the current process.
+ *
+ * This routine will save a pointer to the wait event tranche 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.
+ */
+void
+ExtensionWaitEventRegisterTranche(uint32 wait_event_info, const char *wait_event_name)
+{
+ uint16 eventId;
+
+ /* Check wait event class. */
+ Assert((wait_event_info & 0xFF000000) == PG_WAIT_EXTENSION);
+
+ eventId = wait_event_info & 0x0000FFFF;
+
+ /* This should only be called for user-defined tranches. */
+ if (eventId < NUM_BUILTIN_WAIT_EVENT_EXTENSION)
+ return;
+
+ /* Convert to array index. */
+ eventId -= NUM_BUILTIN_WAIT_EVENT_EXTENSION;
+
+ /* If necessary, create or enlarge array. */
+ if (eventId >= ExtensionWaitEventTrancheNamesAllocated)
+ {
+ int newalloc;
+
+ newalloc = pg_nextpower2_32(Max(8, eventId + 1));
+
+ if (ExtensionWaitEventTrancheNames == NULL)
+ ExtensionWaitEventTrancheNames = (const char **)
+ MemoryContextAllocZero(TopMemoryContext,
+ newalloc * sizeof(char *));
+ else
+ ExtensionWaitEventTrancheNames =
+ repalloc0_array(ExtensionWaitEventTrancheNames, const char *, ExtensionWaitEventTrancheNamesAllocated, newalloc);
+ ExtensionWaitEventTrancheNamesAllocated = newalloc;
+ }
+
+ ExtensionWaitEventTrancheNames[eventId] = wait_event_name;
+}
+
+/*
+ * Return the name of an Extension wait event ID.
+ */
+static const char *
+GetExtensionWaitEventIdentifier(uint16 eventId)
+{
+ /* Build-in tranche? */
+ if (eventId < NUM_BUILTIN_WAIT_EVENT_EXTENSION)
+ return "Extension";
+
+ /*
+ * It's an extension tranche, so look in ExtensionWaitEventTrancheNames[].
+ * However, it's possible that the tranche has never been registered by
+ * calling ExtensionWaitEventRegisterTranche() in the current process, in
+ * which case give up and return "Extension".
+ */
+ eventId -= NUM_BUILTIN_WAIT_EVENT_EXTENSION;
+
+ if (eventId >= ExtensionWaitEventTrancheNamesAllocated ||
+ ExtensionWaitEventTrancheNames[eventId] == NULL)
+ return "Extension";
+
+ return ExtensionWaitEventTrancheNames[eventId];
+}
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 518d3b0a1f..9507c4fd71 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -70,6 +70,35 @@ typedef enum
WAIT_EVENT_WAL_SENDER_WRITE_DATA,
} WaitEventClient;
+/* ----------
+ * Wait Events - Extension
+ *
+ * Use this category when the server process is waiting for some condition
+ * defined by an extension module.
+ *
+ * Extensions can define custom wait events. First, call
+ * ExtensionWaitEventNewTranche() just once to obtain a new wait event tranche.
+ * The ID is allocated from a shared counter. Next, each individual process using
+ * the tranche should call ExtensionWaitEventRegisterTranche() to associate
+ * that wait event with a name.
+ *
+ * It may seem strange that each process using the tranche must register it
+ * separately, but dynamic shared memory segments aren't guaranteed to be
+ * mapped at the same address in all coordinating backends, so storing the
+ * registration in the main shared memory segment wouldn't work for that case.
+ */
+typedef enum
+{
+ WAIT_EVENT_EXTENSION = PG_WAIT_EXTENSION,
+ WAIT_EVENT_EXTENSION_FIRST_USER_DEFINED
+} WaitEventExtension;
+
+extern void WaitEventShmemInit(void);
+extern Size WaitEventShmemSize(void);
+
+extern uint32 ExtensionWaitEventNewTranche(void);
+extern void ExtensionWaitEventRegisterTranche(uint32 wait_event_info, const char *tranche_name);
+
/* ----------
* Wait Events - IPC
*
--
2.25.1