#include "postgres.h"#include <fcntl.h>#include <signal.h>#include <unistd.h>#include "miscadmin.h"#include "storage/ipc.h"#include "storage/pg_sema.h"
Go to the source code of this file.
Defines | |
| #define | PG_SEM_REF(x) (x) |
| #define | IPCProtection (0600) |
Functions | |
| static void | ReleaseSemaphores (int status, Datum arg) |
| static void | PosixSemaphoreCreate (sem_t *sem) |
| static void | PosixSemaphoreKill (sem_t *sem) |
| void | PGReserveSemaphores (int maxSemas, int port) |
| void | PGSemaphoreCreate (PGSemaphore sema) |
| void | PGSemaphoreReset (PGSemaphore sema) |
| void | PGSemaphoreLock (PGSemaphore sema, bool interruptOK) |
| void | PGSemaphoreUnlock (PGSemaphore sema) |
| bool | PGSemaphoreTryLock (PGSemaphore sema) |
Variables | |
| static sem_t ** | mySemPointers |
| static int | numSems |
| static int | maxSems |
| static int | nextSemKey |
| #define IPCProtection (0600) |
Definition at line 38 of file posix_sema.c.
| #define PG_SEM_REF | ( | x | ) | (x) |
Definition at line 34 of file posix_sema.c.
Referenced by PGSemaphoreLock(), PGSemaphoreReset(), PGSemaphoreTryLock(), and PGSemaphoreUnlock().
| void PGReserveSemaphores | ( | int | maxSemas, | |
| int | port | |||
| ) |
Definition at line 154 of file posix_sema.c.
Referenced by CreateSharedMemoryAndSemaphores(), and main().
{
mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *));
if (mySemPointers == NULL)
elog(PANIC, "out of memory");
numSems = 0;
maxSems = maxSemas;
nextSemKey = port * 1000;
on_shmem_exit(ReleaseSemaphores, 0);
}
| void PGSemaphoreCreate | ( | PGSemaphore | sema | ) |
Definition at line 187 of file posix_sema.c.
Referenced by InitProcGlobal(), main(), and s_init_lock_sema().
{
sem_t *newsem;
/* Can't do this in a backend, because static state is postmaster's */
Assert(!IsUnderPostmaster);
if (numSems >= maxSems)
elog(PANIC, "too many semaphores created");
#ifdef USE_NAMED_POSIX_SEMAPHORES
*sema = newsem = PosixSemaphoreCreate();
#else
PosixSemaphoreCreate(sema);
newsem = sema;
#endif
/* Remember new sema for ReleaseSemaphores */
mySemPointers[numSems++] = newsem;
}
| void PGSemaphoreLock | ( | PGSemaphore | sema, | |
| bool | interruptOK | |||
| ) |
Definition at line 239 of file posix_sema.c.
Referenced by LWLockAcquire(), LWLockAcquireOrWait(), main(), ProcSleep(), and ProcWaitForSignal().
{
int errStatus;
/*
* See notes in sysv_sema.c's implementation of PGSemaphoreLock. Just as
* that code does for semop(), we handle both the case where sem_wait()
* returns errno == EINTR after a signal, and the case where it just keeps
* waiting.
*/
do
{
ImmediateInterruptOK = interruptOK;
CHECK_FOR_INTERRUPTS();
errStatus = sem_wait(PG_SEM_REF(sema));
ImmediateInterruptOK = false;
} while (errStatus < 0 && errno == EINTR);
if (errStatus < 0)
elog(FATAL, "sem_wait failed: %m");
}
| void PGSemaphoreReset | ( | PGSemaphore | sema | ) |
Definition at line 214 of file posix_sema.c.
Referenced by InitAuxiliaryProcess(), InitProcess(), and main().
{
/*
* There's no direct API for this in POSIX, so we have to ratchet the
* semaphore down to 0 with repeated trywait's.
*/
for (;;)
{
if (sem_trywait(PG_SEM_REF(sema)) < 0)
{
if (errno == EAGAIN || errno == EDEADLK)
break; /* got it down to 0 */
if (errno == EINTR)
continue; /* can this happen? */
elog(FATAL, "sem_trywait failed: %m");
}
}
}
| bool PGSemaphoreTryLock | ( | PGSemaphore | sema | ) |
Definition at line 292 of file posix_sema.c.
Referenced by main(), PGSemaphoreReset(), and tas_sema().
{
int errStatus;
/*
* Note: if errStatus is -1 and errno == EINTR then it means we returned
* from the operation prematurely because we were sent a signal. So we
* try and lock the semaphore again.
*/
do
{
errStatus = sem_trywait(PG_SEM_REF(sema));
} while (errStatus < 0 && errno == EINTR);
if (errStatus < 0)
{
if (errno == EAGAIN || errno == EDEADLK)
return false; /* failed to lock it */
/* Otherwise we got trouble */
elog(FATAL, "sem_trywait failed: %m");
}
return true;
}
| void PGSemaphoreUnlock | ( | PGSemaphore | sema | ) |
Definition at line 267 of file posix_sema.c.
Referenced by CheckDeadLock(), IpcSemaphoreCreate(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockRelease(), main(), ProcSendSignal(), ProcWakeup(), and s_unlock_sema().
{
int errStatus;
/*
* Note: if errStatus is -1 and errno == EINTR then it means we returned
* from the operation prematurely because we were sent a signal. So we
* try and unlock the semaphore again. Not clear this can really happen,
* but might as well cope.
*/
do
{
errStatus = sem_post(PG_SEM_REF(sema));
} while (errStatus < 0 && errno == EINTR);
if (errStatus < 0)
elog(FATAL, "sem_post failed: %m");
}
| static void PosixSemaphoreCreate | ( | sem_t * | sem | ) | [static] |
Definition at line 110 of file posix_sema.c.
Referenced by PGSemaphoreCreate().
| static void PosixSemaphoreKill | ( | sem_t * | sem | ) | [static] |
Definition at line 122 of file posix_sema.c.
Referenced by ReleaseSemaphores().
| static void ReleaseSemaphores | ( | int | status, | |
| Datum | arg | |||
| ) | [static] |
Definition at line 172 of file posix_sema.c.
References free, i, mySemPointers, numSems, and PosixSemaphoreKill().
Referenced by PGReserveSemaphores().
{
int i;
for (i = 0; i < numSems; i++)
PosixSemaphoreKill(mySemPointers[i]);
free(mySemPointers);
}
int maxSems [static] |
Definition at line 42 of file posix_sema.c.
Referenced by PGReserveSemaphores(), and PGSemaphoreCreate().
sem_t** mySemPointers [static] |
Definition at line 40 of file posix_sema.c.
Referenced by PGReserveSemaphores(), PGSemaphoreCreate(), and ReleaseSemaphores().
int nextSemKey [static] |
Definition at line 43 of file posix_sema.c.
Referenced by PGReserveSemaphores().
int numSems [static] |
Definition at line 41 of file posix_sema.c.
Referenced by PGReserveSemaphores(), PGSemaphoreCreate(), and ReleaseSemaphores().
1.7.1