#define IPCProtection (0600) /* access/modify by user only */
#define PGSemaMagic 537/* must be less than SEMVMX */
static PGSemaphore sharedSemas; /* array of PGSemaphoreData in shared memory */ staticint numSharedSemas; /* number of PGSemaphoreDatas used so far */ staticint maxSharedSemas; /* allocated size of PGSemaphoreData array */ static IpcSemaphoreId *mySemaSets; /* IDs of sema sets acquired so far */ staticint numSemaSets; /* number of sema sets acquired so far */ staticint maxSemaSets; /* allocated size of mySemaSets array */ static IpcSemaphoreKey nextSemaKey; /* next key to try using */ staticint nextSemaNumber; /* next free sem num in last sema set */
static IpcSemaphoreId InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems, bool retry_ok); staticvoid IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value); staticvoid IpcSemaphoreKill(IpcSemaphoreId semId); staticint IpcSemaphoreGetValue(IpcSemaphoreId semId, int semNum); static pid_t IpcSemaphoreGetLastPID(IpcSemaphoreId semId, int semNum); static IpcSemaphoreId IpcSemaphoreCreate(int numSems); staticvoid ReleaseSemaphores(int status, Datum arg);
/* *Elsecomplainandabort
*/
ereport(FATAL,
(errmsg("could not create semaphores: %m"),
errdetail("Failed system call was semget(%lu, %d, 0%o).",
(unsignedlong) semKey, numSems,
IPC_CREAT | IPC_EXCL | IPCProtection),
(saved_errno == ENOSPC) ?
errhint("This error does *not* mean that you have run out of disk space. " "It occurs when either the system limit for the maximum number of " "semaphore sets (SEMMNI), or the system wide maximum number of " "semaphores (SEMMNS), would be exceeded. You need to raise the " "respective kernel parameter. Alternatively, reduce PostgreSQL's " "consumption of semaphores by reducing its \"max_connections\" parameter.\n" "The PostgreSQL documentation contains more information about " "configuring your system for PostgreSQL.") : 0));
}
return semId;
}
/* *Initializeasemaphoretothespecifiedvalue.
*/ staticvoid
IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value)
{ union semun semun;
semun.val = value; if (semctl(semId, semNum, SETVAL, semun) < 0)
{ int saved_errno = errno;
ereport(FATAL,
(errmsg_internal("semctl(%d, %d, SETVAL, %d) failed: %m",
semId, semNum, value),
(saved_errno == ERANGE) ?
errhint("You possibly need to raise your kernel's SEMVMX value to be at least " "%d. Look into the PostgreSQL documentation for details.",
value) : 0));
}
}
/* *IpcSemaphoreKill(semId)-removesasemaphoreset
*/ staticvoid
IpcSemaphoreKill(IpcSemaphoreId semId)
{ union semun semun;
semun.val = 0; /* unused, but keep compiler quiet */
/* Get the current value (semval) of the semaphore */ staticint
IpcSemaphoreGetValue(IpcSemaphoreId semId, int semNum)
{ union semun dummy; /* for Solaris */
dummy.val = 0; /* unused */
return semctl(semId, semNum, GETVAL, dummy);
}
/* Get the PID of the last process to do semop() on the semaphore */ static pid_t
IpcSemaphoreGetLastPID(IpcSemaphoreId semId, int semNum)
{ union semun dummy; /* for Solaris */
/* See if it looks to be leftover from a dead Postgres process */
semId = semget(nextSemaKey, numSems + 1, 0); if (semId < 0) continue; /* failed: must be some other app's */ if (IpcSemaphoreGetValue(semId, numSems) != PGSemaMagic) continue; /* sema belongs to a non-Postgres app */
/* *IfthecreatorPIDismyownPIDordoesnotbelongtoanyextant *process,it'ssafetozapit.
*/
creatorPID = IpcSemaphoreGetLastPID(semId, numSems); if (creatorPID <= 0) continue; /* oops, GETPID failed */ if (creatorPID != getpid())
{ if (kill(creatorPID, 0) == 0 || errno != ESRCH) continue; /* sema belongs to a live process */
}
/* Can't do this in a backend, because static state is postmaster's */
Assert(!IsUnderPostmaster);
if (nextSemaNumber >= SEMAS_PER_SET)
{ /* Time to allocate another semaphore set */ if (numSemaSets >= maxSemaSets)
elog(PANIC, "too many semaphores created");
mySemaSets[numSemaSets] = IpcSemaphoreCreate(SEMAS_PER_SET);
numSemaSets++;
nextSemaNumber = 0;
} /* Use the next shared PGSemaphoreData */ if (numSharedSemas >= maxSharedSemas)
elog(PANIC, "too many semaphores created");
sema = &sharedSemas[numSharedSemas++]; /* Assign the next free semaphore in the current set */
sema->semId = mySemaSets[numSemaSets - 1];
sema->semNum = nextSemaNumber++; /* Initialize it to count 1 */
IpcSemaphoreInitialize(sema->semId, sema->semNum, 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.