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.

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 }
#define PANIC
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:218
#define malloc(a)
Definition: header.h:50
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
static int maxSems
Definition: win32_sema.c:22
static int numSems
Definition: win32_sema.c:21
static HANDLE * mySemSet
Definition: win32_sema.c:20
static void ReleaseSemaphores(int code, Datum arg)
Definition: win32_sema.c:64

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

◆ PGSemaphoreCreate()

PGSemaphore PGSemaphoreCreate ( void  )

Definition at line 79 of file win32_sema.c.

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 }
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ereport(elevel,...)
Definition: elog.h:143
bool IsUnderPostmaster
Definition: globals.c:113
Assert(fmt[strlen(fmt) - 1] !='\n')

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

◆ PGSemaphoreLock()

void PGSemaphoreLock ( PGSemaphore  sema)

Definition at line 132 of file win32_sema.c.

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 FATAL
Definition: elog.h:35
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
void pgwin32_dispatch_queued_signals(void)
Definition: signal.c:118
HANDLE pgwin32_signal_event
Definition: signal.c:27

References CHECK_FOR_INTERRUPTS, elog, ereport, errmsg(), FATAL, pgwin32_dispatch_queued_signals(), and pgwin32_signal_event.

◆ PGSemaphoreReset()

void PGSemaphoreReset ( PGSemaphore  sema)

Definition at line 116 of file win32_sema.c.

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

References PGSemaphoreTryLock().

◆ PGSemaphoreShmemSize()

Size PGSemaphoreShmemSize ( int  maxSemas)

Definition at line 31 of file win32_sema.c.

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.

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

References EAGAIN, ereport, errmsg(), and FATAL.

Referenced by PGSemaphoreReset().

◆ PGSemaphoreUnlock()

void PGSemaphoreUnlock ( PGSemaphore  sema)

Definition at line 196 of file win32_sema.c.

197 {
198  if (!ReleaseSemaphore(sema, 1, NULL))
199  ereport(FATAL,
200  (errmsg("could not unlock semaphore: error code %lu",
201  GetLastError())));
202 }

References ereport, errmsg(), and FATAL.

◆ ReleaseSemaphores()

static void ReleaseSemaphores ( int  code,
Datum  arg 
)
static

Definition at line 64 of file win32_sema.c.

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

References free, i, mySemSet, and numSems.

Referenced by PGReserveSemaphores().

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().