Skip to content

Commit fb9a16a

Browse files
committed
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 84b1c63 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
1 parent 85c9dda commit fb9a16a

File tree

1 file changed

+6
-4
lines changed
  • src/backend/storage/ipc

1 file changed

+6
-4
lines changed

src/backend/storage/ipc/dsm.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ dsm_unpin_mapping(dsm_segment *seg)
920920
void
921921
dsm_pin_segment(dsm_segment *seg)
922922
{
923-
void *handle;
923+
void *handle = NULL;
924924

925925
/*
926926
* Bump reference count for this segment in shared memory. This will
@@ -931,7 +931,8 @@ dsm_pin_segment(dsm_segment *seg)
931931
LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
932932
if (dsm_control->item[seg->control_slot].pinned)
933933
elog(ERROR, "cannot pin a segment that is already pinned");
934-
dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
934+
if (!is_main_region_dsm_handle(seg->handle))
935+
dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
935936
dsm_control->item[seg->control_slot].pinned = true;
936937
dsm_control->item[seg->control_slot].refcnt++;
937938
dsm_control->item[seg->control_slot].impl_private_pm_handle = handle;
@@ -988,8 +989,9 @@ dsm_unpin_segment(dsm_handle handle)
988989
* releasing the lock, because impl_private_pm_handle may get modified by
989990
* dsm_impl_unpin_segment.
990991
*/
991-
dsm_impl_unpin_segment(handle,
992-
&dsm_control->item[control_slot].impl_private_pm_handle);
992+
if (!is_main_region_dsm_handle(handle))
993+
dsm_impl_unpin_segment(handle,
994+
&dsm_control->item[control_slot].impl_private_pm_handle);
993995

994996
/* Note that 1 means no references (0 means unused slot). */
995997
if (--dsm_control->item[control_slot].refcnt == 1)

0 commit comments

Comments
 (0)