Skip to content

Commit dab889d

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 <maxime.boyer@cra-arc.gc.ca> Tested-by: Alexander Lakhin <exclusion@gmail.com> Discussion: https://postgr.es/m/18165-bf4f525cea6e51de%40postgresql.org
1 parent 2d870b4 commit dab889d

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ dsm_unpin_mapping(dsm_segment *seg)
927927
void
928928
dsm_pin_segment(dsm_segment *seg)
929929
{
930-
void *handle;
930+
void *handle = NULL;
931931

932932
/*
933933
* Bump reference count for this segment in shared memory. This will
@@ -938,7 +938,8 @@ dsm_pin_segment(dsm_segment *seg)
938938
LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE);
939939
if (dsm_control->item[seg->control_slot].pinned)
940940
elog(ERROR, "cannot pin a segment that is already pinned");
941-
dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
941+
if (!is_main_region_dsm_handle(seg->handle))
942+
dsm_impl_pin_segment(seg->handle, seg->impl_private, &handle);
942943
dsm_control->item[seg->control_slot].pinned = true;
943944
dsm_control->item[seg->control_slot].refcnt++;
944945
dsm_control->item[seg->control_slot].impl_private_pm_handle = handle;
@@ -995,8 +996,9 @@ dsm_unpin_segment(dsm_handle handle)
995996
* releasing the lock, because impl_private_pm_handle may get modified by
996997
* dsm_impl_unpin_segment.
997998
*/
998-
dsm_impl_unpin_segment(handle,
999-
&dsm_control->item[control_slot].impl_private_pm_handle);
999+
if (!is_main_region_dsm_handle(handle))
1000+
dsm_impl_unpin_segment(handle,
1001+
&dsm_control->item[control_slot].impl_private_pm_handle);
10001002

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

0 commit comments

Comments
 (0)