Header And Logo

PostgreSQL
| The world's most advanced open source database.

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 PGSemaphoreData * PGSemaphore

Functions

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)

Typedef Documentation

typedef PGSemaphoreData* PGSemaphore

Definition at line 62 of file pg_sema.h.


Function Documentation

void PGReserveSemaphores ( int  maxSemas,
int  port 
)

Definition at line 154 of file posix_sema.c.

References elog, malloc, maxSemaSets, maxSems, mySemaSets, mySemPointers, mySemSet, nextSemaKey, nextSemaNumber, nextSemKey, NULL, numSemaSets, numSems, on_shmem_exit(), PANIC, ReleaseSemaphores(), and SEMAS_PER_SET.

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.

References Assert, elog, ereport, errmsg(), IpcSemaphoreCreate(), IpcSemaphoreInitialize(), IsUnderPostmaster, maxSemaSets, maxSems, mySemaSets, mySemPointers, mySemSet, nextSemaNumber, NULL, numSemaSets, numSems, PANIC, PosixSemaphoreCreate(), and SEMAS_PER_SET.

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.

References CHECK_FOR_INTERRUPTS, EINTR, elog, ereport, errmsg(), FALSE, FATAL, ImmediateInterruptOK, PG_SEM_REF, pgwin32_dispatch_queued_signals(), pgwin32_signal_event, and TRUE.

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.

References EAGAIN, EINTR, elog, FATAL, IpcSemaphoreInitialize(), PG_SEM_REF, and PGSemaphoreTryLock().

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.

References EAGAIN, EINTR, elog, ereport, errmsg(), EWOULDBLOCK, FATAL, and PG_SEM_REF.

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.

References EINTR, elog, ereport, errmsg(), FATAL, NULL, and PG_SEM_REF.

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");
}