36#ifndef HAVE_UNION_SEMUN
60#define SEMAS_PER_SET 19
62#define IPCProtection (0600)
64#define PGSemaMagic 537
107 int saved_errno = errno;
115 if (saved_errno == EEXIST || saved_errno == EACCES
117 || saved_errno ==
EIDRM
126 (
errmsg(
"could not create semaphores: %m"),
127 errdetail(
"Failed system call was semget(%lu, %d, 0%o).",
128 (
unsigned long) semKey,
numSems,
130 (saved_errno == ENOSPC) ?
131 errhint(
"This error does *not* mean that you have run out of disk space. "
132 "It occurs when either the system limit for the maximum number of "
133 "semaphore sets (SEMMNI), or the system wide maximum number of "
134 "semaphores (SEMMNS), would be exceeded. You need to raise the "
135 "respective kernel parameter. Alternatively, reduce PostgreSQL's "
136 "consumption of semaphores by reducing its \"max_connections\" parameter.\n"
137 "The PostgreSQL documentation contains more information about "
138 "configuring your system for PostgreSQL.") : 0));
155 int saved_errno = errno;
159 semId, semNum,
value),
160 (saved_errno == ERANGE) ?
161 errhint(
"You possibly need to raise your kernel's SEMVMX value to be at least "
162 "%d. Look into the PostgreSQL documentation for details.",
178 elog(
LOG,
"semctl(%d, 0, IPC_RMID, ...) failed: %m", semId);
189 return semctl(semId, semNum,
GETVAL, dummy);
200 return semctl(semId, semNum,
GETPID, dummy);
244 if (creatorPID != getpid())
246 if (
kill(creatorPID, 0) == 0 || errno != ESRCH)
281 mysema.semId = semId;
329 errmsg(
"could not stat data directory \"%s\": %m",
385 elog(
PANIC,
"too many semaphores created");
392 elog(
PANIC,
"too many semaphores created");
427 sops.sem_num = sema->
semNum;
440 errStatus = semop(sema->
semId, &sops, 1);
441 }
while (errStatus < 0 && errno ==
EINTR);
460 sops.sem_num = sema->
semNum;
470 errStatus = semop(sema->
semId, &sops, 1);
471 }
while (errStatus < 0 && errno ==
EINTR);
490 sops.sem_num = sema->
semNum;
499 errStatus = semop(sema->
semId, &sops, 1);
500 }
while (errStatus < 0 && errno ==
EINTR);
509#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
struct PGSemaphoreData * PGSemaphore
void * ShmemAllocUnlocked(Size size)
Size mul_size(Size s1, Size s2)
Size PGSemaphoreShmemSize(int maxSemas)
void PGSemaphoreUnlock(PGSemaphore sema)
struct PGSemaphoreData PGSemaphoreData
static pid_t IpcSemaphoreGetLastPID(IpcSemaphoreId semId, int semNum)
static int IpcSemaphoreGetValue(IpcSemaphoreId semId, int semNum)
void PGReserveSemaphores(int maxSemas)
static void IpcSemaphoreKill(IpcSemaphoreId semId)
static int maxSharedSemas
void PGSemaphoreReset(PGSemaphore sema)
void PGSemaphoreLock(PGSemaphore sema)
static IpcSemaphoreKey nextSemaKey
bool PGSemaphoreTryLock(PGSemaphore sema)
static int nextSemaNumber
static PGSemaphore sharedSemas
static IpcSemaphoreId InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
PGSemaphore PGSemaphoreCreate(void)
static int numSharedSemas
static void ReleaseSemaphores(int status, Datum arg)
static IpcSemaphoreId * mySemaSets
static IpcSemaphoreId IpcSemaphoreCreate(int numSems)
static void IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value)