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

Commitb28ac1d

Browse files
committed
Provide sigaction() for Windows.
Commit9abb2bf left behind code to block signals inside signalhandlers on Windows, because our signal porting layer didn't havesigaction(). Provide a minimal implementation that is capable ofblocking signals, to get rid of platform differences. See also relatedcommitc94ae9d.Discussion:https://postgr.es/m/CA%2BhUKGKKKfcgx6jzok9AYenp2TNti_tfs8FMoJpL8%2B0Gsy%3D%3D_A%40mail.gmail.com
1 parent6bbd8b7 commitb28ac1d

File tree

5 files changed

+53
-79
lines changed

5 files changed

+53
-79
lines changed

‎src/backend/libpq/pqsignal.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,10 @@ pqinitmask(void)
110110
* postmaster ever unblocks signals.
111111
*
112112
* pqinitmask() must have been invoked previously.
113-
*
114-
* On Windows, this function is just an alias for pqsignal()
115-
* (and note that it's calling the code in src/backend/port/win32/signal.c,
116-
* not src/port/pqsignal.c). On that platform, the postmaster's signal
117-
* handlers still have to block signals for themselves.
118113
*/
119114
pqsigfunc
120115
pqsignal_pm(intsigno,pqsigfuncfunc)
121116
{
122-
#ifndefWIN32
123117
structsigactionact,
124118
oact;
125119

@@ -142,7 +136,4 @@ pqsignal_pm(int signo, pqsigfunc func)
142136
if (sigaction(signo,&act,&oact)<0)
143137
returnSIG_ERR;
144138
returnoact.sa_handler;
145-
#else/* WIN32 */
146-
returnpqsignal(signo,func);
147-
#endif
148139
}

‎src/backend/port/win32/signal.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ HANDLEpgwin32_initial_signal_pipe = INVALID_HANDLE_VALUE;
3434
staticCRITICAL_SECTIONpg_signal_crit_sec;
3535

3636
/* Note that array elements 0 are unused since they correspond to signal 0 */
37-
staticpqsigfuncpg_signal_array[PG_SIGNAL_COUNT];
37+
staticstructsigactionpg_signal_array[PG_SIGNAL_COUNT];
3838
staticpqsigfuncpg_signal_defaults[PG_SIGNAL_COUNT];
3939

4040

@@ -85,7 +85,9 @@ pgwin32_signal_initialize(void)
8585

8686
for (i=0;i<PG_SIGNAL_COUNT;i++)
8787
{
88-
pg_signal_array[i]=SIG_DFL;
88+
pg_signal_array[i].sa_handler=SIG_DFL;
89+
pg_signal_array[i].sa_mask=0;
90+
pg_signal_array[i].sa_flags=0;
8991
pg_signal_defaults[i]=SIG_IGN;
9092
}
9193
pg_signal_mask=0;
@@ -131,15 +133,27 @@ pgwin32_dispatch_queued_signals(void)
131133
if (exec_mask&sigmask(i))
132134
{
133135
/* Execute this signal */
134-
pqsigfuncsig=pg_signal_array[i];
136+
structsigaction*act=&pg_signal_array[i];
137+
pqsigfuncsig=act->sa_handler;
135138

136139
if (sig==SIG_DFL)
137140
sig=pg_signal_defaults[i];
138141
pg_signal_queue &= ~sigmask(i);
139142
if (sig!=SIG_ERR&&sig!=SIG_IGN&&sig!=SIG_DFL)
140143
{
144+
sigset_tblock_mask;
145+
sigset_tsave_mask;
146+
141147
LeaveCriticalSection(&pg_signal_crit_sec);
148+
149+
block_mask=act->sa_mask;
150+
if ((act->sa_flags&SA_NODEFER)==0)
151+
block_mask |=sigmask(i);
152+
153+
sigprocmask(SIG_BLOCK,&block_mask,&save_mask);
142154
sig(i);
155+
sigprocmask(SIG_SETMASK,&save_mask,NULL);
156+
143157
EnterCriticalSection(&pg_signal_crit_sec);
144158
break;/* Restart outer loop, in case signal mask or
145159
* queue has been modified inside signal
@@ -187,22 +201,25 @@ pqsigprocmask(int how, const sigset_t *set, sigset_t *oset)
187201
return0;
188202
}
189203

190-
191204
/*
192205
* Unix-like signal handler installation
193206
*
194207
* Only called on main thread, no sync required
195208
*/
196-
pqsigfunc
197-
pqsignal(intsignum,pqsigfunchandler)
209+
int
210+
pqsigaction(intsignum,conststructsigaction*act,
211+
structsigaction*oldact)
198212
{
199-
pqsigfuncprevfunc;
200-
201213
if (signum >=PG_SIGNAL_COUNT||signum<0)
202-
returnSIG_ERR;
203-
prevfunc=pg_signal_array[signum];
204-
pg_signal_array[signum]=handler;
205-
returnprevfunc;
214+
{
215+
errno=EINVAL;
216+
return-1;
217+
}
218+
if (oldact)
219+
*oldact=pg_signal_array[signum];
220+
if (act)
221+
pg_signal_array[signum]=*act;
222+
return0;
206223
}
207224

208225
/* Create the signal listener pipe for specified PID */

‎src/backend/postmaster/postmaster.c

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,10 @@ PostmasterMain(int argc, char *argv[])
620620
* is used by all child processes and client processes). That has a
621621
* couple of special behaviors:
622622
*
623-
* 1.Except on Windows, wetell sigaction() to block all signals for the
624-
*duration of thesignal handler. This is faster than our old approach
625-
*ofblocking/unblocking explicitly in the signal handler, and it should
626-
*alsoprevent excessive stack consumption if signals arrive quickly.
623+
* 1.Wetell sigaction() to block all signals for the duration of the
624+
* signal handler. This is faster than our old approach of
625+
* blocking/unblocking explicitly in the signal handler, and it should also
626+
* prevent excessive stack consumption if signals arrive quickly.
627627
*
628628
* 2. We do not set the SA_RESTART flag. This is because signals will be
629629
* blocked at all times except when ServerLoop is waiting for something to
@@ -2726,14 +2726,6 @@ SIGHUP_handler(SIGNAL_ARGS)
27262726
{
27272727
intsave_errno=errno;
27282728

2729-
/*
2730-
* We rely on the signal mechanism to have blocked all signals ... except
2731-
* on Windows, which lacks sigaction(), so we have to do it manually.
2732-
*/
2733-
#ifdefWIN32
2734-
PG_SETMASK(&BlockSig);
2735-
#endif
2736-
27372729
if (Shutdown <=SmartShutdown)
27382730
{
27392731
ereport(LOG,
@@ -2790,10 +2782,6 @@ SIGHUP_handler(SIGNAL_ARGS)
27902782
#endif
27912783
}
27922784

2793-
#ifdefWIN32
2794-
PG_SETMASK(&UnBlockSig);
2795-
#endif
2796-
27972785
errno=save_errno;
27982786
}
27992787

@@ -2806,14 +2794,6 @@ pmdie(SIGNAL_ARGS)
28062794
{
28072795
intsave_errno=errno;
28082796

2809-
/*
2810-
* We rely on the signal mechanism to have blocked all signals ... except
2811-
* on Windows, which lacks sigaction(), so we have to do it manually.
2812-
*/
2813-
#ifdefWIN32
2814-
PG_SETMASK(&BlockSig);
2815-
#endif
2816-
28172797
ereport(DEBUG2,
28182798
(errmsg_internal("postmaster received signal %d",
28192799
postgres_signal_arg)));
@@ -2938,10 +2918,6 @@ pmdie(SIGNAL_ARGS)
29382918
break;
29392919
}
29402920

2941-
#ifdefWIN32
2942-
PG_SETMASK(&UnBlockSig);
2943-
#endif
2944-
29452921
errno=save_errno;
29462922
}
29472923

@@ -2955,14 +2931,6 @@ reaper(SIGNAL_ARGS)
29552931
intpid;/* process id of dead child process */
29562932
intexitstatus;/* its exit status */
29572933

2958-
/*
2959-
* We rely on the signal mechanism to have blocked all signals ... except
2960-
* on Windows, which lacks sigaction(), so we have to do it manually.
2961-
*/
2962-
#ifdefWIN32
2963-
PG_SETMASK(&BlockSig);
2964-
#endif
2965-
29662934
ereport(DEBUG4,
29672935
(errmsg_internal("reaping dead processes")));
29682936

@@ -3255,11 +3223,6 @@ reaper(SIGNAL_ARGS)
32553223
*/
32563224
PostmasterStateMachine();
32573225

3258-
/* Done with signal handler */
3259-
#ifdefWIN32
3260-
PG_SETMASK(&UnBlockSig);
3261-
#endif
3262-
32633226
errno=save_errno;
32643227
}
32653228

@@ -5106,14 +5069,6 @@ sigusr1_handler(SIGNAL_ARGS)
51065069
{
51075070
intsave_errno=errno;
51085071

5109-
/*
5110-
* We rely on the signal mechanism to have blocked all signals ... except
5111-
* on Windows, which lacks sigaction(), so we have to do it manually.
5112-
*/
5113-
#ifdefWIN32
5114-
PG_SETMASK(&BlockSig);
5115-
#endif
5116-
51175072
/*
51185073
* RECOVERY_STARTED and BEGIN_HOT_STANDBY signals are ignored in
51195074
* unexpected states. If the startup process quickly starts up, completes
@@ -5254,10 +5209,6 @@ sigusr1_handler(SIGNAL_ARGS)
52545209
signal_child(StartupPID,SIGUSR2);
52555210
}
52565211

5257-
#ifdefWIN32
5258-
PG_SETMASK(&UnBlockSig);
5259-
#endif
5260-
52615212
errno=save_errno;
52625213
}
52635214

‎src/include/libpq/pqsignal.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,26 @@
2121
/* Emulate POSIX sigset_t APIs on Windows */
2222
typedefintsigset_t;
2323

24+
#defineSA_RESTART1
25+
#defineSA_NODEFER2
26+
27+
structsigaction
28+
{
29+
void(*sa_handler) (int);
30+
/* sa_sigaction not yet implemented */
31+
sigset_tsa_mask;
32+
intsa_flags;
33+
};
34+
2435
externintpqsigprocmask(inthow,constsigset_t*set,sigset_t*oset);
36+
externintpqsigaction(intsignum,conststructsigaction*act,
37+
structsigaction*oldact);
2538

2639
#defineSIG_BLOCK1
2740
#defineSIG_UNBLOCK2
2841
#defineSIG_SETMASK3
2942
#definesigprocmask(how,set,oset) pqsigprocmask((how), (set), (oset))
43+
#definesigaction(signum,act,oldact) pqsigaction((signum), (act), (oldact))
3044
#definesigemptyset(set)(*(set) = 0)
3145
#definesigfillset(set)(*(set) = ~0)
3246
#definesigaddset(set,signum)(*(set) |= (sigmask(signum)))

‎src/port/pqsignal.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929

3030
#include<signal.h>
3131

32-
#if !defined(WIN32)|| defined(FRONTEND)
32+
#ifndefFRONTEND
33+
#include"libpq/pqsignal.h"
34+
#endif
3335

3436
/*
3537
* Set up a signal handler, with SA_RESTART, for signal "signo"
@@ -39,7 +41,7 @@
3941
pqsigfunc
4042
pqsignal(intsigno,pqsigfuncfunc)
4143
{
42-
#ifndefWIN32
44+
#if !(defined(WIN32)&& defined(FRONTEND))
4345
structsigactionact,
4446
oact;
4547

@@ -53,9 +55,8 @@ pqsignal(int signo, pqsigfunc func)
5355
if (sigaction(signo,&act,&oact)<0)
5456
returnSIG_ERR;
5557
returnoact.sa_handler;
56-
#else/* WIN32 */
58+
#else
59+
/* Forward to Windows native signal system. */
5760
returnsignal(signo,func);
5861
#endif
5962
}
60-
61-
#endif/* !defined(WIN32) || defined(FRONTEND) */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp