1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-09 22:41:56 +03:00

Extend dsm API with a new function dsm_unpin_segment.

If you have previously pinned a segment and decide that you don't
actually want to keep it around until shutdown, this new API lets you
remove the pin.  This is pretty trivial except on Windows, where it
requires closing the duplicate handle that was used to implement the
pin.

Thomas Munro and Amit Kapila, reviewed by Amit Kapila and by me.
This commit is contained in:
Robert Haas
2016-08-23 14:32:23 -04:00
parent 19998730ae
commit 0fda682e54
4 changed files with 169 additions and 10 deletions

View File

@ -987,8 +987,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
#endif
/*
* Implementation-specific actions that must be performed when a segment
* is to be preserved until postmaster shutdown.
* Implementation-specific actions that must be performed when a segment is to
* be preserved even when no backend has it attached.
*
* Except on Windows, we don't need to do anything at all. But since Windows
* cleans up segments automatically when no references remain, we duplicate
@ -996,7 +996,8 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size,
* do anything to receive the handle; Windows transfers it automatically.
*/
void
dsm_impl_pin_segment(dsm_handle handle, void *impl_private)
dsm_impl_pin_segment(dsm_handle handle, void *impl_private,
void **impl_private_pm_handle)
{
switch (dynamic_shared_memory_type)
{
@ -1018,6 +1019,56 @@ dsm_impl_pin_segment(dsm_handle handle, void *impl_private)
errmsg("could not duplicate handle for \"%s\": %m",
name)));
}
/*
* Here, we remember the handle that we created in the
* postmaster process. This handle isn't actually usable in
* any process other than the postmaster, but that doesn't
* matter. We're just holding onto it so that, if the segment
* is unpinned, dsm_impl_unpin_segment can close it.
*/
*impl_private_pm_handle = hmap;
break;
}
#endif
default:
break;
}
}
/*
* Implementation-specific actions that must be performed when a segment is no
* longer to be preserved, so that it will be cleaned up when all backends
* have detached from it.
*
* Except on Windows, we don't need to do anything at all. For Windows, we
* close the extra handle that dsm_impl_pin_segment created in the
* postmaster's process space.
*/
void
dsm_impl_unpin_segment(dsm_handle handle, void **impl_private)
{
switch (dynamic_shared_memory_type)
{
#ifdef USE_DSM_WINDOWS
case DSM_IMPL_WINDOWS:
{
if (*impl_private &&
!DuplicateHandle(PostmasterHandle, *impl_private,
NULL, NULL, 0, FALSE,
DUPLICATE_CLOSE_SOURCE))
{
char name[64];
snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
_dosmaperr(GetLastError());
ereport(ERROR,
(errcode_for_dynamic_shared_memory(),
errmsg("could not duplicate handle for \"%s\": %m",
name)));
}
*impl_private = NULL;
break;
}
#endif