Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5049196

Browse files
committed
Here's the latest win32 signals code, this time in the form of a patch
against the latest shapshot. It also includes the replacement of kill()with pqkill() and sigsetmask() with pqsigsetmask().Passes all tests fine on my linux machine once applied. Still doesn'tlink completely on Win32 - there are a few things still required. Butmuch closer than before.At Bruce's request, I'm goint to write up a README file about the methodof signals delivery chosen and why the others were rejected (basically asummary of the mailinglist discussions). I'll finish that up once/if thepatch is accepted.Magnus Hagander
1 parenteec08b9 commit5049196

File tree

10 files changed

+404
-26
lines changed

10 files changed

+404
-26
lines changed

‎src/backend/commands/async.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.107 2004/01/07 18:56:25 neilc Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.108 2004/01/27 00:45:26 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -83,6 +83,7 @@
8383
#include"commands/async.h"
8484
#include"libpq/libpq.h"
8585
#include"libpq/pqformat.h"
86+
#include"libpq/pqsignal.h"
8687
#include"miscadmin.h"
8788
#include"storage/ipc.h"
8889
#include"tcop/tcopprot.h"
@@ -497,7 +498,7 @@ AtCommit_Notify(void)
497498
* for some reason. It's OK to send the signal first, because
498499
* the other guy can't read pg_listener until we unlock it.
499500
*/
500-
if (kill(listenerPID,SIGUSR2)<0)
501+
if (pqkill(listenerPID,SIGUSR2)<0)
501502
{
502503
/*
503504
* Get rid of pg_listener entry if it refers to a PID that

‎src/backend/libpq/pqsignal.c

Lines changed: 242 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/libpq/pqsignal.c,v 1.28 2003/11/29 19:51:49 pgsql Exp $
12+
* $PostgreSQL: pgsql/src/backend/libpq/pqsignal.c,v 1.29 2004/01/27 00:45:26 momjian Exp $
1313
*
1414
* NOTES
1515
*This shouldn't be in libpq, but the monitor and some other
@@ -38,9 +38,18 @@
3838
*is to do signal-handler reinstallation, which doesn't work well
3939
*at all.
4040
* ------------------------------------------------------------------------*/
41+
#ifdefWIN32
42+
#defineWIN32_LEAN_AND_MEAN
43+
#define_WIN32_WINNT 0x0400
44+
#endif
45+
4146
#include"postgres.h"
4247

48+
#ifndefWIN32
4349
#include<signal.h>
50+
#else
51+
#include<windows.h>
52+
#endif
4453

4554
#include"libpq/pqsignal.h"
4655

@@ -127,6 +136,7 @@ pqinitmask(void)
127136
}
128137

129138

139+
#ifndefWIN32
130140
/*
131141
* Set up a signal handler
132142
*/
@@ -149,3 +159,234 @@ pqsignal(int signo, pqsigfunc func)
149159
returnoact.sa_handler;
150160
#endif/* !HAVE_POSIX_SIGNALS */
151161
}
162+
163+
164+
#else
165+
166+
167+
/* Win32 specific signals code */
168+
169+
/* pg_signal_crit_sec is used to protect only pg_signal_queue. That is the only
170+
* variable that can be accessed from the signal sending threads! */
171+
staticCRITICAL_SECTIONpg_signal_crit_sec;
172+
staticintpg_signal_queue;
173+
174+
#definePG_SIGNAL_COUNT 32
175+
staticpqsigfuncpg_signal_array[PG_SIGNAL_COUNT];
176+
staticpqsigfuncpg_signal_defaults[PG_SIGNAL_COUNT];
177+
staticintpg_signal_mask;
178+
179+
HANDLEpgwin32_main_thread_handle;
180+
181+
/* Signal handling thread function */
182+
staticDWORDWINAPIpg_signal_thread(LPVOIDparam);
183+
184+
/* Initialization */
185+
voidpgwin32_signal_initialize(void) {
186+
inti;
187+
HANDLEsignal_thread_handle;
188+
InitializeCriticalSection(&pg_signal_crit_sec);
189+
190+
for (i=0;i<PG_SIGNAL_COUNT;i++) {
191+
pg_signal_array[i]=SIG_DFL;
192+
pg_signal_defaults[i]=SIG_IGN;
193+
}
194+
pg_signal_mask=0;
195+
pg_signal_queue=0;
196+
197+
/* Get handle to main thread so we can post calls to it later */
198+
if (!DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),
199+
GetCurrentProcess(),&pgwin32_main_thread_handle,
200+
0,FALSE,DUPLICATE_SAME_ACCESS)) {
201+
fprintf(stderr,gettext("Failed to get main thread handle!\n"));
202+
exit(1);
203+
}
204+
205+
/* Create thread for handling signals */
206+
signal_thread_handle=CreateThread(NULL,0,pg_signal_thread,NULL,0,NULL);
207+
if (signal_thread_handle==NULL) {
208+
fprintf(stderr,gettext("Failed to create signal handler thread!\n"));
209+
exit(1);
210+
}
211+
}
212+
213+
214+
/* Dispatch all signals currently queued and not blocked
215+
* Blocked signals are ignored, and will be fired at the time of
216+
* the sigsetmask() call. */
217+
staticvoiddispatch_queued_signals(void) {
218+
inti;
219+
220+
EnterCriticalSection(&pg_signal_crit_sec);
221+
while (pg_signal_queue& ~pg_signal_mask) {
222+
/* One or more unblocked signals queued for execution */
223+
224+
intexec_mask=pg_signal_queue& ~pg_signal_mask;
225+
226+
for (i=0;i<PG_SIGNAL_COUNT;i++) {
227+
if (exec_mask&sigmask(i)) {
228+
/* Execute this signal */
229+
pqsigfuncsig=pg_signal_array[i];
230+
if (sig==SIG_DFL)
231+
sig=pg_signal_defaults[i];
232+
pg_signal_queue &= ~sigmask(i);
233+
if (sig!=SIG_ERR&&sig!=SIG_IGN&&sig!=SIG_DFL) {
234+
LeaveCriticalSection(&pg_signal_crit_sec);
235+
sig(i);
236+
EnterCriticalSection(&pg_signal_crit_sec);
237+
break;/* Restart outer loop, in case signal mask or queue
238+
has been modified inside signal handler */
239+
}
240+
}
241+
}
242+
}
243+
LeaveCriticalSection(&pg_signal_crit_sec);
244+
}
245+
246+
/* signal masking. Only called on main thread, no sync required */
247+
intpqsigsetmask(intmask) {
248+
intprevmask;
249+
prevmask=pg_signal_mask;
250+
pg_signal_mask=mask;
251+
252+
/* Dispatch any signals queued up right away, in case we have
253+
unblocked one or more signals previously queued */
254+
dispatch_queued_signals();
255+
256+
returnprevmask;
257+
}
258+
259+
260+
/* signal manipulation. Only called on main thread, no sync required */
261+
pqsigfuncpqsignal(intsignum,pqsigfunchandler) {
262+
pqsigfuncprevfunc;
263+
if (signum >=PG_SIGNAL_COUNT||signum<0)
264+
returnSIG_ERR;
265+
prevfunc=pg_signal_array[signum];
266+
pg_signal_array[signum]=handler;
267+
returnprevfunc;
268+
}
269+
270+
/* signal sending */
271+
intpqkill(intpid,intsig) {
272+
charpipename[128];
273+
BYTEsigData=sig;
274+
BYTEsigRet=0;
275+
DWORDbytes;
276+
277+
if (sig >=PG_SIGNAL_COUNT||sig <=0) {
278+
errno=EINVAL;
279+
return-1;
280+
}
281+
if (pid <=0) {
282+
/* No support for process groups */
283+
errno=EINVAL;
284+
return-1;
285+
}
286+
wsprintf(pipename,"\\\\.\\pipe\\pgsignal_%i",pid);
287+
if (!CallNamedPipe(pipename,&sigData,1,&sigRet,1,&bytes,1000)) {
288+
if (GetLastError()==ERROR_FILE_NOT_FOUND)
289+
errno=ESRCH;
290+
elseif (GetLastError()==ERROR_ACCESS_DENIED)
291+
errno=EPERM;
292+
else
293+
errno=EINVAL;
294+
return-1;
295+
}
296+
if (bytes!=1||sigRet!=sig) {
297+
errno=ESRCH;
298+
return-1;
299+
}
300+
301+
return0;
302+
}
303+
304+
/* APC callback scheduled on main thread when signals are fired */
305+
staticvoidCALLBACKpg_signal_apc(ULONG_PTRparam) {
306+
dispatch_queued_signals();
307+
}
308+
309+
/*
310+
* All functions below execute on the signal handler thread
311+
* and must be synchronized as such!
312+
* NOTE! The only global variable that can be used is
313+
* pg_signal_queue!
314+
*/
315+
316+
317+
staticvoidpg_queue_signal(intsignum) {
318+
if (signum >=PG_SIGNAL_COUNT||signum<0)
319+
return;
320+
321+
EnterCriticalSection(&pg_signal_crit_sec);
322+
pg_signal_queue |=sigmask(signum);
323+
LeaveCriticalSection(&pg_signal_crit_sec);
324+
325+
QueueUserAPC(pg_signal_apc,pgwin32_main_thread_handle,(ULONG_PTR)NULL);
326+
}
327+
328+
/* Signal dispatching thread */
329+
staticDWORDWINAPIpg_signal_dispatch_thread(LPVOIDparam) {
330+
HANDLEpipe= (HANDLE)param;
331+
BYTEsigNum;
332+
DWORDbytes;
333+
334+
if (!ReadFile(pipe,&sigNum,1,&bytes,NULL)) {
335+
/* Client died before sending */
336+
CloseHandle(pipe);
337+
return0;
338+
}
339+
if (bytes!=1) {
340+
/* Received <bytes> bytes over signal pipe (should be 1) */
341+
CloseHandle(pipe);
342+
return0;
343+
}
344+
WriteFile(pipe,&sigNum,1,&bytes,NULL);/* Don't care if it works or not.. */
345+
FlushFileBuffers(pipe);
346+
DisconnectNamedPipe(pipe);
347+
CloseHandle(pipe);
348+
349+
pg_queue_signal(sigNum);
350+
return0;
351+
}
352+
353+
/* Signal handling thread */
354+
staticDWORDWINAPIpg_signal_thread(LPVOIDparam) {
355+
charpipename[128];
356+
HANDLEpipe=INVALID_HANDLE_VALUE;
357+
358+
wsprintf(pipename,"\\\\.\\pipe\\pgsignal_%i",GetCurrentProcessId());
359+
360+
for (;;) {
361+
BOOLfConnected;
362+
HANDLEhThread;
363+
364+
pipe=CreateNamedPipe(pipename,PIPE_ACCESS_DUPLEX,
365+
PIPE_TYPE_MESSAGE |PIPE_READMODE_MESSAGE |PIPE_WAIT,
366+
PIPE_UNLIMITED_INSTANCES,16,16,1000,NULL);
367+
if (pipe==INVALID_HANDLE_VALUE) {
368+
fprintf(stderr,gettext("Failed to create signal listener pipe: %i. Retrying.\n"),(int)GetLastError());
369+
SleepEx(500,TRUE);
370+
continue;
371+
}
372+
373+
fConnected=ConnectNamedPipe(pipe,NULL) ? TRUE : (GetLastError()==ERROR_PIPE_CONNECTED);
374+
if (fConnected) {
375+
hThread=CreateThread(NULL,0,
376+
(LPTHREAD_START_ROUTINE)pg_signal_dispatch_thread,
377+
(LPVOID)pipe,0,NULL);
378+
if (hThread==INVALID_HANDLE_VALUE) {
379+
fprintf(stderr,gettext("Failed to create signal dispatch thread: %i\n"),(int)GetLastError());
380+
}
381+
else
382+
CloseHandle(hThread);
383+
}
384+
else
385+
/* Connection failed. Cleanup and try again */
386+
CloseHandle(pipe);
387+
}
388+
return0;
389+
}
390+
391+
392+
#endif

‎src/backend/main/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.71 2004/01/11 03:49:31 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.72 2004/01/27 00:45:26 momjian Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -40,6 +40,9 @@
4040
#include"utils/help_config.h"
4141
#include"utils/ps_status.h"
4242
#include"pgstat.h"
43+
#ifdefWIN32
44+
#include"libpq/pqsignal.h"
45+
#endif
4346

4447

4548

@@ -97,6 +100,8 @@ main(int argc, char *argv[])
97100
argv[0],err);
98101
exit(1);
99102
}
103+
104+
pgwin32_signal_initialize();
100105
}
101106
#endif
102107

‎src/backend/port/sysv_sema.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/port/sysv_sema.c,v 1.12 2003/12/01 22:15:37 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/port/sysv_sema.c,v 1.13 2004/01/27 00:45:26 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,6 +31,7 @@
3131
#include"miscadmin.h"
3232
#include"storage/ipc.h"
3333
#include"storage/pg_sema.h"
34+
#include"libpq/pqsignal.h"
3435

3536

3637
#ifndefHAVE_UNION_SEMUN
@@ -232,7 +233,7 @@ IpcSemaphoreCreate(int numSems)
232233
continue;/* oops, GETPID failed */
233234
if (creatorPID!=getpid())
234235
{
235-
if (kill(creatorPID,0)==0||
236+
if (pqkill(creatorPID,0)==0||
236237
errno!=ESRCH)
237238
continue;/* sema belongs to a live process */
238239
}

‎src/backend/port/sysv_shmem.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.28 2004/01/07 18:56:27 neilc Exp $
13+
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.29 2004/01/27 00:45:26 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -33,6 +33,7 @@
3333
#include"miscadmin.h"
3434
#include"storage/ipc.h"
3535
#include"storage/pg_shmem.h"
36+
#include"libpq/pqsignal.h"
3637

3738

3839
typedefkey_tIpcMemoryKey;/* shared memory key passed to shmget(2) */
@@ -284,7 +285,7 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
284285
hdr= (PGShmemHeader*)memAddress;
285286
if (hdr->creatorPID!=getpid())
286287
{
287-
if (kill(hdr->creatorPID,0)==0||errno!=ESRCH)
288+
if (pqkill(hdr->creatorPID,0)==0||errno!=ESRCH)
288289
{
289290
shmdt(memAddress);
290291
continue;/* segment belongs to a live process */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp