PostgreSQL Source Code  git master
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)
 
Size PGSemaphoreShmemSize (int maxSemas)
 
void PGReserveSemaphores (int maxSemas)
 
PGSemaphore PGSemaphoreCreate (void)
 
void PGSemaphoreReset (PGSemaphore sema)
 
void PGSemaphoreLock (PGSemaphore sema)
 
void PGSemaphoreUnlock (PGSemaphore sema)
 
bool PGSemaphoreTryLock (PGSemaphore sema)
 

Variables

static HANDLE * mySemSet
 
static int numSems
 
static int maxSems
 

Function Documentation

◆ PGReserveSemaphores()

void PGReserveSemaphores ( int  maxSemas)

Definition at line 47 of file win32_sema.c.

References DataDir, elog, ereport, errcode_for_file_access(), errmsg(), FATAL, malloc, maxSems, mySemSet, nextSemKey, numSems, on_shmem_exit(), PANIC, PGSemaphoreShmemSize(), ReleaseSemaphores(), ShmemAllocUnlocked(), and stat.

48 {
49  mySemSet = (HANDLE *) malloc(maxSemas * sizeof(HANDLE));
50  if (mySemSet == NULL)
51  elog(PANIC, "out of memory");
52  numSems = 0;
53  maxSems = maxSemas;
54 
56 }
static int numSems
Definition: win32_sema.c:21
#define PANIC
Definition: elog.h:53
static int maxSems
Definition: win32_sema.c:22
#define malloc(a)
Definition: header.h:50
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
static HANDLE * mySemSet
Definition: win32_sema.c:20
static void ReleaseSemaphores(int code, Datum arg)
Definition: win32_sema.c:64
#define elog(elevel,...)
Definition: elog.h:226

◆ PGSemaphoreCreate()

PGSemaphore PGSemaphoreCreate ( void  )

Definition at line 79 of file win32_sema.c.

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

80 {
81  HANDLE cur_handle;
82  SECURITY_ATTRIBUTES sec_attrs;
83 
84  /* Can't do this in a backend, because static state is postmaster's */
86 
87  if (numSems >= maxSems)
88  elog(PANIC, "too many semaphores created");
89 
90  ZeroMemory(&sec_attrs, sizeof(sec_attrs));
91  sec_attrs.nLength = sizeof(sec_attrs);
92  sec_attrs.lpSecurityDescriptor = NULL;
93  sec_attrs.bInheritHandle = TRUE;
94 
95  /* We don't need a named semaphore */
96  cur_handle = CreateSemaphore(&sec_attrs, 1, 32767, NULL);
97  if (cur_handle)
98  {
99  /* Successfully done */
100  mySemSet[numSems++] = cur_handle;
101  }
102  else
103  ereport(PANIC,
104  (errmsg("could not create semaphore: error code %lu",
105  GetLastError())));
106 
107  return (PGSemaphore) cur_handle;
108 }
static int numSems
Definition: win32_sema.c:21
#define TRUE
Definition: ecpglib.h:35
#define PANIC
Definition: elog.h:53
static int maxSems
Definition: win32_sema.c:22
bool IsUnderPostmaster
Definition: globals.c:109
static HANDLE * mySemSet
Definition: win32_sema.c:20
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226

◆ PGSemaphoreLock()

void PGSemaphoreLock ( PGSemaphore  sema)

Definition at line 132 of file win32_sema.c.

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

133 {
134  HANDLE wh[2];
135  bool done = false;
136 
137  /*
138  * Note: pgwin32_signal_event should be first to ensure that it will be
139  * reported when multiple events are set. We want to guarantee that
140  * pending signals are serviced.
141  */
142  wh[0] = pgwin32_signal_event;
143  wh[1] = sema;
144 
145  /*
146  * As in other implementations of PGSemaphoreLock, we need to check for
147  * cancel/die interrupts each time through the loop. But here, there is
148  * no hidden magic about whether the syscall will internally service a
149  * signal --- we do that ourselves.
150  */
151  while (!done)
152  {
153  DWORD rc;
154 
156 
157  rc = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
158  switch (rc)
159  {
160  case WAIT_OBJECT_0:
161  /* Signal event is set - we have a signal to deliver */
163  break;
164  case WAIT_OBJECT_0 + 1:
165  /* We got it! */
166  done = true;
167  break;
168  case WAIT_IO_COMPLETION:
169 
170  /*
171  * The system interrupted the wait to execute an I/O
172  * completion routine or asynchronous procedure call in this
173  * thread. PostgreSQL does not provoke either of these, but
174  * atypical loaded DLLs or even other processes might do so.
175  * Now, resume waiting.
176  */
177  break;
178  case WAIT_FAILED:
179  ereport(FATAL,
180  (errmsg("could not lock semaphore: error code %lu",
181  GetLastError())));
182  break;
183  default:
184  elog(FATAL, "unexpected return code from WaitForMultipleObjectsEx(): %lu", rc);
185  break;
186  }
187  }
188 }
#define TRUE
Definition: ecpglib.h:35
#define FALSE
Definition: ecpglib.h:39
HANDLE pgwin32_signal_event
Definition: signal.c:27
void pgwin32_dispatch_queued_signals(void)
Definition: signal.c:108
#define FATAL
Definition: elog.h:52
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99

◆ PGSemaphoreReset()

void PGSemaphoreReset ( PGSemaphore  sema)

Definition at line 116 of file win32_sema.c.

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

117 {
118  /*
119  * There's no direct API for this in Win32, so we have to ratchet the
120  * semaphore down to 0 with repeated trylock's.
121  */
122  while (PGSemaphoreTryLock(sema))
123  /* loop */ ;
124 }
bool PGSemaphoreTryLock(PGSemaphore sema)
Definition: win32_sema.c:210

◆ PGSemaphoreShmemSize()

Size PGSemaphoreShmemSize ( int  maxSemas)

Definition at line 31 of file win32_sema.c.

References mul_size().

32 {
33  /* No shared memory needed on Windows */
34  return 0;
35 }

◆ PGSemaphoreTryLock()

bool PGSemaphoreTryLock ( PGSemaphore  sema)

Definition at line 210 of file win32_sema.c.

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

Referenced by PGSemaphoreReset().

211 {
212  DWORD ret;
213 
214  ret = WaitForSingleObject(sema, 0);
215 
216  if (ret == WAIT_OBJECT_0)
217  {
218  /* We got it! */
219  return true;
220  }
221  else if (ret == WAIT_TIMEOUT)
222  {
223  /* Can't get it */
224  errno = EAGAIN;
225  return false;
226  }
227 
228  /* Otherwise we are in trouble */
229  ereport(FATAL,
230  (errmsg("could not try-lock semaphore: error code %lu",
231  GetLastError())));
232 
233  /* keep compiler quiet */
234  return false;
235 }
#define EAGAIN
Definition: win32_port.h:321
#define FATAL
Definition: elog.h:52
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ PGSemaphoreUnlock()

void PGSemaphoreUnlock ( PGSemaphore  sema)

Definition at line 196 of file win32_sema.c.

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

197 {
198  if (!ReleaseSemaphore(sema, 1, NULL))
199  ereport(FATAL,
200  (errmsg("could not unlock semaphore: error code %lu",
201  GetLastError())));
202 }
#define FATAL
Definition: elog.h:52
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ ReleaseSemaphores()

static void ReleaseSemaphores ( int  code,
Datum  arg 
)
static

Definition at line 64 of file win32_sema.c.

References free, i, mySemSet, and numSems.

Referenced by PGReserveSemaphores().

65 {
66  int i;
67 
68  for (i = 0; i < numSems; i++)
69  CloseHandle(mySemSet[i]);
70  free(mySemSet);
71 }
static int numSems
Definition: win32_sema.c:21
static HANDLE * mySemSet
Definition: win32_sema.c:20
#define free(a)
Definition: header.h:65
int i

Variable Documentation

◆ maxSems

int maxSems
static

Definition at line 22 of file win32_sema.c.

Referenced by PGReserveSemaphores(), and PGSemaphoreCreate().

◆ mySemSet

HANDLE* mySemSet
static

Definition at line 20 of file win32_sema.c.

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

◆ numSems

int numSems
static

Definition at line 21 of file win32_sema.c.

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