diff options
author | Robert Haas <rhaas@postgresql.org> | 2014-03-10 14:04:47 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2014-03-10 14:04:47 -0400 |
commit | 8722017bbcbc95e311bbaa6d21cd028e296e5e35 (patch) | |
tree | 3fe4426fd8888edcde9360f553f2c290c2bb1dd8 /src/backend/storage/ipc/dsm_impl.c | |
parent | 5a991ef8692ed0d170b44958a81a6bd70e90585c (diff) |
Allow dynamic shared memory segments to be kept until shutdown.
Amit Kapila, reviewed by Kyotaro Horiguchi, with some further
changes by me.
Diffstat (limited to 'src/backend/storage/ipc/dsm_impl.c')
-rw-r--r-- | src/backend/storage/ipc/dsm_impl.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index a8d8a64afbd..745ff23a8d8 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -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() { |