PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
dsm_impl.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "pgstat.h"
#include "portability/mem.h"
#include "storage/dsm_impl.h"
#include "storage/fd.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "postmaster/postmaster.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_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)
 
bool dsm_impl_can_resize (void)
 
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
 

Macro Definition Documentation

#define SEGMENT_NAME_PREFIX   "Global/PostgreSQL"

Definition at line 117 of file dsm_impl.c.

Referenced by dsm_impl_pin_segment(), and dsm_impl_unpin_segment().

#define ZBUFFER_SIZE   8192

Definition at line 115 of file dsm_impl.c.

Referenced by dsm_impl_mmap().

Function Documentation

bool dsm_impl_can_resize ( void  )

Definition at line 207 of file dsm_impl.c.

References DSM_IMPL_MMAP, DSM_IMPL_NONE, DSM_IMPL_POSIX, DSM_IMPL_SYSV, DSM_IMPL_WINDOWS, and dynamic_shared_memory_type.

208 {
210  {
211  case DSM_IMPL_NONE:
212  return false;
213  case DSM_IMPL_POSIX:
214  return true;
215  case DSM_IMPL_SYSV:
216  return false;
217  case DSM_IMPL_WINDOWS:
218  return false;
219  case DSM_IMPL_MMAP:
220  return true;
221  default:
222  return false; /* should not happen */
223  }
224 }
#define DSM_IMPL_MMAP
Definition: dsm_impl.h:21
#define DSM_IMPL_SYSV
Definition: dsm_impl.h:19
#define DSM_IMPL_WINDOWS
Definition: dsm_impl.h:20
#define DSM_IMPL_POSIX
Definition: dsm_impl.h:18
int dynamic_shared_memory_type
Definition: dsm_impl.c:112
#define DSM_IMPL_NONE
Definition: dsm_impl.h:17
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 799 of file dsm_impl.c.

References close, CloseTransientFile(), DSM_OP_ATTACH, DSM_OP_CREATE, DSM_OP_DESTROY, DSM_OP_DETACH, ereport, errcode_for_dynamic_shared_memory(), errmsg(), fd(), ftruncate, MAP_FAILED, MAP_HASSEMAPHORE, MAP_NOSYNC, NULL, OpenTransientFile(), palloc0(), PG_DYNSHMEM_DIR, PG_DYNSHMEM_MMAP_FILE_PREFIX, pgstat_report_wait_end(), pgstat_report_wait_start(), remaining, snprintf(), success, unlink(), WAIT_EVENT_DSM_FILL_ZERO_WRITE, write, and ZBUFFER_SIZE.

Referenced by dsm_impl_op().

802 {
803  char name[64];
804  int flags;
805  int fd;
806  char *address;
807 
809  handle);
810 
811  /* Handle teardown cases. */
812  if (op == DSM_OP_DETACH || op == DSM_OP_DESTROY)
813  {
814  if (*mapped_address != NULL
815  && munmap(*mapped_address, *mapped_size) != 0)
816  {
817  ereport(elevel,
819  errmsg("could not unmap shared memory segment \"%s\": %m",
820  name)));
821  return false;
822  }
823  *mapped_address = NULL;
824  *mapped_size = 0;
825  if (op == DSM_OP_DESTROY && unlink(name) != 0)
826  {
827  ereport(elevel,
829  errmsg("could not remove shared memory segment \"%s\": %m",
830  name)));
831  return false;
832  }
833  return true;
834  }
835 
836  /* Create new segment or open an existing one for attach or resize. */
837  flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0);
838  if ((fd = OpenTransientFile(name, flags, 0600)) == -1)
839  {
840  if (errno != EEXIST)
841  ereport(elevel,
843  errmsg("could not open shared memory segment \"%s\": %m",
844  name)));
845  return false;
846  }
847 
848  /*
849  * If we're attaching the segment, determine the current size; if we are
850  * creating or resizing the segment, set the size to the requested value.
851  */
852  if (op == DSM_OP_ATTACH)
853  {
854  struct stat st;
855 
856  if (fstat(fd, &st) != 0)
857  {
858  int save_errno;
859 
860  /* Back out what's already been done. */
861  save_errno = errno;
862  CloseTransientFile(fd);
863  errno = save_errno;
864 
865  ereport(elevel,
867  errmsg("could not stat shared memory segment \"%s\": %m",
868  name)));
869  return false;
870  }
871  request_size = st.st_size;
872  }
873  else if (*mapped_size > request_size && ftruncate(fd, request_size))
874  {
875  int save_errno;
876 
877  /* Back out what's already been done. */
878  save_errno = errno;
879  close(fd);
880  if (op == DSM_OP_CREATE)
881  unlink(name);
882  errno = save_errno;
883 
884  ereport(elevel,
886  errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m",
887  name, request_size)));
888  return false;
889  }
890  else if (*mapped_size < request_size)
891  {
892  /*
893  * Allocate a buffer full of zeros.
894  *
895  * Note: palloc zbuffer, instead of just using a local char array, to
896  * ensure it is reasonably well-aligned; this may save a few cycles
897  * transferring data to the kernel.
898  */
899  char *zbuffer = (char *) palloc0(ZBUFFER_SIZE);
900  uint32 remaining = request_size;
901  bool success = true;
902 
903  /*
904  * Zero-fill the file. We have to do this the hard way to ensure that
905  * all the file space has really been allocated, so that we don't
906  * later seg fault when accessing the memory mapping. This is pretty
907  * pessimal.
908  */
909  while (success && remaining > 0)
910  {
911  Size goal = remaining;
912 
913  if (goal > ZBUFFER_SIZE)
914  goal = ZBUFFER_SIZE;
916  if (write(fd, zbuffer, goal) == goal)
917  remaining -= goal;
918  else
919  success = false;
921  }
922 
923  if (!success)
924  {
925  int save_errno;
926 
927  /* Back out what's already been done. */
928  save_errno = errno;
929  CloseTransientFile(fd);
930  if (op == DSM_OP_CREATE)
931  unlink(name);
932  errno = save_errno ? save_errno : ENOSPC;
933 
934  ereport(elevel,
936  errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m",
937  name, request_size)));
938  return false;
939  }
940  }
941 
942  /*
943  * If we're reattaching or resizing, we must remove any existing mapping,
944  * unless we've already got the right thing mapped.
945  */
946  if (*mapped_address != NULL)
947  {
948  if (*mapped_size == request_size)
949  return true;
950  if (munmap(*mapped_address, *mapped_size) != 0)
951  {
952  int save_errno;
953 
954  /* Back out what's already been done. */
955  save_errno = errno;
956  CloseTransientFile(fd);
957  if (op == DSM_OP_CREATE)
958  unlink(name);
959  errno = save_errno;
960 
961  ereport(elevel,
963  errmsg("could not unmap shared memory segment \"%s\": %m",
964  name)));
965  return false;
966  }
967  *mapped_address = NULL;
968  *mapped_size = 0;
969  }
970 
971  /* Map it. */
972  address = mmap(NULL, request_size, PROT_READ | PROT_WRITE,
973  MAP_SHARED | MAP_HASSEMAPHORE | MAP_NOSYNC, fd, 0);
974  if (address == MAP_FAILED)
975  {
976  int save_errno;
977 
978  /* Back out what's already been done. */
979  save_errno = errno;
980  CloseTransientFile(fd);
981  if (op == DSM_OP_CREATE)
982  unlink(name);
983  errno = save_errno;
984 
985  ereport(elevel,
987  errmsg("could not map shared memory segment \"%s\": %m",
988  name)));
989  return false;
990  }
991  *mapped_address = address;
992  *mapped_size = request_size;
993  CloseTransientFile(fd);
994 
995  return true;
996 }
int remaining
Definition: informix.c:692
#define MAP_HASSEMAPHORE
Definition: mem.h:30
#define MAP_FAILED
Definition: mem.h:45
#define PG_DYNSHMEM_DIR
Definition: dsm_impl.h:51
#define write(a, b, c)
Definition: win32.h:14
#define MAP_NOSYNC
Definition: mem.h:38
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static int errcode_for_dynamic_shared_memory(void)
Definition: dsm_impl.c:1091
static bool success
Definition: pg_basebackup.c:96
int OpenTransientFile(FileName fileName, int fileFlags, int fileMode)
Definition: fd.c:2144
unsigned int uint32
Definition: c.h:268
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1232
int unlink(const char *filename)
#define ereport(elevel, rest)
Definition: elog.h:122
int CloseTransientFile(int fd)
Definition: fd.c:2305
static int elevel
Definition: vacuumlazy.c:137
void * palloc0(Size size)
Definition: mcxt.c:878
#define ftruncate(a, b)
Definition: win32.h:59
#define NULL
Definition: c.h:229
size_t Size
Definition: c.h:356
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1208
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_DYNSHMEM_MMAP_FILE_PREFIX
Definition: dsm_impl.h:52
#define ZBUFFER_SIZE
Definition: dsm_impl.c:115
#define close(a)
Definition: win32.h:12
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 162 of file dsm_impl.c.

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

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(), dsm_remap(), dsm_resize(), and dsm_unpin_segment().

165 {
166  Assert(op == DSM_OP_CREATE || op == DSM_OP_RESIZE || request_size == 0);
167  Assert((op != DSM_OP_CREATE && op != DSM_OP_ATTACH) ||
168  (*mapped_address == NULL && *mapped_size == 0));
169 
171  {
172 #ifdef USE_DSM_POSIX
173  case DSM_IMPL_POSIX:
174  return dsm_impl_posix(op, handle, request_size, impl_private,
175  mapped_address, mapped_size, elevel);
176 #endif
177 #ifdef USE_DSM_SYSV
178  case DSM_IMPL_SYSV:
179  return dsm_impl_sysv(op, handle, request_size, impl_private,
180  mapped_address, mapped_size, elevel);
181 #endif
182 #ifdef USE_DSM_WINDOWS
183  case DSM_IMPL_WINDOWS:
184  return dsm_impl_windows(op, handle, request_size, impl_private,
185  mapped_address, mapped_size, elevel);
186 #endif
187 #ifdef USE_DSM_MMAP
188  case DSM_IMPL_MMAP:
189  return dsm_impl_mmap(op, handle, request_size, impl_private,
190  mapped_address, mapped_size, elevel);
191 #endif
192  default:
193  elog(ERROR, "unexpected dynamic shared memory type: %d",
195  return false;
196  }
197 }
#define DSM_IMPL_MMAP
Definition: dsm_impl.h:21
#define DSM_IMPL_SYSV
Definition: dsm_impl.h:19
#define DSM_IMPL_WINDOWS
Definition: dsm_impl.h:20
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:799
#define ERROR
Definition: elog.h:43
#define DSM_IMPL_POSIX
Definition: dsm_impl.h:18
int dynamic_shared_memory_type
Definition: dsm_impl.c:112
static int elevel
Definition: vacuumlazy.c:137
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:408
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define elog
Definition: elog.h:219
void dsm_impl_pin_segment ( dsm_handle  handle,
void *  impl_private,
void **  impl_private_pm_handle 
)

Definition at line 1009 of file dsm_impl.c.

References _dosmaperr(), DSM_IMPL_WINDOWS, dynamic_shared_memory_type, ereport, errcode_for_dynamic_shared_memory(), errmsg(), ERROR, FALSE, SEGMENT_NAME_PREFIX, and snprintf().

Referenced by dsm_pin_segment().

1011 {
1013  {
1014 #ifdef USE_DSM_WINDOWS
1015  case DSM_IMPL_WINDOWS:
1016  {
1017  HANDLE hmap;
1018 
1019  if (!DuplicateHandle(GetCurrentProcess(), impl_private,
1020  PostmasterHandle, &hmap, 0, FALSE,
1021  DUPLICATE_SAME_ACCESS))
1022  {
1023  char name[64];
1024 
1025  snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
1026  _dosmaperr(GetLastError());
1027  ereport(ERROR,
1029  errmsg("could not duplicate handle for \"%s\": %m",
1030  name)));
1031  }
1032 
1033  /*
1034  * Here, we remember the handle that we created in the
1035  * postmaster process. This handle isn't actually usable in
1036  * any process other than the postmaster, but that doesn't
1037  * matter. We're just holding onto it so that, if the segment
1038  * is unpinned, dsm_impl_unpin_segment can close it.
1039  */
1040  *impl_private_pm_handle = hmap;
1041  break;
1042  }
1043 #endif
1044  default:
1045  break;
1046  }
1047 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define DSM_IMPL_WINDOWS
Definition: dsm_impl.h:20
static int errcode_for_dynamic_shared_memory(void)
Definition: dsm_impl.c:1091
#define ERROR
Definition: elog.h:43
#define FALSE
Definition: c.h:221
#define SEGMENT_NAME_PREFIX
Definition: dsm_impl.c:117
int dynamic_shared_memory_type
Definition: dsm_impl.c:112
#define ereport(elevel, rest)
Definition: elog.h:122
void _dosmaperr(unsigned long)
Definition: win32error.c:171
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
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 408 of file dsm_impl.c.

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

Referenced by dsm_impl_op().

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

Definition at line 1059 of file dsm_impl.c.

References _dosmaperr(), DSM_IMPL_WINDOWS, dynamic_shared_memory_type, ereport, errcode_for_dynamic_shared_memory(), errmsg(), ERROR, FALSE, NULL, SEGMENT_NAME_PREFIX, and snprintf().

Referenced by dsm_unpin_segment().

1060 {
1062  {
1063 #ifdef USE_DSM_WINDOWS
1064  case DSM_IMPL_WINDOWS:
1065  {
1066  if (*impl_private &&
1067  !DuplicateHandle(PostmasterHandle, *impl_private,
1068  NULL, NULL, 0, FALSE,
1069  DUPLICATE_CLOSE_SOURCE))
1070  {
1071  char name[64];
1072 
1073  snprintf(name, 64, "%s.%u", SEGMENT_NAME_PREFIX, handle);
1074  _dosmaperr(GetLastError());
1075  ereport(ERROR,
1077  errmsg("could not duplicate handle for \"%s\": %m",
1078  name)));
1079  }
1080 
1081  *impl_private = NULL;
1082  break;
1083  }
1084 #endif
1085  default:
1086  break;
1087  }
1088 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define DSM_IMPL_WINDOWS
Definition: dsm_impl.h:20
static int errcode_for_dynamic_shared_memory(void)
Definition: dsm_impl.c:1091
#define ERROR
Definition: elog.h:43
#define FALSE
Definition: c.h:221
#define SEGMENT_NAME_PREFIX
Definition: dsm_impl.c:117
int dynamic_shared_memory_type
Definition: dsm_impl.c:112
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:229
void _dosmaperr(unsigned long)
Definition: win32error.c:171
const char * name
Definition: encode.c:521
int errmsg(const char *fmt,...)
Definition: elog.c:797
static int errcode_for_dynamic_shared_memory ( void  )
static

Definition at line 1091 of file dsm_impl.c.

References errcode(), and errcode_for_file_access().

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

1092 {
1093  if (errno == EFBIG || errno == ENOMEM)
1094  return errcode(ERRCODE_OUT_OF_MEMORY);
1095  else
1096  return errcode_for_file_access();
1097 }
int errcode(int sqlerrcode)
Definition: elog.c:575
int errcode_for_file_access(void)
Definition: elog.c:598

Variable Documentation

const struct config_enum_entry dynamic_shared_memory_options[]
Initial value:
= {
{"sysv", DSM_IMPL_SYSV, false},
{"mmap", DSM_IMPL_MMAP, false},
{"none", DSM_IMPL_NONE, false},
{NULL, 0, false}
}
#define DSM_IMPL_MMAP
Definition: dsm_impl.h:21
#define DSM_IMPL_SYSV
Definition: dsm_impl.h:19
#define NULL
Definition: c.h:229
#define DSM_IMPL_NONE
Definition: dsm_impl.h:17

Definition at line 94 of file dsm_impl.c.