1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-09-22 03:40:47 +02:00

19809: improve NO_TRAPS_ASYNC by queueing traps alone

This commit is contained in:
Peter Stephenson 2004-04-21 11:18:45 +00:00
parent f34d9be61b
commit 5747147aff
4 changed files with 48 additions and 10 deletions

View File

@ -1,3 +1,10 @@
2004-04-21 Peter Stephenson <pws@csr.com>
* 19809: Src/jobs.c, Src/signals.c, Src/signals.h: improve
zsh-users/7365 by only queuing traps when TRAPS_ASYNC is set.
This avoids any nasty races, including one reported by Vincent
Stemen.
2004-04-21 Oliver Kiddle <opk@zsh.org>
* 19806: Src/prompt.c: fix bug with %v expansion and negative index

View File

@ -994,11 +994,8 @@ zwaitjob(int job, int sig)
int q = queue_signal_level();
Job jn = jobtab + job;
queue_not_sigchld++;
if (isset(TRAPSASYNC))
dont_queue_signals();
else
queue_signals();
dont_queue_signals();
queue_traps();
child_block(); /* unblocked during child_suspend() */
if (jn->procs || jn->auxprocs) { /* if any forks were done */
jn->stat |= STAT_LOCKED;
@ -1029,10 +1026,8 @@ zwaitjob(int job, int sig)
numpipestats = 1;
}
child_unblock();
dont_queue_traps();
restore_queue_signals(q);
if (!queueing_enabled)
run_queued_signals();
queue_not_sigchld--;
}
/* wait for running job to finish */

View File

@ -49,12 +49,19 @@ mod_export int nsigtrapped;
/* Variables used by signal queueing */
/**/
mod_export int queueing_enabled, queue_front, queue_rear, queue_not_sigchld;
mod_export int queueing_enabled, queue_front, queue_rear;
/**/
mod_export int signal_queue[MAX_QUEUE_SIZE];
/**/
mod_export sigset_t signal_mask_queue[MAX_QUEUE_SIZE];
/* Variables used by trap queueing */
/**/
mod_export int trap_queueing_enabled, trap_queue_front, trap_queue_rear;
/**/
mod_export int trap_queue[MAX_QUEUE_SIZE];
/* This is only used on machines that don't understand signal sets. *
* On SYSV machines this will represent the signals that are blocked *
* (held) using sighold. On machines which can't block signals at *
@ -426,7 +433,7 @@ zhandler(int sig)
#endif
/* Are we queueing signals now? */
if (queueing_enabled && (sig != SIGCHLD || !queue_not_sigchld)) {
if (queueing_enabled) {
int temp_rear = ++queue_rear % MAX_QUEUE_SIZE;
DPUTS(temp_rear == queue_front, "BUG: signal queue full");
@ -1058,5 +1065,17 @@ dotrap(int sig)
if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag)
return;
/* Adapted from signal queueing in zhandler */
if (trap_queueing_enabled && !isset(TRAPSASYNC)) {
int temp_rear = ++trap_queue_rear % MAX_QUEUE_SIZE;
DPUTS(temp_rear == trap_queue_front, "BUG: trap queue full");
if (temp_rear != trap_queue_front) {
trap_queue_rear = temp_rear;
trap_queue[trap_queue_rear] = sig;
}
return;
}
dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]);
}

View File

@ -101,6 +101,23 @@
#define restore_queue_signals(q) (queueing_enabled = (q))
/*
* Similar (but simpler) mechanism used for queueing traps.
* Only needed if NO_TRAPS_ASYNC is set.
*/
#define queue_traps() (trap_queueing_enabled++)
#define run_queued_traps() do { \
while (trap_queue_front != trap_queue_rear) { /* while traps in queue */ \
trap_queue_front = (trap_queue_front + 1) % MAX_QUEUE_SIZE; \
dotrap(trap_queue[trap_queue_front]); /* handle queued trap */ \
} \
} while (0)
#define dont_queue_traps() do { \
trap_queueing_enabled = 0; \
run_queued_traps(); \
} while (0)
/* Make some signal functions faster. */