PostgreSQL Source Code: src/backend/port/win32/signal.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
17
18
19
20
21
22
23
26
29
30
31
32
33
35
36
39
40
41
44
45
46
47
48
49
50
51
52void
54{
56 {
57
58
59
60
61
62 SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
63 return;
64 }
65
67 (microsec < 500 ? 1 : (microsec + 500) / 1000))
68 == WAIT_OBJECT_0)
69 {
72 return;
73 }
74}
75
76
77
78void
80{
81 int i;
82 HANDLE signal_thread_handle;
83
85
87 {
92 }
95
96
100 (errmsg_internal("could not create signal event: error code %lu", GetLastError())));
101
102
103 signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, NULL);
104 if (signal_thread_handle == NULL)
106 (errmsg_internal("could not create signal handler thread")));
107
108
111 (errmsg_internal("could not set console control handler")));
112}
113
114
115
116
117
118
119void
121{
122 int exec_mask;
123
127 {
128
129 int i;
130
132 {
134 {
135
138
139 if (sig == SIG_DFL)
142 if (sig != SIG_ERR && sig != SIG_IGN && sig != SIG_DFL)
143 {
144 sigset_t block_mask;
145 sigset_t save_mask;
146
148
149 block_mask = act->sa_mask;
150 if ((act->sa_flags & SA_NODEFER) == 0)
152
153 sigprocmask(SIG_BLOCK, &block_mask, &save_mask);
155 sigprocmask(SIG_SETMASK, &save_mask, NULL);
156
158 break;
159
160
161 }
162 }
163 }
164 }
167}
168
169
170int
172{
173 if (oset)
175
176 if (!set)
177 return 0;
178
179 switch (how)
180 {
181 case SIG_BLOCK:
183 break;
184 case SIG_UNBLOCK:
186 break;
187 case SIG_SETMASK:
189 break;
190 default:
191 errno = EINVAL;
192 return -1;
193 }
194
195
196
197
198
200
201 return 0;
202}
203
204
205
206
207
208
209int
211 struct sigaction *oldact)
212{
214 {
215 errno = EINVAL;
216 return -1;
217 }
218 if (oldact)
220 if (act)
222 return 0;
223}
224
225
226HANDLE
228{
229 char pipename[128];
230 HANDLE pipe;
231
232 snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", (int) pid);
233
234 pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
235 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
236 PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
237
238 if (pipe == INVALID_HANDLE_VALUE)
240 (errmsg("could not create signal listener pipe for PID %d: error code %lu",
241 (int) pid, GetLastError())));
242
243 return pipe;
244}
245
246
247
248
249
250
251
252
253
254
255
256
257
258void
260{
263 return;
264
268
270}
271
272
273static DWORD WINAPI
275{
276 char pipename[128];
278
279
280 snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%lu", GetCurrentProcessId());
281
282 for (;;)
283 {
284 BOOL fConnected;
285
286
287 if (pipe == INVALID_HANDLE_VALUE)
288 {
289 pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
290 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
291 PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
292
293 if (pipe == INVALID_HANDLE_VALUE)
294 {
295 write_stderr("could not create signal listener pipe: error code %lu; retrying\n", GetLastError());
296 SleepEx(500, FALSE);
297 continue;
298 }
299 }
300
301
302
303
304
305
306 fConnected = ConnectNamedPipe(pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
307 if (fConnected)
308 {
309
310
311
312 BYTE sigNum;
313 DWORD bytes;
314
315 if (ReadFile(pipe, &sigNum, 1, &bytes, NULL) &&
316 bytes == 1)
317 {
318
319
320
321
322
323
324
325
326
328
329
330
331
332
333 WriteFile(pipe, &sigNum, 1, &bytes, NULL);
334
335
336
337
338
339
340
341
342 FlushFileBuffers(pipe);
343 }
344 else
345 {
346
347
348
349
350
351 }
352
353
354 DisconnectNamedPipe(pipe);
355 }
356 else
357 {
358
359
360
361
362
363
364
365
366 CloseHandle(pipe);
367 pipe = INVALID_HANDLE_VALUE;
368 }
369 }
370 return 0;
371}
372
373
374
375
376static BOOL WINAPI
378{
379 if (dwCtrlType == CTRL_C_EVENT ||
380 dwCtrlType == CTRL_BREAK_EVENT ||
381 dwCtrlType == CTRL_CLOSE_EVENT ||
382 dwCtrlType == CTRL_SHUTDOWN_EVENT)
383 {
385 return TRUE;
386 }
387 return FALSE;
388}
#define write_stderr(str)
int errmsg_internal(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Assert(PointerIsAligned(start, uint64))
void(* pqsigfunc)(SIGNAL_ARGS)
HANDLE pgwin32_create_signal_listener(pid_t pid)
static DWORD WINAPI pg_signal_thread(LPVOID param)
int pqsigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
static struct sigaction pg_signal_array[PG_SIGNAL_COUNT]
void pg_queue_signal(int signum)
void pg_usleep(long microsec)
volatile int pg_signal_queue
HANDLE pgwin32_initial_signal_pipe
static CRITICAL_SECTION pg_signal_crit_sec
static BOOL WINAPI pg_console_handler(DWORD dwCtrlType)
static pqsigfunc pg_signal_defaults[PG_SIGNAL_COUNT]
void pgwin32_dispatch_queued_signals(void)
HANDLE pgwin32_signal_event
int pqsigprocmask(int how, const sigset_t *set, sigset_t *oset)
void pgwin32_signal_initialize(void)
#define UNBLOCKED_SIGNAL_QUEUE()