Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  win32_sema.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * win32_sema.c
 *   Microsoft Windows Win32 Semaphores Emulation
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *   src/backend/port/win32_sema.c
 *
 *-------------------------------------------------------------------------
 */


#include "postgres.h"

#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/pg_sema.h"

static HANDLE *mySemSet;  /* IDs of sema sets acquired so far */
static int numSems;   /* number of sema sets acquired so far */
static int maxSems;   /* allocated size of mySemaSet array */

static void ReleaseSemaphores(int code, Datum arg);


/*
 * Report amount of shared memory needed for semaphores
 */

Size
PGSemaphoreShmemSize(int maxSemas)
{
 /* No shared memory needed on Windows */
 return 0;
}

/*
 * PGReserveSemaphores --- initialize semaphore support
 *
 * In the Win32 implementation, we acquire semaphores on-demand; the
 * maxSemas parameter is just used to size the array that keeps track of
 * acquired semas for subsequent releasing.  We use anonymous semaphores
 * so the semaphores are automatically freed when the last referencing
 * process exits.
 */

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

 on_shmem_exit(ReleaseSemaphores, 0);
}

/*
 * Release semaphores at shutdown or shmem reinitialization
 *
 * (called as an on_shmem_exit callback, hence funny argument list)
 */

static void
ReleaseSemaphores(int code, Datum arg)
{
 int   i;

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

/*
 * PGSemaphoreCreate
 *
 * Allocate a PGSemaphore structure with initial count 1
 */

PGSemaphore
PGSemaphoreCreate(void)
{
 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, 132767, NULL);
 if (cur_handle)
 {
  /* Successfully done */
  mySemSet[numSems++] = cur_handle;
 }
 else
  ereport(PANIC,
    (errmsg("could not create semaphore: error code %lu",
      GetLastError())));

 return (PGSemaphore) cur_handle;
}

/*
 * PGSemaphoreReset
 *
 * Reset a previously-initialized PGSemaphore to have count 0
 */

void
PGSemaphoreReset(PGSemaphore sema)
{
 /*
  * 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))
   /* loop */ ;
}

/*
 * PGSemaphoreLock
 *
 * Lock a semaphore (decrement count), blocking if count would be < 0.
 */

void
PGSemaphoreLock(PGSemaphore sema)
{
 HANDLE  wh[2];
 bool  done = false;

 /*
  * 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.
 */

 while (!done)
 {
  DWORD  rc;

  CHECK_FOR_INTERRUPTS();

  rc = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
  switch (rc)
  {
   case WAIT_OBJECT_0:
    /* Signal event is set - we have a signal to deliver */
    pgwin32_dispatch_queued_signals();
    break;
   case WAIT_OBJECT_0 + 1:
    /* We got it! */
    done = true;
    break;
   case WAIT_IO_COMPLETION:

    /*
     * The system interrupted the wait to execute an I/O
     * completion routine or asynchronous procedure call in this
     * thread.  PostgreSQL does not provoke either of these, but
     * atypical loaded DLLs or even other processes might do so.
     * Now, resume waiting.
 */

    break;
   case WAIT_FAILED:
    ereport(FATAL,
      (errmsg("could not lock semaphore: error code %lu",
        GetLastError())));
    break;
   default:
    elog(FATAL, "unexpected return code from WaitForMultipleObjectsEx(): %lu", rc);
    break;
  }
 }
}

/*
 * PGSemaphoreUnlock
 *
 * Unlock a semaphore (increment count)
 */

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

/*
 * PGSemaphoreTryLock
 *
 * Lock a semaphore only if able to do so without blocking
 */

bool
PGSemaphoreTryLock(PGSemaphore sema)
{
 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;
}

Messung V0.5 in Prozent
C=90 H=90 G=90

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142