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 1uyuso-00EQzu-WC for pgsql-hackers@arkaria.postgresql.org; Wed, 17 Sep 2025 16:19:51 +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 1uyusm-00976p-1V for pgsql-hackers@arkaria.postgresql.org; Wed, 17 Sep 2025 16:19:48 +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 1uyusl-00976h-Mf for pgsql-hackers@lists.postgresql.org; Wed, 17 Sep 2025 16:19:48 +0000 Received: from mail-il1-x136.google.com ([2607:f8b0:4864:20::136]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uyusi-001LiT-0a for pgsql-hackers@postgresql.org; Wed, 17 Sep 2025 16:19:47 +0000 Received: by mail-il1-x136.google.com with SMTP id e9e14a558f8ab-417661ecbb1so75307445ab.2 for ; Wed, 17 Sep 2025 09:19:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1758125983; x=1758730783; 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=VZDzRZZgg/DPa5Fkce8JXWAYi/ExyNAlJjBNe80q9s4=; b=UNVMqvgf+aRIKoBvs0yenXk+MU2h3+kLzYd2jLSjxWBd8PCOLNU0IYrwpymBlWn9RL NEwK2uFwWkGoP7BeHhTF3PHM53wP3gYBejVNH9jyJD9oktTUI0xjiunT6dvGnYtr2Mw8 aVQe08IipCJxq7O6T/zxOkM5E6yCaqFUV6MiHnjNNKmXogcC4rdb6hVZqqNQBJtbQ+Sp FYPeO6NQIhF2lLGjBk/GGePohOQB4/1zeJeyd5B3SHsycF2jUTEhZkw257cp4WaSOG7q Qinu5zD1MSPqCINzU0fd8/Ddw++W/CrMskLAgyHPemqopJib02p9G0uysH7UM1EuKnth 0dgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758125983; x=1758730783; 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=VZDzRZZgg/DPa5Fkce8JXWAYi/ExyNAlJjBNe80q9s4=; b=tMAFcS4PvMRMoeYKdQgr4GSKPZJrnltU26ZD0+us3aI403JQcVD9Ph9/fuvzL0C0iO a3HEOb90riQ4Pm2azsRXDGtoSJv0ytYQ/Dyo2s1+nE0wld62lyXVE+z18wXk2J4Uw5GL HOjon5uKO/pmGeV0VI2XW2fGIGuHNnag0aED4Gimxcao2q8nEz+S7w4kHNlqXcf8uiqb PBI/YsFq3xKuYRHM5QbIt7QH9goZUGjyjAV1Dx/j/dzIwSuchG2f0r/XW0zQhB7qWxt1 pMgI2NcccjWgRtX3N02w0lMSAGitoS7lHibap9M78krNEPuWLn0m1UOiDghO6NxwJUms aFNg== X-Gm-Message-State: AOJu0YyjOpLm+XDUiINq5IMlQL/8m+TkK+WNMC+TTkdCdOY6QnsEc3X7 wGwdSYmsUDYMR+XexBY1oU5Iszl1NRIevLdKhEVluIw3Q6dIk0PFMRJQbZ21jg== X-Gm-Gg: ASbGncsZvKYhnHHNV9ekXpVTs6wOPU3WqBbmpmmnMVubVb2onufqJdD9J+ZqKQXi7A7 Cxi9/46NgchLmOtf+mUjd6LRa9tEMFsP2foemblPFeKVWeiGIw61CiabwmJc1R8jholkZ444gtI FEgjh9pc9N+B5yAlfpy0PfFHVe1RvL8I82pszShCi2CeDZulyubV+m4AlWs3Wvdi7hH941TW4fr Sud+YDA1H33srUrOhsIFIl0lgBZYt9LdUh3T0704jAz+toUm7FrofYSM6qflPC7MmXc2FSfg34R B6eCpTxGzq9PwjGIM2cYSXWdqRyH92KH9E6xdLRcJiXQwU60Mv+ahUOD7S+7xRl0wWF07TiXWOm YHrfwgRsMEeaMqrrZdvxHxUvxyIKnBtl86KFAzjVG97bG186X4zF72CYA2rIdpvNqfUUUj+MXlm e/pS3TZaRVXGKl X-Google-Smtp-Source: AGHT+IGfZ9E91uy8iYJuf5ZN8BYRezf7/KSi3Tc+44GFrID99jZmzSV4UkCzwRU3PIRx29Cntk1iCQ== X-Received: by 2002:a05:6e02:228f:b0:423:5293:574f with SMTP id e9e14a558f8ab-4241a52960cmr32929185ab.18.1758125983528; Wed, 17 Sep 2025 09:19:43 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-5120bd4bd24sm5432971173.63.2025.09.17.09.19.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Sep 2025 09:19:42 -0700 (PDT) Date: Wed, 17 Sep 2025 11:19:41 -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="2U771KkmV8F/D8wC" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --2U771KkmV8F/D8wC Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Sep 17, 2025 at 11:08:12AM -0500, Sami Imseih wrote: >> 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? > > It does not really matter for the tests being done, but it just > seems odd that you would create 254 tranches during startup and > leave room for only 2 dynamic tranches. It is not the typical > pattern out there, in my opinion. Okay. I changed it in v8. -- nathan --2U771KkmV8F/D8wC Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v8-0001-test_lwlock_tranches.patch From f5d462e175fe6d9ab76b1e59b98013480df5ed9b Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Tue, 16 Sep 2025 10:15:11 -0500 Subject: [PATCH v8 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..4e2c43ac933 --- /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 (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) --2U771KkmV8F/D8wC--