PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_sema.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef struct PGSemaphoreDataPGSemaphore
 

Functions

void PGSemaphoreShmemRequest (int maxSemas)
 
void PGSemaphoreInit (int maxSemas)
 
PGSemaphore PGSemaphoreCreate (void)
 
void PGSemaphoreReset (PGSemaphore sema)
 
void PGSemaphoreLock (PGSemaphore sema)
 
void PGSemaphoreUnlock (PGSemaphore sema)
 
bool PGSemaphoreTryLock (PGSemaphore sema)
 

Typedef Documentation

◆ PGSemaphore

Definition at line 34 of file pg_sema.h.

Function Documentation

◆ PGSemaphoreCreate()

PGSemaphore PGSemaphoreCreate ( void  )
extern

Definition at line 255 of file posix_sema.c.

256{
257 PGSemaphore sema;
258 sem_t *newsem;
259
260 /* Can't do this in a backend, because static state is postmaster's */
262
263 if (numSems >= maxSems)
264 elog(PANIC, "too many semaphores created");
265
266#ifdef USE_NAMED_POSIX_SEMAPHORES
268 /* Remember new sema for ReleaseSemaphores */
270 sema = (PGSemaphore) newsem;
271#else
272 sema = &sharedSemas[numSems];
273 newsem = PG_SEM_REF(sema);
275#endif
276
277 numSems++;
278
279 return sema;
280}
#define Assert(condition)
Definition c.h:943
#define PANIC
Definition elog.h:44
#define elog(elevel,...)
Definition elog.h:228
bool IsUnderPostmaster
Definition globals.c:122
struct PGSemaphoreData * PGSemaphore
Definition pg_sema.h:34
static int maxSems
Definition posix_sema.c:67
static int numSems
Definition posix_sema.c:66
static PGSemaphore sharedSemas
Definition posix_sema.c:64
static void PosixSemaphoreCreate(sem_t *sem)
Definition posix_sema.c:135
#define PG_SEM_REF(x)
Definition posix_sema.c:57
static int fb(int x)

References Assert, elog, ereport, errmsg, fb(), IpcSemaphoreCreate(), IpcSemaphoreInitialize(), IsUnderPostmaster, maxSemaSets, maxSems, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaNumber, numSemaSets, numSems, numSems, numSharedSemas, PANIC, PG_SEM_REF, PosixSemaphoreCreate(), SEMAS_PER_SET, PGSemaphoreData::semId, PGSemaphoreData::semNum, sharedSemas, and sharedSemas.

Referenced by ProcGlobalShmemInit().

◆ PGSemaphoreInit()

void PGSemaphoreInit ( int  maxSemas)
extern

Definition at line 198 of file posix_sema.c.

199{
200 struct stat statbuf;
201
202 /*
203 * We use the data directory's inode number to seed the search for free
204 * semaphore keys. This minimizes the odds of collision with other
205 * postmasters, while maximizing the odds that we will detect and clean up
206 * semaphores left over from a crashed postmaster in our own directory.
207 */
208 if (stat(DataDir, &statbuf) < 0)
211 errmsg("could not stat data directory \"%s\": %m",
212 DataDir)));
213
214#ifdef USE_NAMED_POSIX_SEMAPHORES
215 mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *));
216 if (mySemPointers == NULL)
217 elog(PANIC, "out of memory");
218#endif
219
220 numSems = 0;
222 nextSemKey = statbuf.st_ino;
223
225}
int errcode_for_file_access(void)
Definition elog.c:897
#define FATAL
Definition elog.h:42
#define ereport(elevel,...)
Definition elog.h:152
char * DataDir
Definition globals.c:73
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
static char * errmsg
static int nextSemKey
Definition posix_sema.c:68
static void ReleaseSemaphores(int status, Datum arg)
Definition posix_sema.c:233
#define malloc(a)
#define stat
Definition win32_port.h:74

References DataDir, elog, ereport, errcode_for_file_access(), errmsg, FATAL, fb(), malloc, maxSemaSets, maxSems, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaKey, nextSemaNumber, nextSemKey, numSemaSets, numSems, numSems, numSharedSemas, on_shmem_exit(), PANIC, ReleaseSemaphores(), ReleaseSemaphores(), ReleaseSemaphores(), SEMAS_PER_SET, and stat.

Referenced by ProcGlobalShmemInit().

◆ PGSemaphoreLock()

void PGSemaphoreLock ( PGSemaphore  sema)
extern

Definition at line 313 of file posix_sema.c.

314{
315 int errStatus;
316
317 /* See notes in sysv_sema.c's implementation of PGSemaphoreLock. */
318 do
319 {
321 } while (errStatus < 0 && errno == EINTR);
322
323 if (errStatus < 0)
324 elog(FATAL, "sem_wait failed: %m");
325}
#define EINTR
Definition win32_port.h:361

References CHECK_FOR_INTERRUPTS, EINTR, elog, ereport, errmsg, FATAL, fb(), PG_SEM_REF, pgwin32_dispatch_queued_signals(), pgwin32_signal_event, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

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

◆ PGSemaphoreReset()

void PGSemaphoreReset ( PGSemaphore  sema)
extern

Definition at line 288 of file posix_sema.c.

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

References EAGAIN, EINTR, elog, FATAL, fb(), IpcSemaphoreInitialize(), PG_SEM_REF, PGSemaphoreTryLock(), PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by InitAuxiliaryProcess(), and InitProcess().

◆ PGSemaphoreShmemRequest()

void PGSemaphoreShmemRequest ( int  maxSemas)
extern

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#else
170 /* Need a PGSemaphoreData per semaphore */
171 ShmemRequestStruct(.name = "Semaphores",
172 .size = mul_size(maxSemas, sizeof(PGSemaphoreData)),
173 .ptr = (void **) &sharedSemas,
174 );
175#endif
176}
Size mul_size(Size s1, Size s2)
Definition shmem.c:1063
#define ShmemRequestStruct(...)
Definition shmem.h:176
const char * name

References fb(), mul_size(), name, sharedSemas, sharedSemas, and ShmemRequestStruct.

Referenced by ProcGlobalShmemRequest().

◆ PGSemaphoreTryLock()

bool PGSemaphoreTryLock ( PGSemaphore  sema)
extern

Definition at line 358 of file posix_sema.c.

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

References EAGAIN, EINTR, elog, ereport, errmsg, EWOULDBLOCK, FATAL, fb(), IPC_NOWAIT, PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by PGSemaphoreReset().

◆ PGSemaphoreUnlock()

void PGSemaphoreUnlock ( PGSemaphore  sema)
extern

Definition at line 333 of file posix_sema.c.

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

References EINTR, elog, ereport, errmsg, FATAL, fb(), PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by BufferLockAcquire(), BufferLockDequeueSelf(), BufferLockWakeup(), IpcSemaphoreCreate(), LWLockAcquire(), LWLockAcquireOrWait(), LWLockDequeueSelf(), LWLockUpdateVar(), LWLockWaitForVar(), LWLockWakeup(), ProcArrayGroupClearXid(), and TransactionGroupUpdateXidStatus().