mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Allow dynamic shared memory segments to be kept until shutdown.
Amit Kapila, reviewed by Kyotaro Horiguchi, with some further changes by me.
This commit is contained in:
@ -67,6 +67,7 @@
|
||||
#include "storage/fd.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
|
||||
#ifdef USE_DSM_POSIX
|
||||
static bool dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size,
|
||||
@ -113,6 +114,8 @@ int dynamic_shared_memory_type;
|
||||
/* Size of buffer to be used for zero-filling. */
|
||||
#define ZBUFFER_SIZE 8192
|
||||
|
||||
#define SEGMENT_NAME_PREFIX "Global/PostgreSQL"
|
||||
|
||||
/*------
|
||||
* Perform a low-level shared memory operation in a platform-specific way,
|
||||
* as dictated by the selected implementation. Each implementation is
|
||||
@ -635,7 +638,7 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size,
|
||||
* convention similar to main shared memory. We can change here once
|
||||
* issue mentioned in GetSharedMemName is resolved.
|
||||
*/
|
||||
snprintf(name, 64, "Global/PostgreSQL.%u", handle);
|
||||
snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
|
||||
|
||||
/*
|
||||
* Handle teardown cases. Since Windows automatically destroys the object
|
||||
@ -982,6 +985,46 @@ 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.
|
||||
*
|
||||
* 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
|
||||
* the segment handle into the postmaster process. The postmaster needn't
|
||||
* do anything to receive the handle; Windows transfers it automatically.
|
||||
*/
|
||||
void
|
||||
dsm_impl_keep_segment(dsm_handle handle, void *impl_private)
|
||||
{
|
||||
switch (dynamic_shared_memory_type)
|
||||
{
|
||||
#ifdef USE_DSM_WINDOWS
|
||||
case DSM_IMPL_WINDOWS:
|
||||
{
|
||||
HANDLE hmap;
|
||||
|
||||
if (!DuplicateHandle(GetCurrentProcess(), impl_private,
|
||||
PostmasterHandle, &hmap, 0, FALSE,
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
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)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
errcode_for_dynamic_shared_memory()
|
||||
{
|
||||
|
Reference in New Issue
Block a user