#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().