PostgreSQL Source Code git master
Loading...
Searching...
No Matches
dsm_impl.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include "common/file_perm.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "portability/mem.h"
#include "postmaster/postmaster.h"
#include "storage/dsm_impl.h"
#include "storage/fd.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/wait_event.h"
Include dependency graph for dsm_impl.c:

Go to the source code of this file.

Macros

#define ZBUFFER_SIZE   8192
 
#define SEGMENT_NAME_PREFIX   "Global/PostgreSQL"
 

Functions

static bool dsm_impl_posix (dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
 
static int dsm_impl_posix_resize (int fd, off_t size)
 
static bool dsm_impl_sysv (dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
 
static bool dsm_impl_mmap (dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
 
static int errcode_for_dynamic_shared_memory (void)
 
bool dsm_impl_op (dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
 
void dsm_impl_pin_segment (dsm_handle handle, void *impl_private, void **impl_private_pm_handle)
 
void dsm_impl_unpin_segment (dsm_handle handle, void **impl_private)
 

Variables

const struct config_enum_entry dynamic_shared_memory_options []
 
int dynamic_shared_memory_type = DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE
 
int min_dynamic_shared_memory
 

Macro Definition Documentation

◆ SEGMENT_NAME_PREFIX

#define SEGMENT_NAME_PREFIX   "Global/PostgreSQL"

Definition at line 121 of file dsm_impl.c.

◆ ZBUFFER_SIZE

#define ZBUFFER_SIZE   8192

Definition at line 119 of file dsm_impl.c.

Function Documentation

◆ dsm_impl_mmap()

static bool dsm_impl_mmap ( dsm_op  op,
dsm_handle  handle,
Size  request_size,
void **  impl_private,
void **  mapped_address,
Size mapped_size,
int  elevel 
)
static

Definition at line 793 of file dsm_impl.c.

796{
797 char name[64];
798 int flags;
799 int fd;
800 char *address;
801
803 handle);
804
805 /* Handle teardown cases. */
806 if (op == DSM_OP_DETACH || op == DSM_OP_DESTROY)
807 {
808 if (*mapped_address != NULL
809 && munmap(*mapped_address, *mapped_size) != 0)
810 {
811 ereport(elevel,
813 errmsg("could not unmap shared memory segment \"%s\": %m",
814 name)));
815 return false;
816 }
817 *mapped_address = NULL;
818 *mapped_size = 0;
819 if (op == DSM_OP_DESTROY && unlink(name) != 0)
820 {
821 ereport(elevel,
823 errmsg("could not remove shared memory segment \"%s\": %m",
824 name)));
825 return false;
826 }
827 return true;
828 }
829
830 /* Create new segment or open an existing one for attach. */
831 flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
832 if ((fd = OpenTransientFile(name, flags)) == -1)
833 {
834 if (op == DSM_OP_ATTACH || errno != EEXIST)
835 ereport(elevel,
837 errmsg("could not open shared memory segment \"%s\": %m",
838 name)));
839 return false;
840 }
841
842 /*
843 * If we're attaching the segment, determine the current size; if we are
844 * creating the segment, set the size to the requested value.
845 */
846 if (op == DSM_OP_ATTACH)
847 {
848 struct stat st;
849
850 if (fstat(fd, &st) != 0)
851 {
852 int save_errno;
853
854 /* Back out what's already been done. */
858
859 ereport(elevel,
861 errmsg("could not stat shared memory segment \"%s\": %m",
862 name)));
863 return false;
864 }
865 request_size = st.st_size;
866 }
867 else
868 {
869 /*
870 * Allocate a buffer full of zeros.
871 *
872 * Note: palloc zbuffer, instead of just using a local char array, to
873 * ensure it is reasonably well-aligned; this may save a few cycles
874 * transferring data to the kernel.
875 */
876 char *zbuffer = (char *) palloc0(ZBUFFER_SIZE);
878 bool success = true;
879
880 /*
881 * Zero-fill the file. We have to do this the hard way to ensure that
882 * all the file space has really been allocated, so that we don't
883 * later seg fault when accessing the memory mapping. This is pretty
884 * pessimal.
885 */
886 while (success && remaining > 0)
887 {
889
890 if (goal > ZBUFFER_SIZE)
893 if (write(fd, zbuffer, goal) == goal)
894 remaining -= goal;
895 else
896 success = false;
898 }
899
900 if (!success)
901 {
902 int save_errno;
903
904 /* Back out what's already been done. */
907 unlink(name);
909
910 ereport(elevel,
912 errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m",
913 name, request_size)));
914 return false;
915 }
916 }
917
918 /* Map it. */
921 if (address == MAP_FAILED)
922 {
923 int save_errno;
924
925 /* Back out what's already been done. */
928 if (op == DSM_OP_CREATE)
929 unlink(name);
931
932 ereport(elevel,
934 errmsg("could not map shared memory segment \"%s\": %m",
935 name)));
936 return false;
937 }
938 *mapped_address = address;
939 *mapped_size = request_size;
940
941 if (CloseTransientFile(fd) != 0)
942 {
943 ereport(elevel,
945 errmsg("could not close shared memory segment \"%s\": %m",
946 name)));
947 return false;
948 }
949
950 return true;
951}
size_t Size
Definition c.h:652
static int errcode_for_dynamic_shared_memory(void)
Definition dsm_impl.c:1048
#define ZBUFFER_SIZE
Definition dsm_impl.c:119
@ DSM_OP_DETACH
Definition dsm_impl.h:65
@ DSM_OP_CREATE
Definition dsm_impl.h:63
@ DSM_OP_DESTROY
Definition dsm_impl.h:66
@ DSM_OP_ATTACH
Definition dsm_impl.h:64
#define PG_DYNSHMEM_MMAP_FILE_PREFIX
Definition dsm_impl.h:52
#define PG_DYNSHMEM_DIR
Definition dsm_impl.h:51
int errcode_for_file_access(void)
Definition elog.c:897
#define ereport(elevel,...)
Definition elog.h:150
int CloseTransientFile(int fd)
Definition fd.c:2855
int OpenTransientFile(const char *fileName, int fileFlags)
Definition fd.c:2678
int remaining
Definition informix.c:692
static bool success
Definition initdb.c:187
#define write(a, b, c)
Definition win32.h:14
void * palloc0(Size size)
Definition mcxt.c:1417
#define MAP_FAILED
Definition mem.h:43
#define MAP_HASSEMAPHORE
Definition mem.h:30
#define MAP_NOSYNC
Definition mem.h:38
static char * errmsg
#define snprintf
Definition port.h:260
static int fd(const char *x, int i)
static int fb(int x)
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:69
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
const char * name
#define fstat
Definition win32_port.h:73

References CloseTransientFile(), DSM_OP_ATTACH, DSM_OP_CREATE, DSM_OP_DESTROY, DSM_OP_DETACH, ereport, errcode_for_dynamic_shared_memory(), errcode_for_file_access(), errmsg, fb(), fd(), fstat, MAP_FAILED, MAP_HASSEMAPHORE, MAP_NOSYNC, name, OpenTransientFile(), palloc0(), PG_DYNSHMEM_DIR, PG_DYNSHMEM_MMAP_FILE_PREFIX, pgstat_report_wait_end(), pgstat_report_wait_start(), remaining, snprintf, stat::st_size, success, write, and ZBUFFER_SIZE.

Referenced by dsm_impl_op().

◆ dsm_impl_op()

bool dsm_impl_op ( dsm_op  op,
dsm_handle  handle,
Size  request_size,
void **  impl_private,
void **  mapped_address,
Size mapped_size,
int  elevel 
)

Definition at line 160 of file dsm_impl.c.

163{
164 Assert(op == DSM_OP_CREATE || request_size == 0);
165 Assert((op != DSM_OP_CREATE && op != DSM_OP_ATTACH) ||
166 (*mapped_address == NULL && *mapped_size == 0));
167
169 {
170#ifdef USE_DSM_POSIX
171 case DSM_IMPL_POSIX:
172 return dsm_impl_posix(op, handle, request_size, impl_private,
173 mapped_address, mapped_size, elevel);
174#endif
175#ifdef USE_DSM_SYSV
176 case DSM_IMPL_SYSV:
177 return dsm_impl_sysv(op, handle, request_size, impl_private,
178 mapped_address, mapped_size, elevel);
179#endif
180#ifdef USE_DSM_WINDOWS
181 case DSM_IMPL_WINDOWS:
182 return dsm_impl_windows(op, handle, request_size, impl_private,
183 mapped_address, mapped_size, elevel);
184#endif
185#ifdef USE_DSM_MMAP
186 case DSM_IMPL_MMAP:
187 return dsm_impl_mmap(op, handle, request_size, impl_private,
188 mapped_address, mapped_size, elevel);
189#endif
190 default:
191 elog(ERROR, "unexpected dynamic shared memory type: %d",
193 return false;
194 }
195}
#define Assert(condition)
Definition c.h:906
int dynamic_shared_memory_type
Definition dsm_impl.c:113
static bool dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
Definition dsm_impl.c:424
static bool dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
Definition dsm_impl.c:213
static bool dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
Definition dsm_impl.c:793
#define DSM_IMPL_WINDOWS
Definition dsm_impl.h:19
#define DSM_IMPL_POSIX
Definition dsm_impl.h:17
#define DSM_IMPL_SYSV
Definition dsm_impl.h:18
#define DSM_IMPL_MMAP
Definition dsm_impl.h:20
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226

References Assert, dsm_impl_mmap(), DSM_IMPL_MMAP, dsm_impl_posix(), DSM_IMPL_POSIX, dsm_impl_sysv(), DSM_IMPL_SYSV, DSM_IMPL_WINDOWS, DSM_OP_ATTACH, DSM_OP_CREATE, dynamic_shared_memory_type, elog, ERROR, and fb().

Referenced by dsm_attach(), dsm_backend_startup(), dsm_cleanup_using_control_segment(), dsm_create(), dsm_detach(), dsm_detach_all(), dsm_postmaster_shutdown(), dsm_postmaster_startup(), and dsm_unpin_segment().

◆ dsm_impl_pin_segment()

void dsm_impl_pin_segment ( dsm_handle  handle,
void impl_private,
void **  impl_private_pm_handle 
)

Definition at line 964 of file dsm_impl.c.

966{
968 {
969#ifdef USE_DSM_WINDOWS
970 case DSM_IMPL_WINDOWS:
972 {
973 HANDLE hmap;
974
975 if (!DuplicateHandle(GetCurrentProcess(), impl_private,
978 {
979 char name[64];
980
981 snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
985 errmsg("could not duplicate handle for \"%s\": %m",
986 name)));
987 }
988
989 /*
990 * Here, we remember the handle that we created in the
991 * postmaster process. This handle isn't actually usable in
992 * any process other than the postmaster, but that doesn't
993 * matter. We're just holding onto it so that, if the segment
994 * is unpinned, dsm_impl_unpin_segment can close it.
995 */
996 *impl_private_pm_handle = hmap;
997 }
998 break;
999#endif
1000 default:
1001 break;
1002 }
1003}
#define SEGMENT_NAME_PREFIX
Definition dsm_impl.c:121
bool IsUnderPostmaster
Definition globals.c:120
void _dosmaperr(unsigned long)
Definition win32error.c:177

References _dosmaperr(), DSM_IMPL_WINDOWS, dynamic_shared_memory_type, ereport, errcode_for_dynamic_shared_memory(), errmsg, ERROR, fb(), IsUnderPostmaster, name, SEGMENT_NAME_PREFIX, and snprintf.

Referenced by dsm_pin_segment().

◆ dsm_impl_posix()

static bool dsm_impl_posix ( dsm_op  op,
dsm_handle  handle,
Size  request_size,
void **  impl_private,
void **  mapped_address,
Size mapped_size,
int  elevel 
)
static

Definition at line 213 of file dsm_impl.c.

216{
217 char name[64];
218 int flags;
219 int fd;
220 char *address;
221
222 snprintf(name, 64, "/PostgreSQL.%u", handle);
223
224 /* Handle teardown cases. */
225 if (op == DSM_OP_DETACH || op == DSM_OP_DESTROY)
226 {
227 if (*mapped_address != NULL
228 && munmap(*mapped_address, *mapped_size) != 0)
229 {
230 ereport(elevel,
232 errmsg("could not unmap shared memory segment \"%s\": %m",
233 name)));
234 return false;
235 }
236 *mapped_address = NULL;
237 *mapped_size = 0;
238 if (op == DSM_OP_DESTROY && shm_unlink(name) != 0)
239 {
240 ereport(elevel,
242 errmsg("could not remove shared memory segment \"%s\": %m",
243 name)));
244 return false;
245 }
246 return true;
247 }
248
249 /*
250 * Create new segment or open an existing one for attach.
251 *
252 * Even though we will close the FD before returning, it seems desirable
253 * to use Reserve/ReleaseExternalFD, to reduce the probability of EMFILE
254 * failure. The fact that we won't hold the FD open long justifies using
255 * ReserveExternalFD rather than AcquireExternalFD, though.
256 */
258
259 flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
260 if ((fd = shm_open(name, flags, PG_FILE_MODE_OWNER)) == -1)
261 {
263 if (op == DSM_OP_ATTACH || errno != EEXIST)
264 ereport(elevel,
266 errmsg("could not open shared memory segment \"%s\": %m",
267 name)));
268 return false;
269 }
270
271 /*
272 * If we're attaching the segment, determine the current size; if we are
273 * creating the segment, set the size to the requested value.
274 */
275 if (op == DSM_OP_ATTACH)
276 {
277 struct stat st;
278
279 if (fstat(fd, &st) != 0)
280 {
281 int save_errno;
282
283 /* Back out what's already been done. */
285 close(fd);
288
289 ereport(elevel,
291 errmsg("could not stat shared memory segment \"%s\": %m",
292 name)));
293 return false;
294 }
295 request_size = st.st_size;
296 }
297 else if (dsm_impl_posix_resize(fd, request_size) != 0)
298 {
299 int save_errno;
300
301 /* Back out what's already been done. */
303 close(fd);
307
308 ereport(elevel,
310 errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m",
311 name, request_size)));
312 return false;
313 }
314
315 /* Map it. */
318 if (address == MAP_FAILED)
319 {
320 int save_errno;
321
322 /* Back out what's already been done. */
324 close(fd);
326 if (op == DSM_OP_CREATE)
329
330 ereport(elevel,
332 errmsg("could not map shared memory segment \"%s\": %m",
333 name)));
334 return false;
335 }
336 *mapped_address = address;
337 *mapped_size = request_size;
338 close(fd);
340
341 return true;
342}
static int dsm_impl_posix_resize(int fd, off_t size)
Definition dsm_impl.c:352
void ReleaseExternalFD(void)
Definition fd.c:1225
void ReserveExternalFD(void)
Definition fd.c:1207
#define PG_FILE_MODE_OWNER
Definition file_perm.h:38
#define close(a)
Definition win32.h:12

References close, dsm_impl_posix_resize(), DSM_OP_ATTACH, DSM_OP_CREATE, DSM_OP_DESTROY, DSM_OP_DETACH, ereport, errcode_for_dynamic_shared_memory(), errmsg, fb(), fd(), fstat, MAP_FAILED, MAP_HASSEMAPHORE, MAP_NOSYNC, name, PG_FILE_MODE_OWNER, ReleaseExternalFD(), ReserveExternalFD(), snprintf, and stat::st_size.

Referenced by dsm_impl_op().

◆ dsm_impl_posix_resize()

static int dsm_impl_posix_resize ( int  fd,
off_t  size 
)
static

Definition at line 352 of file dsm_impl.c.

353{
354 int rc;
355 int save_errno;
357
358 /*
359 * Block all blockable signals, except SIGQUIT. posix_fallocate() can run
360 * for quite a long time, and is an all-or-nothing operation. If we
361 * allowed SIGUSR1 to interrupt us repeatedly (for example, due to
362 * recovery conflicts), the retry loop might never succeed.
363 */
366
368#if defined(HAVE_POSIX_FALLOCATE) && defined(__linux__)
369
370 /*
371 * On Linux, a shm_open fd is backed by a tmpfs file. If we were to use
372 * ftruncate, the file would contain a hole. Accessing memory backed by a
373 * hole causes tmpfs to allocate pages, which fails with SIGBUS if there
374 * is no more tmpfs space available. So we ask tmpfs to allocate pages
375 * here, so we can fail gracefully with ENOSPC now rather than risking
376 * SIGBUS later.
377 *
378 * We still use a traditional EINTR retry loop to handle SIGCONT.
379 * posix_fallocate() doesn't restart automatically, and we don't want this
380 * to fail if you attach a debugger.
381 */
382 do
383 {
384 rc = posix_fallocate(fd, 0, size);
385 } while (rc == EINTR);
386
387 /*
388 * The caller expects errno to be set, but posix_fallocate() doesn't set
389 * it. Instead it returns error numbers directly. So set errno, even
390 * though we'll also return rc to indicate success or failure.
391 */
392 errno = rc;
393#else
394 /* Extend the file to the requested size. */
395 do
396 {
397 rc = ftruncate(fd, size);
398 } while (rc < 0 && errno == EINTR);
399#endif
401
403 {
407 }
408
409 return rc;
410}
sigset_t BlockSig
Definition pqsignal.c:23
#define EINTR
Definition win32_port.h:361

References BlockSig, EINTR, fb(), fd(), IsUnderPostmaster, pgstat_report_wait_end(), and pgstat_report_wait_start().

Referenced by dsm_impl_posix().

◆ dsm_impl_sysv()

static bool dsm_impl_sysv ( dsm_op  op,
dsm_handle  handle,
Size  request_size,
void **  impl_private,
void **  mapped_address,
Size mapped_size,
int  elevel 
)
static

Definition at line 424 of file dsm_impl.c.

427{
428 key_t key;
429 int ident;
430 char *address;
431 char name[64];
432 int *ident_cache;
433
434 /*
435 * POSIX shared memory and mmap-based shared memory identify segments with
436 * names. To avoid needless error message variation, we use the handle as
437 * the name.
438 */
439 snprintf(name, 64, "%u", handle);
440
441 /*
442 * The System V shared memory namespace is very restricted; names are of
443 * type key_t, which is expected to be some sort of integer data type, but
444 * not necessarily the same one as dsm_handle. Since we use dsm_handle to
445 * identify shared memory segments across processes, this might seem like
446 * a problem, but it's really not. If dsm_handle is bigger than key_t,
447 * the cast below might truncate away some bits from the handle the
448 * user-provided, but it'll truncate exactly the same bits away in exactly
449 * the same fashion every time we use that handle, which is all that
450 * really matters. Conversely, if dsm_handle is smaller than key_t, we
451 * won't use the full range of available key space, but that's no big deal
452 * either.
453 *
454 * We do make sure that the key isn't negative, because that might not be
455 * portable.
456 */
457 key = (key_t) handle;
458 if (key < 1) /* avoid compiler warning if type is unsigned */
459 key = -key;
460
461 /*
462 * There's one special key, IPC_PRIVATE, which can't be used. If we end
463 * up with that value by chance during a create operation, just pretend it
464 * already exists, so that caller will retry. If we run into it anywhere
465 * else, the caller has passed a handle that doesn't correspond to
466 * anything we ever created, which should not happen.
467 */
468 if (key == IPC_PRIVATE)
469 {
470 if (op != DSM_OP_CREATE)
471 elog(DEBUG4, "System V shared memory key may not be IPC_PRIVATE");
472 errno = EEXIST;
473 return false;
474 }
475
476 /*
477 * Before we can do anything with a shared memory segment, we have to map
478 * the shared memory key to a shared memory identifier using shmget(). To
479 * avoid repeated lookups, we store the key using impl_private.
480 */
481 if (*impl_private != NULL)
482 {
483 ident_cache = *impl_private;
485 }
486 else
487 {
488 int flags = IPCProtection;
489 size_t segsize;
490
491 /*
492 * Allocate the memory BEFORE acquiring the resource, so that we don't
493 * leak the resource if memory allocation fails.
494 */
496
497 /*
498 * When using shmget to find an existing segment, we must pass the
499 * size as 0. Passing a non-zero size which is greater than the
500 * actual size will result in EINVAL.
501 */
502 segsize = 0;
503
504 if (op == DSM_OP_CREATE)
505 {
506 flags |= IPC_CREAT | IPC_EXCL;
508 }
509
510 if ((ident = shmget(key, segsize, flags)) == -1)
511 {
512 if (op == DSM_OP_ATTACH || errno != EEXIST)
513 {
514 int save_errno = errno;
515
518 ereport(elevel,
520 errmsg("could not get shared memory segment: %m")));
521 }
522 return false;
523 }
524
526 *impl_private = ident_cache;
527 }
528
529 /* Handle teardown cases. */
530 if (op == DSM_OP_DETACH || op == DSM_OP_DESTROY)
531 {
533 *impl_private = NULL;
534 if (*mapped_address != NULL && shmdt(*mapped_address) != 0)
535 {
536 ereport(elevel,
538 errmsg("could not unmap shared memory segment \"%s\": %m",
539 name)));
540 return false;
541 }
542 *mapped_address = NULL;
543 *mapped_size = 0;
544 if (op == DSM_OP_DESTROY && shmctl(ident, IPC_RMID, NULL) < 0)
545 {
546 ereport(elevel,
548 errmsg("could not remove shared memory segment \"%s\": %m",
549 name)));
550 return false;
551 }
552 return true;
553 }
554
555 /* If we're attaching it, we must use IPC_STAT to determine the size. */
556 if (op == DSM_OP_ATTACH)
557 {
558 struct shmid_ds shm;
559
560 if (shmctl(ident, IPC_STAT, &shm) != 0)
561 {
562 ereport(elevel,
564 errmsg("could not stat shared memory segment \"%s\": %m",
565 name)));
566 return false;
567 }
568 request_size = shm.shm_segsz;
569 }
570
571 /* Map it. */
572 address = shmat(ident, NULL, PG_SHMAT_FLAGS);
573 if (address == (void *) -1)
574 {
575 int save_errno;
576
577 /* Back out what's already been done. */
579 if (op == DSM_OP_CREATE)
582
583 ereport(elevel,
585 errmsg("could not map shared memory segment \"%s\": %m",
586 name)));
587 return false;
588 }
589 *mapped_address = address;
590 *mapped_size = request_size;
591
592 return true;
593}
#define DEBUG4
Definition elog.h:27
#define ident
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void pfree(void *pointer)
Definition mcxt.c:1616
MemoryContext TopMemoryContext
Definition mcxt.c:166
#define PG_SHMAT_FLAGS
Definition mem.h:20
#define IPCProtection
Definition posix_sema.c:59
#define IPC_STAT
Definition win32_port.h:98
#define IPC_RMID
Definition win32_port.h:93
long key_t
Definition win32_port.h:237
#define IPC_EXCL
Definition win32_port.h:95
#define IPC_CREAT
Definition win32_port.h:94
#define IPC_PRIVATE
Definition win32_port.h:96

References DEBUG4, DSM_OP_ATTACH, DSM_OP_CREATE, DSM_OP_DESTROY, DSM_OP_DETACH, elog, ereport, errcode_for_dynamic_shared_memory(), errmsg, fb(), ident, IPC_CREAT, IPC_EXCL, IPC_PRIVATE, IPC_RMID, IPC_STAT, IPCProtection, MemoryContextAlloc(), name, pfree(), PG_SHMAT_FLAGS, snprintf, and TopMemoryContext.

Referenced by dsm_impl_op().

◆ dsm_impl_unpin_segment()

void dsm_impl_unpin_segment ( dsm_handle  handle,
void **  impl_private 
)

Definition at line 1015 of file dsm_impl.c.

1016{
1018 {
1019#ifdef USE_DSM_WINDOWS
1020 case DSM_IMPL_WINDOWS:
1022 {
1023 if (*impl_private &&
1024 !DuplicateHandle(PostmasterHandle, *impl_private,
1025 NULL, NULL, 0, FALSE,
1027 {
1028 char name[64];
1029
1030 snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
1032 ereport(ERROR,
1034 errmsg("could not duplicate handle for \"%s\": %m",
1035 name)));
1036 }
1037
1038 *impl_private = NULL;
1039 }
1040 break;
1041#endif
1042 default:
1043 break;
1044 }
1045}

References _dosmaperr(), DSM_IMPL_WINDOWS, dynamic_shared_memory_type, ereport, errcode_for_dynamic_shared_memory(), errmsg, ERROR, fb(), IsUnderPostmaster, name, SEGMENT_NAME_PREFIX, and snprintf.

Referenced by dsm_unpin_segment().

◆ errcode_for_dynamic_shared_memory()

static int errcode_for_dynamic_shared_memory ( void  )
static

Definition at line 1048 of file dsm_impl.c.

1049{
1050 if (errno == EFBIG || errno == ENOMEM)
1052 else
1053 return errcode_for_file_access();
1054}
int errcode(int sqlerrcode)
Definition elog.c:874

References errcode(), errcode_for_file_access(), and fb().

Referenced by dsm_impl_mmap(), dsm_impl_pin_segment(), dsm_impl_posix(), dsm_impl_sysv(), and dsm_impl_unpin_segment().

Variable Documentation

◆ dynamic_shared_memory_options

const struct config_enum_entry dynamic_shared_memory_options[]
Initial value:
= {
{"posix", DSM_IMPL_POSIX, false},
{"sysv", DSM_IMPL_SYSV, false},
{"mmap", DSM_IMPL_MMAP, false},
{NULL, 0, false}
}

Definition at line 96 of file dsm_impl.c.

96 {
97#ifdef USE_DSM_POSIX
98 {"posix", DSM_IMPL_POSIX, false},
99#endif
100#ifdef USE_DSM_SYSV
101 {"sysv", DSM_IMPL_SYSV, false},
102#endif
103#ifdef USE_DSM_WINDOWS
104 {"windows", DSM_IMPL_WINDOWS, false},
105#endif
106#ifdef USE_DSM_MMAP
107 {"mmap", DSM_IMPL_MMAP, false},
108#endif
109 {NULL, 0, false}
110};

◆ dynamic_shared_memory_type

◆ min_dynamic_shared_memory

int min_dynamic_shared_memory

Definition at line 116 of file dsm_impl.c.

Referenced by dsm_estimate_size().