Header And Logo

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

Functions | Variables

win32_sema.c File Reference

#include "postgres.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/pg_sema.h"
Include dependency graph for win32_sema.c:

Go to the source code of this file.

Functions

static void ReleaseSemaphores (int code, Datum arg)
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 HANDLE * mySemSet
static int numSems
static int maxSems

Function Documentation

void PGReserveSemaphores ( int  maxSemas,
int  port 
)

Definition at line 36 of file win32_sema.c.

References elog, malloc, maxSems, mySemPointers, mySemSet, nextSemKey, NULL, numSems, on_shmem_exit(), PANIC, and ReleaseSemaphores().

{
    mySemSet = (HANDLE *) malloc(maxSemas * sizeof(HANDLE));
    if (mySemSet == NULL)
        elog(PANIC, "out of memory");
    numSems = 0;
    maxSems = maxSemas;

    on_shmem_exit(ReleaseSemaphores, 0);
}

void PGSemaphoreCreate ( PGSemaphore  sema  ) 

Definition at line 68 of file win32_sema.c.

References Assert, elog, ereport, errmsg(), IsUnderPostmaster, maxSems, mySemPointers, mySemSet, NULL, numSems, PANIC, and PosixSemaphoreCreate().

{
    HANDLE      cur_handle;
    SECURITY_ATTRIBUTES sec_attrs;

    /* Can't do this in a backend, because static state is postmaster's */
    Assert(!IsUnderPostmaster);

    if (numSems >= maxSems)
        elog(PANIC, "too many semaphores created");

    ZeroMemory(&sec_attrs, sizeof(sec_attrs));
    sec_attrs.nLength = sizeof(sec_attrs);
    sec_attrs.lpSecurityDescriptor = NULL;
    sec_attrs.bInheritHandle = TRUE;

    /* We don't need a named semaphore */
    cur_handle = CreateSemaphore(&sec_attrs, 1, 32767, NULL);
    if (cur_handle)
    {
        /* Successfully done */
        *sema = cur_handle;
        mySemSet[numSems++] = cur_handle;
    }
    else
        ereport(PANIC,
                (errmsg("could not create semaphore: error code %lu", GetLastError())));
}

void PGSemaphoreLock ( PGSemaphore  sema,
bool  interruptOK 
)

Definition at line 119 of file win32_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.

{
    DWORD       ret;
    HANDLE      wh[2];

    /*
     * Note: pgwin32_signal_event should be first to ensure that it will be
     * reported when multiple events are set.  We want to guarantee that
     * pending signals are serviced.
     */
    wh[0] = pgwin32_signal_event;
    wh[1] = *sema;

    /*
     * As in other implementations of PGSemaphoreLock, we need to check for
     * cancel/die interrupts each time through the loop.  But here, there is
     * no hidden magic about whether the syscall will internally service a
     * signal --- we do that ourselves.
     */
    do
    {
        ImmediateInterruptOK = interruptOK;
        CHECK_FOR_INTERRUPTS();

        ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);

        if (ret == WAIT_OBJECT_0)
        {
            /* Signal event is set - we have a signal to deliver */
            pgwin32_dispatch_queued_signals();
            errno = EINTR;
        }
        else if (ret == WAIT_OBJECT_0 + 1)
        {
            /* We got it! */
            errno = 0;
        }
        else
            /* Otherwise we are in trouble */
            errno = EIDRM;

        ImmediateInterruptOK = false;
    } while (errno == EINTR);

    if (errno != 0)
        ereport(FATAL,
        (errmsg("could not lock semaphore: error code %lu", GetLastError())));
}

void PGSemaphoreReset ( PGSemaphore  sema  ) 

Definition at line 103 of file win32_sema.c.

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

{
    /*
     * There's no direct API for this in Win32, so we have to ratchet the
     * semaphore down to 0 with repeated trylock's.
     */
    while (PGSemaphoreTryLock(sema));
}

bool PGSemaphoreTryLock ( PGSemaphore  sema  ) 

Definition at line 187 of file win32_sema.c.

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

{
    DWORD       ret;

    ret = WaitForSingleObject(*sema, 0);

    if (ret == WAIT_OBJECT_0)
    {
        /* We got it! */
        return true;
    }
    else if (ret == WAIT_TIMEOUT)
    {
        /* Can't get it */
        errno = EAGAIN;
        return false;
    }

    /* Otherwise we are in trouble */
    ereport(FATAL,
    (errmsg("could not try-lock semaphore: error code %lu", GetLastError())));

    /* keep compiler quiet */
    return false;
}

void PGSemaphoreUnlock ( PGSemaphore  sema  ) 

Definition at line 174 of file win32_sema.c.

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

{
    if (!ReleaseSemaphore(*sema, 1, NULL))
        ereport(FATAL,
                (errmsg("could not unlock semaphore: error code %lu", GetLastError())));
}

static void ReleaseSemaphores ( int  code,
Datum  arg 
) [static]

Definition at line 53 of file win32_sema.c.

References free, i, mySemSet, and numSems.

Referenced by PGReserveSemaphores().

{
    int         i;

    for (i = 0; i < numSems; i++)
        CloseHandle(mySemSet[i]);
    free(mySemSet);
}


Variable Documentation

int maxSems [static]

Definition at line 22 of file win32_sema.c.

Referenced by PGReserveSemaphores(), and PGSemaphoreCreate().

HANDLE* mySemSet [static]

Definition at line 20 of file win32_sema.c.

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

int numSems [static]

Definition at line 21 of file win32_sema.c.

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