summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2023-10-21 21:04:55 +0000
committerThomas Munro2023-10-21 21:04:55 +0000
commitdab889d60bac3fbf691973ca1770f2eb50547999 (patch)
tree44dc5c426cb99adf700612e97700c431560eceec
parent2d870b4aeff174ea3b8a0837bc2065c820fb43e2 (diff)
Fix min_dynamic_shared_memory on Windows.
When min_dynamic_shared_memory is set above 0, we try to find space in a pre-allocated region of the main shared memory area instead of calling dsm_impl_XXX() routines to allocate more. The dsm_pin_segment() and dsm_unpin_segment() routines had a bug: they called dsm_impl_XXX() routines even for main region segments. Nobody noticed before now because those routines do nothing on Unix, but on Windows they'd fail while attempting to duplicate an invalid Windows HANDLE. Add the missing gating. Back-patch to 14, where commit 84b1c63a added this feature. Fixes pgsql-bugs bug #18165. Reported-by: Maxime Boyer <[email protected]> Tested-by: Alexander Lakhin <[email protected]> Discussion: https://postgr.es/m/18165-bf4f525cea6e51de%40postgresql.org
-rw-r--r--src/backend/storage/ipc/dsm.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c
index 10b029bb162..7e4e27810e8 100644
--- a/src/backend/storage/ipc/dsm.c
+++ b/src/backend/storage/ipc/dsm.c
@@ -927,7 +927,7 @@ dsm_unpin_mapping(dsm_segment *seg)
void
dsm_pin_segment(dsm_segment *seg)
{
- void *handle;
+ void *handle = NULL;
/*
* Bump reference count for this segment in shared memory. This will
@@ -938,7 +938,8 @@ dsm_pin_segment(dsm_segment *seg)
LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
if (dsm_control->item[seg->control_slot].pinned)
elog(ERROR, "cannot pin a segment that is already pinned");
- dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
+ if (!is_main_region_dsm_handle(seg->handle))
+ dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
dsm_control->item[seg->control_slot].pinned = true;
dsm_control->item[seg->control_slot].refcnt++;
dsm_control->item[seg->control_slot].impl_private_pm_handle = handle;
@@ -995,8 +996,9 @@ dsm_unpin_segment(dsm_handle handle)
* releasing the lock, because impl_private_pm_handle may get modified by
* dsm_impl_unpin_segment.
*/
- dsm_impl_unpin_segment(handle,
- &dsm_control->item[control_slot].impl_private_pm_handle);
+ if (!is_main_region_dsm_handle(handle))
+ dsm_impl_unpin_segment(handle,
+ &dsm_control->item[control_slot].impl_private_pm_handle);
/* Note that 1 means no references (0 means unused slot). */
if (--dsm_control->item[control_slot].refcnt == 1)