PostgreSQL Source Code git master
Typedefs | Functions
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

Size  PGSemaphoreShmemSize (int maxSemas)
 
void  PGReserveSemaphores (int maxSemas)
 
 
 
 
 
 

Typedef Documentation

PGSemaphore

typedef struct PGSemaphoreData* PGSemaphore

Definition at line 34 of file pg_sema.h.

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:877
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define FATAL
Definition: elog.h:41
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
char * DataDir
Definition: globals.c:71
#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:238
Definition: win32_port.h:255
#define stat
Definition: win32_port.h:274

References DataDir, elog, ereport, errcode_for_file_access(), errmsg(), FATAL, malloc, maxSemaSets, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaKey, nextSemaNumber, nextSemKey, numSemaSets, numSems, numSharedSemas, on_shmem_exit(), PANIC, PGSemaphoreShmemSize(), ReleaseSemaphores(), SEMAS_PER_SET, 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}
bool IsUnderPostmaster
Definition: globals.c:120
Assert(PointerIsAligned(start, uint64))
static void PosixSemaphoreCreate(sem_t *sem)
Definition: posix_sema.c:135
#define PG_SEM_REF(x)
Definition: posix_sema.c:57

References Assert(), elog, ereport, errmsg(), IpcSemaphoreCreate(), IpcSemaphoreInitialize(), IsUnderPostmaster, maxSemaSets, maxSems, maxSharedSemas, mySemaSets, mySemSet, nextSemaNumber, numSemaSets, numSems, numSharedSemas, PANIC, PG_SEM_REF, PosixSemaphoreCreate(), SEMAS_PER_SET, PGSemaphoreData::semId, PGSemaphoreData::semNum, 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:364

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

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:362

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

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:510

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, ereport, errmsg(), EWOULDBLOCK, FATAL, IPC_NOWAIT, PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

Referenced by PGSemaphoreReset().

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, ereport, errmsg(), FATAL, PG_SEM_REF, PGSemaphoreData::semId, and PGSemaphoreData::semNum.

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

AltStyle によって変換されたページ (->オリジナル) /