Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uyu7i-00EIfg-Rv for pgsql-hackers@arkaria.postgresql.org; Wed, 17 Sep 2025 15:31:11 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uyu7g-008d7v-Ou for pgsql-hackers@arkaria.postgresql.org; Wed, 17 Sep 2025 15:31:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uyu7g-008d7n-E5 for pgsql-hackers@lists.postgresql.org; Wed, 17 Sep 2025 15:31:09 +0000 Received: from mail-io1-xd30.google.com ([2607:f8b0:4864:20::d30]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uyu7b-001LJV-0i for pgsql-hackers@postgresql.org; Wed, 17 Sep 2025 15:31:08 +0000 Received: by mail-io1-xd30.google.com with SMTP id ca18e2360f4ac-889b60cc6feso510077739f.2 for ; Wed, 17 Sep 2025 08:31:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1758123062; x=1758727862; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=vs7Q03hyzjdrF/vqrcB+WVs+VaArLovF3XrEAmEaT+w=; b=AgoN20fAWJYVdGDsCH5jDIL5Cea0nL7wrPysKvyinAhdxW4insz/k8roLzbWaqLnZ+ b901cp03TQyKLTfDJJE0IgQbZW72JVkTuZI3/ppF7p6hxa5F82KSxC6JqsckBRkQdjKB beExFaVGsW9fQWPYA+QnI60cwTeY+fWa6Rkmd+gH0PwHJSnXV8DOl7cyUPnx3N52QN3c A0NeQrL6Ql3YqklRJi9dX7iLW+X7W9XMwwXnPQVd5b9f8JED+vKK+0M5Dho42vEkVi3G NxK/677tlmtCw6bqio/lTKEj/aQaZpdBu7yN3Qs4fpYapA4fAryFrGfBlZq0TQzVBfD1 NA4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758123062; x=1758727862; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=vs7Q03hyzjdrF/vqrcB+WVs+VaArLovF3XrEAmEaT+w=; b=YGOMNrI7qSSzIriYCRzyVPcvPqTkylJaWL/0p+f2AXXNOZ5fUQJNsKa68zYmh/FMB4 OkU/9Wc4wQYdqUAu9QkgiW3zlQDZO3de4XHLm4kXCM498oN84S6EuAtY4go7TmCVY2mW woaSX+aTY915hFDhjKQxTT1s5NhghzaCy8m4WVXHdMpoqakm0wrp7r8URO9FyODvRPVE XAcr15v2tinsTPS6gm5H+CF6s0VLbbU4zgFGlfN/Nv8zGfexWf8ByoqjSOT4iJVkQkcM yJBWAVFG6gscO4iAbMv27eMvy5hvSABUFbROAB+bzpX9njHwyVwYO1awZ4PNrKs5XPpr T0Lw== X-Gm-Message-State: AOJu0YwuY/f2KqG9UIDIoCuMNQF7bnL6xs8mMNkotth5Yi0T8bx87dB/ MI9d/b10tusiIxc9PSRtc+lP6bfiwcNbbMoV688fYY6VTVppW9GqdLE5 X-Gm-Gg: ASbGncuTX820jbRdd14chT0nX+EK9LsQ3XLfuK9gYsT5fqtg494r4qR2Qq5iQSjSMhl F6gxMEJ7b+VPkV9LHVW/7wmwox+yDe6Za1VyHqnsr/3aMjoGwFTO+SPYiEUOZecEHTFJJBk7YiA A+9MhnuepMdGKhxujuP0HF72i3NAJcYTRFRGoADGyRGY/kT1hupUZHLjUUOki6V5VqY1MCvMwe6 cpm4rlOtnSL+KmQ+mYSdp3FXR1WVhvtnd6WAGNwtFQOh4KxOKfJtngg3RMKZ/OrQh4xKFvuVkCh D2bdQxFEoAwO9k1TDs8QAc3wzp65BNO6pMEItu1eFygs2ZhZOa9BajfmXgJ+ByLb1pnQIOA4lni cM9Y+5ZDyJnzIhCC5c1AKGB58TcyvllyyaeFcBSDaH3Y2tYTayIbFlOZoFIinM99Wumxg2WQDYe GHiFsQcx7ZQKFF X-Google-Smtp-Source: AGHT+IHLkasHXO+0KzhJY9KG/1OsEyplQsoiMStBhCWTl5th5moZwOC5yFkX8styjca9sM8ArI4O5A== X-Received: by 2002:a5d:85da:0:b0:894:77e6:4698 with SMTP id ca18e2360f4ac-89d27ed7318mr310119239f.15.1758123062481; Wed, 17 Sep 2025 08:31:02 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id ca18e2360f4ac-8949b5f911fsm194946239f.6.2025.09.17.08.31.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Sep 2025 08:31:01 -0700 (PDT) Date: Wed, 17 Sep 2025 10:31:00 -0500 From: Nathan Bossart To: Sami Imseih Cc: pgsql-hackers Subject: Re: GetNamedLWLockTranche crashes on Windows in normal backend Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="hTu8Qy/GtaDsumby" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --hTu8Qy/GtaDsumby Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Sep 16, 2025 at 04:04:39PM -0500, Sami Imseih wrote: > startup tranches should be: > > #define NUM_STARTUP_TRANCHES (2) > > instead of: > > #define NUM_STARTUP_TRANCHES (256 - 2) Why? > I do think we should add tests for LWLockInitialize to test error for > an unregistered tranche. I added an initialization test. -- nathan --hTu8Qy/GtaDsumby Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v7-0001-test_lwlock_tranches.patch From 7fd394355c0ee19d00247a95554040ae35c4cacb Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 16 Sep 2025 10:15:11 -0500 Subject: [PATCH v7] 1/1] test_lwlock_tranches --- src/test/modules/Makefile | 1 + src/test/modules/meson.build | 1 + .../modules/test_lwlock_tranches/.gitignore | 4 + .../modules/test_lwlock_tranches/Makefile | 25 ++++ .../expected/test_lwlock_tranches.out | 32 +++++ .../modules/test_lwlock_tranches/meson.build | 35 ++++++ .../sql/test_lwlock_tranches.sql | 15 +++ .../test_lwlock_tranches--1.0.sql | 16 +++ .../test_lwlock_tranches.c | 110 ++++++++++++++++++ .../test_lwlock_tranches.conf | 1 + .../test_lwlock_tranches.control | 4 + 11 files changed, 244 insertions(+) create mode 100644 src/test/modules/test_lwlock_tranches/.gitignore create mode 100644 src/test/modules/test_lwlock_tranches/Makefile create mode 100644 src/test/modules/test_lwlock_tranches/expected/test_lwlock_tranches.out create mode 100644 src/test/modules/test_lwlock_tranches/meson.build create mode 100644 src/test/modules/test_lwlock_tranches/sql/test_lwlock_tranches.sql create mode 100644 src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql create mode 100644 src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c create mode 100644 src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf create mode 100644 src/test/modules/test_lwlock_tranches/test_lwlock_tranches.control diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 903a8ac151a..8a3cd2afab7 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -29,6 +29,7 @@ SUBDIRS = \ test_integerset \ test_json_parser \ test_lfind \ + test_lwlock_tranches \ test_misc \ test_oat_hooks \ test_parser \ diff --git a/src/test/modules/meson.build b/src/test/modules/meson.build index 93be0f57289..717e85066ba 100644 --- a/src/test/modules/meson.build +++ b/src/test/modules/meson.build @@ -28,6 +28,7 @@ subdir('test_int128') subdir('test_integerset') subdir('test_json_parser') subdir('test_lfind') +subdir('test_lwlock_tranches') subdir('test_misc') subdir('test_oat_hooks') subdir('test_parser') diff --git a/src/test/modules/test_lwlock_tranches/.gitignore b/src/test/modules/test_lwlock_tranches/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/test_lwlock_tranches/Makefile b/src/test/modules/test_lwlock_tranches/Makefile new file mode 100644 index 00000000000..e357b7d6d66 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/Makefile @@ -0,0 +1,25 @@ +# src/test/modules/test_lwlock_tranches/Makefile + +MODULE_big = test_lwlock_tranches +OBJS = \ + $(WIN32RES) \ + test_lwlock_tranches.o +PGFILEDESC = "test_lwlock_tranches - test code for LWLock tranches allocated by extensions" + +EXTENSION = test_lwlock_tranches +DATA = test_lwlock_tranches--1.0.sql + +REGRESS_OPTS = --temp-config $(top_srcdir)/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf +REGRESS = test_lwlock_tranches +NO_INSTALLCHECK = 1 + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_lwlock_tranches +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_lwlock_tranches/expected/test_lwlock_tranches.out b/src/test/modules/test_lwlock_tranches/expected/test_lwlock_tranches.out new file mode 100644 index 00000000000..38c227b5bc3 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/expected/test_lwlock_tranches.out @@ -0,0 +1,32 @@ +CREATE EXTENSION test_lwlock_tranches; +\c +SELECT test_lwlock_tranches(); + test_lwlock_tranches +---------------------- + +(1 row) + +\c +SELECT test_lwlock_tranche_creation(NULL); +ERROR: tranche name cannot be NULL +\c +SELECT test_lwlock_tranche_creation(repeat('a', 64)); +ERROR: tranche name too long +DETAIL: LWLock tranche names must be no longer than 63 bytes. +\c +SELECT test_lwlock_tranche_creation('test'); +ERROR: maximum number of tranches already registered +DETAIL: No more than 256 tranches may be registered. +\c +SELECT test_lwlock_tranche_lookup('test_lwlock_tranches_startup'); + test_lwlock_tranche_lookup +---------------------------- + +(1 row) + +\c +SELECT test_lwlock_tranche_lookup('bogus'); +ERROR: requested tranche is not registered +\c +SELECT test_lwlock_initialize(65535); +ERROR: tranche 65535 is not registered diff --git a/src/test/modules/test_lwlock_tranches/meson.build b/src/test/modules/test_lwlock_tranches/meson.build new file mode 100644 index 00000000000..755c2b72267 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/meson.build @@ -0,0 +1,35 @@ +# Copyright (c) 2025, PostgreSQL Global Development Group + +test_lwlock_tranches_sources = files( + 'test_lwlock_tranches.c', +) + +if host_system == 'windows' + test_lwlock_tranches_sources += rc_lib_gen.process(win32ver_rc, extra_args: [ + '--NAME', 'test_lwlock_tranches', + '--FILEDESC', 'test_lwlock_tranches - test code for LWLock tranches allocated by extensions',]) +endif + +test_lwlock_tranches = shared_module('test_lwlock_tranches', + test_lwlock_tranches_sources, + kwargs: pg_test_mod_args, +) +test_install_libs += test_lwlock_tranches + +test_install_data += files( + 'test_lwlock_tranches.control', + 'test_lwlock_tranches--1.0.sql', +) + +tests += { + 'name': 'test_lwlock_tranches', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'regress': { + 'sql': [ + 'test_lwlock_tranches', + ], + 'regress_args': ['--temp-config', files('test_lwlock_tranches.conf')], + 'runningcheck': false, + }, +} diff --git a/src/test/modules/test_lwlock_tranches/sql/test_lwlock_tranches.sql b/src/test/modules/test_lwlock_tranches/sql/test_lwlock_tranches.sql new file mode 100644 index 00000000000..18845343ebc --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/sql/test_lwlock_tranches.sql @@ -0,0 +1,15 @@ +CREATE EXTENSION test_lwlock_tranches; +\c +SELECT test_lwlock_tranches(); +\c +SELECT test_lwlock_tranche_creation(NULL); +\c +SELECT test_lwlock_tranche_creation(repeat('a', 64)); +\c +SELECT test_lwlock_tranche_creation('test'); +\c +SELECT test_lwlock_tranche_lookup('test_lwlock_tranches_startup'); +\c +SELECT test_lwlock_tranche_lookup('bogus'); +\c +SELECT test_lwlock_initialize(65535); diff --git a/src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql new file mode 100644 index 00000000000..34821981521 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql @@ -0,0 +1,16 @@ +/* src/test/modules/test_lwlock_tranches/test_lwlock_tranches--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_lwlock_tranches" to load this file. \quit + +CREATE FUNCTION test_lwlock_tranches() RETURNS VOID + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION test_lwlock_tranche_creation(tranche_name TEXT) RETURNS VOID + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION test_lwlock_tranche_lookup(tranche_name TEXT) RETURNS VOID + AS 'MODULE_PATHNAME' LANGUAGE C; + +CREATE FUNCTION test_lwlock_initialize(tranche_id INT) RETURNS VOID + AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c new file mode 100644 index 00000000000..a52525b5b1e --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c @@ -0,0 +1,110 @@ +/*-------------------------------------------------------------------------- + * + * test_lwlock_tranches.c + * Test code for LWLock tranches allocated by extensions. + * + * Copyright (c) 2025, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_lwlock_tranches/test_lwlock_tranches.c + * + * ------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "fmgr.h" +#include "miscadmin.h" +#include "storage/lwlock.h" +#include "utils/builtins.h" +#include "utils/wait_classes.h" + +PG_MODULE_MAGIC; + +#define STARTUP_TRANCHE_NAME "test_lwlock_tranches_startup" +#define DYNAMIC_TRANCHE_NAME "test_lwlock_tranches_dynamic" + +#define NUM_STARTUP_TRANCHES (256 - 2) +#define NUM_DYNAMIC_TRANCHES (256 - NUM_STARTUP_TRANCHES) + +#define GET_TRANCHE_NAME(a) GetLWLockIdentifier(PG_WAIT_LWLOCK, (a)) + +static shmem_request_hook_type prev_shmem_request_hook; +static void test_lwlock_tranches_shmem_request(void); + +void +_PG_init(void) +{ + prev_shmem_request_hook = shmem_request_hook; + shmem_request_hook = test_lwlock_tranches_shmem_request; +} + +static void +test_lwlock_tranches_shmem_request(void) +{ + if (prev_shmem_request_hook) + prev_shmem_request_hook(); + + for (int i = 0; i < NUM_STARTUP_TRANCHES; i++) + RequestNamedLWLockTranche(STARTUP_TRANCHE_NAME, 1); +} + +PG_FUNCTION_INFO_V1(test_lwlock_tranches); +Datum +test_lwlock_tranches(PG_FUNCTION_ARGS) +{ + int dynamic_tranches[NUM_DYNAMIC_TRANCHES]; + + for (int i = 0; i < NUM_DYNAMIC_TRANCHES; i++) + dynamic_tranches[i] = LWLockNewTrancheId(DYNAMIC_TRANCHE_NAME); + + for (int i = 0; i < NUM_STARTUP_TRANCHES; i++) + { + if (strcmp(GET_TRANCHE_NAME(LWTRANCHE_FIRST_USER_DEFINED + i), + STARTUP_TRANCHE_NAME) != 0) + elog(ERROR, "incorrect startup lock tranche name"); + } + + for (int i = 0; i < NUM_DYNAMIC_TRANCHES; i++) + { + if (strcmp(GET_TRANCHE_NAME(dynamic_tranches[i]), + DYNAMIC_TRANCHE_NAME) != 0) + elog(ERROR, "incorrect dynamic lock tranche name"); + } + + PG_RETURN_VOID(); +} + +PG_FUNCTION_INFO_V1(test_lwlock_tranche_creation); +Datum +test_lwlock_tranche_creation(PG_FUNCTION_ARGS) +{ + char *tranche_name = PG_ARGISNULL(0) ? NULL : TextDatumGetCString(PG_GETARG_DATUM(0)); + + (void) LWLockNewTrancheId(tranche_name); + + PG_RETURN_VOID(); +} + +PG_FUNCTION_INFO_V1(test_lwlock_tranche_lookup); +Datum +test_lwlock_tranche_lookup(PG_FUNCTION_ARGS) +{ + char *tranche_name = TextDatumGetCString(PG_GETARG_DATUM(0)); + + (void) GetNamedLWLockTranche(tranche_name); + + PG_RETURN_VOID(); +} + +PG_FUNCTION_INFO_V1(test_lwlock_initialize); +Datum +test_lwlock_initialize(PG_FUNCTION_ARGS) +{ + int tranche_id = PG_GETARG_INT32(0); + LWLock lock; + + LWLockInitialize(&lock, tranche_id); + + PG_RETURN_VOID(); +} diff --git a/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf new file mode 100644 index 00000000000..acbe5bf51c3 --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.conf @@ -0,0 +1 @@ +shared_preload_libraries = 'test_lwlock_tranches' diff --git a/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.control b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.control new file mode 100644 index 00000000000..1cde04bdc0b --- /dev/null +++ b/src/test/modules/test_lwlock_tranches/test_lwlock_tranches.control @@ -0,0 +1,4 @@ +comment = 'Test code for LWLock tranches allocated by extensions' +default_version = '1.0' +module_pathname = '$libdir/test_lwlock_tranches' +relocatable = true -- 2.39.5 (Apple Git-154) --hTu8Qy/GtaDsumby--