PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
posix_sema.c File Reference
#include "postgres.h"
#include <fcntl.h>
#include <semaphore.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/pg_sema.h"
#include "storage/shmem.h"
Include dependency graph for posix_sema.c:

Go to the source code of this file.

Data Structures

union  SemTPadded
 
struct  PGSemaphoreData
 

Macros

#define PG_SEM_REF(x)   (&(x)->sem_padded.pgsem)
 
#define IPCProtection   (0600) /* access/modify by user only */
 

Typedefs

typedef union SemTPadded SemTPadded
 
typedef struct PGSemaphoreData PGSemaphoreData
 

Functions

static void ReleaseSemaphores (int status, Datum arg)
 
static void PosixSemaphoreCreate (sem_t *sem)
 
static void PosixSemaphoreKill (sem_t *sem)
 
Size PGSemaphoreShmemSize (int maxSemas)
 
void PGReserveSemaphores (int maxSemas)
 
PGSemaphore PGSemaphoreCreate (void)
 
void PGSemaphoreReset (PGSemaphore sema)
 
void PGSemaphoreLock (PGSemaphore sema)
 
void PGSemaphoreUnlock (PGSemaphore sema)
 
bool PGSemaphoreTryLock (PGSemaphore sema)
 

Variables

static PGSemaphore sharedSemas
 
static int numSems
 
static int maxSems
 
static int nextSemKey
 

Macro Definition Documentation

◆ IPCProtection

#define IPCProtection   (0600) /* access/modify by user only */

Definition at line 59 of file posix_sema.c.

◆ PG_SEM_REF

#define PG_SEM_REF (   x)    (&(x)->sem_padded.pgsem)

Definition at line 57 of file posix_sema.c.

Typedef Documentation

◆ PGSemaphoreData

◆ SemTPadded

typedef union SemTPadded SemTPadded

Function Documentation

◆ PGReserveSemaphores()

void PGReserveSemaphores ( int  maxSemas)

Definition at line 196 of file posix_sema.c.

197{
198 struct stat statbuf;
199
200 /*
201 * We use the data directory's inode number to seed the search for free
202 * semaphore keys. This minimizes the odds of collision with other
203 * postmasters, while maximizing the odds that we will detect and clean up
204 * semaphores left over from a crashed postmaster in our own directory.
205 */
206 if (stat(DataDir, &statbuf) < 0)
209 errmsg("could not stat data directory \"%s\": %m",
210 DataDir)));
211
212#ifdef USE_NAMED_POSIX_SEMAPHORES
213 mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *));
214 if (mySemPointers == NULL)
215 elog(PANIC, "out of memory");
216#else
217
218 /*
219 * We must use ShmemAllocUnlocked(), since the spinlock protecting
220 * ShmemAlloc() won't be ready yet.
221 */
224#endif
225
226 numSems = 0;
227 maxSems = maxSemas;
228 nextSemKey = statbuf.st_ino;
229
231}
int errcode_for_file_access(void)
Definition: elog.c:876
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define FATAL
Definition: elog.h:41
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
char * DataDir
Definition: globals.c:70
#define malloc(a)
Definition: header.h:50
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
struct PGSemaphoreData * PGSemaphore
Definition: pg_sema.h:34
Size PGSemaphoreShmemSize(int maxSemas)
Definition: posix_sema.c:165
static int maxSems
Definition: posix_sema.c:67
static int nextSemKey
Definition: posix_sema.c:68
static int numSems
Definition: posix_sema.c:66
static PGSemaphore sharedSemas
Definition: posix_sema.c:64
static void ReleaseSemaphores(int status, Datum arg)
Definition: posix_sema.c:239
void * ShmemAllocUnlocked(Size size)
Definition: shmem.c:233
#define stat
Definition: win32_port.h:284

References DataDir, elog, ereport, errcode_for_file_access(), errmsg(), FATAL, malloc, maxSems, nextSemKey, numSems, on_shmem_exit(), PANIC, PGSemaphoreShmemSize(), ReleaseSemaphores(), sharedSemas, ShmemAllocUnlocked(), stat::st_ino, and stat.

Referenced by CreateSharedMemoryAndSemaphores().

◆ PGSemaphoreCreate()

PGSemaphore PGSemaphoreCreate ( void  )

Definition at line 261 of file posix_sema.c.

262{
263 PGSemaphore sema;
264 sem_t *newsem;
265
266 /* Can't do this in a backend, because static state is postmaster's */
268
269 if (numSems >= maxSems)
270 elog(PANIC, "too many semaphores created");
271
272#ifdef USE_NAMED_POSIX_SEMAPHORES
273 newsem = PosixSemaphoreCreate();
274 /* Remember new sema for ReleaseSemaphores */
275 mySemPointers[numSems] = newsem;
276 sema = (PGSemaphore) newsem;
277#else
278 sema = &sharedSemas[numSems];
279 newsem = PG_SEM_REF(sema);
280 PosixSemaphoreCreate(newsem);
281#endif
282
283 numSems++;
284
285 return sema;
286}
#define Assert(condition)
Definition: c.h:812
bool IsUnderPostmaster
Definition: globals.c:119
static void PosixSemaphoreCreate(sem_t *sem)
Definition: posix_sema.c:135
#define PG_SEM_REF(x)
Definition: posix_sema.c:57

References Assert, elog, IsUnderPostmaster, maxSems, numSems, PANIC, PG_SEM_REF, PosixSemaphoreCreate(), and sharedSemas.

Referenced by InitProcGlobal().

◆ PGSemaphoreLock()

void PGSemaphoreLock ( PGSemaphore  sema)

Definition at line 319 of file posix_sema.c.

320{
321 int errStatus;
322
323 /* See notes in sysv_sema.c's implementation of PGSemaphoreLock. */
324 do
325 {
326 errStatus = sem_wait(PG_SEM_REF(sema));
327 } while (errStatus < 0 && errno == EINTR);
328
329 if (errStatus < 0)
330 elog(FATAL, "sem_wait failed: %m");
331}
#define EINTR
Definition: win32_port.h:374

References EINTR, elog, FATAL, and PG_SEM_REF.

Referenced by LWLockAcquire(), LWLockAcquireOrWait(), LWLockDequeueSelf(), LWLockWaitForVar(), ProcArrayGroupClearXid(), and TransactionGroupUpdateXidStatus().

◆ PGSemaphoreReset()

void PGSemaphoreReset ( PGSemaphore  sema)

Definition at line 294 of file posix_sema.c.

295{
296 /*
297 * There's no direct API for this in POSIX, so we have to ratchet the
298 * semaphore down to 0 with repeated trywait's.
299 */
300 for (;;)
301 {
302 if (sem_trywait(PG_SEM_REF(sema)) < 0)
303 {
304 if (errno == EAGAIN || errno == EDEADLK)
305 break; /* got it down to 0 */
306 if (errno == EINTR)
307 continue; /* can this happen? */
308 elog(FATAL, "sem_trywait failed: %m");
309 }
310 }
311}
#define EAGAIN
Definition: win32_port.h:372

References EAGAIN, EINTR, elog, FATAL, and PG_SEM_REF.

Referenced by InitAuxiliaryProcess(), and InitProcess().

◆ PGSemaphoreShmemSize()

Size PGSemaphoreShmemSize ( int  maxSemas)

Definition at line 165 of file posix_sema.c.

166{
167#ifdef USE_NAMED_POSIX_SEMAPHORES
168 /* No shared memory needed in this case */
169 return 0;
170#else
171 /* Need a PGSemaphoreData per semaphore */
172 return mul_size(maxSemas, sizeof(PGSemaphoreData));
173#endif
174}
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505

References mul_size().

Referenced by CalculateShmemSize(), and PGReserveSemaphores().

◆ PGSemaphoreTryLock()

bool PGSemaphoreTryLock ( PGSemaphore  sema)

Definition at line 364 of file posix_sema.c.

365{
366 int errStatus;
367
368 /*
369 * Note: if errStatus is -1 and errno == EINTR then it means we returned
370 * from the operation prematurely because we were sent a signal. So we
371 * try and lock the semaphore again.
372 */
373 do
374 {
375 errStatus = sem_trywait(PG_SEM_REF(sema));
376 } while (errStatus < 0 && errno == EINTR);
377
378 if (errStatus < 0)
379 {
380 if (errno == EAGAIN || errno == EDEADLK)
381 return false; /* failed to lock it */
382 /* Otherwise we got trouble */
383 elog(FATAL, "sem_trywait failed: %m");
384 }
385
386 return true;
387}

References EAGAIN, EINTR, elog, FATAL, and PG_SEM_REF.

◆ PGSemaphoreUnlock()

void PGSemaphoreUnlock ( PGSemaphore  sema)

Definition at line 339 of file posix_sema.c.

340{
341 int errStatus;
342
343 /*
344 * Note: if errStatus is -1 and errno == EINTR then it means we returned
345 * from the operation prematurely because we were sent a signal. So we
346 * try and unlock the semaphore again. Not clear this can really happen,
347 * but might as well cope.
348 */
349 do
350 {
351 errStatus = sem_post(PG_SEM_REF(sema));
352 } while (errStatus < 0 && errno == EINTR);
353
354 if (errStatus < 0)
355 elog(FATAL, "sem_post failed: %m");
356}

References EINTR, elog, FATAL, and PG_SEM_REF.

Referenced by LWLockAcquire(), LWLockAcquireOrWait(), LWLockDequeueSelf(), LWLockUpdateVar(), LWLockWaitForVar(), LWLockWakeup(), ProcArrayGroupClearXid(), and TransactionGroupUpdateXidStatus().

◆ PosixSemaphoreCreate()

static void PosixSemaphoreCreate ( sem_t *  sem)
static

Definition at line 135 of file posix_sema.c.

136{
137 if (sem_init(sem, 1, 1) < 0)
138 elog(FATAL, "sem_init failed: %m");
139}
static JsonSemAction sem

References elog, FATAL, and sem.

Referenced by PGSemaphoreCreate().

◆ PosixSemaphoreKill()

static void PosixSemaphoreKill ( sem_t *  sem)
static

Definition at line 147 of file posix_sema.c.

148{
149#ifdef USE_NAMED_POSIX_SEMAPHORES
150 /* Got to use sem_close for named semaphores */
151 if (sem_close(sem) < 0)
152 elog(LOG, "sem_close failed: %m");
153#else
154 /* Got to use sem_destroy for unnamed semaphores */
155 if (sem_destroy(sem) < 0)
156 elog(LOG, "sem_destroy failed: %m");
157#endif
158}
#define LOG
Definition: elog.h:31

References elog, LOG, and sem.

Referenced by ReleaseSemaphores().

◆ ReleaseSemaphores()

static void ReleaseSemaphores ( int  status,
Datum  arg 
)
static

Definition at line 239 of file posix_sema.c.

240{
241 int i;
242
243#ifdef USE_NAMED_POSIX_SEMAPHORES
244 for (i = 0; i < numSems; i++)
245 PosixSemaphoreKill(mySemPointers[i]);
246 free(mySemPointers);
247#endif
248
249#ifdef USE_UNNAMED_POSIX_SEMAPHORES
250 for (i = 0; i < numSems; i++)
252#endif
253}
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:72
static void PosixSemaphoreKill(sem_t *sem)
Definition: posix_sema.c:147

References free, i, numSems, PG_SEM_REF, PosixSemaphoreKill(), and sharedSemas.

Referenced by PGReserveSemaphores().

Variable Documentation

◆ maxSems

int maxSems
static

Definition at line 67 of file posix_sema.c.

Referenced by PGReserveSemaphores(), and PGSemaphoreCreate().

◆ nextSemKey

int nextSemKey
static

Definition at line 68 of file posix_sema.c.

Referenced by PGReserveSemaphores().

◆ numSems

◆ sharedSemas

PGSemaphore sharedSemas
static

Definition at line 64 of file posix_sema.c.

Referenced by PGReserveSemaphores(), PGSemaphoreCreate(), and ReleaseSemaphores().