Discussion:
[ast-developers] Why does ksh93 use SIGALRM to sleep?
ольга крыжановская
2013-07-11 06:11:04 UTC
Permalink
Why does ksh93 use SIGALRM internally to implement sleep? It looks a
bit byzantine, aside from the issue that the code in
src/cmd/ksh93/sh/fault.c can never work, as intended:
if(shp->savesig)
{
/* critical region, save and process later */
if(!(shp->sigflag[sig]&SH_SIGIGNORE))
shp->savesig = sig;
return;
}
if(sig==SIGALRM && shp->bltinfun==b_sleep)
{
if(trap && *trap)
{
shp->trapnote |= SH_SIGTRAP;
shp->sigflag[sig] |= SH_SIGTRAP;
#ifdef _lib_sigaction
set_trapinfo(shp,sig,info);
#endif
}
return;
}

I can imagine so many problems caused by this.
1. if(shp->savesig)/return; - if this code is *ever* executed for a
signal we loose the siginfo data for this signal.

2. if(sig==SIGALRM && shp->bltinfun==b_sleep) happens only during
builtin sleep(1), but at the same time it cannot work because this is
an asynchronous timer signal which can happen at *any* time, while
being inside b_sleep(), or not. There is no guarantee by POSIX that it
should arrive exactly then.

IMO the whole byzantine SIGALRM code should be removed.

Olga
--
, _ _ ,
{ \/`o;====- Olga Kryzhanovska -====;o`\/ }
.----'-/`-/ olga.kryzhanovska at gmail.com \-`\-'----.
`'-..-| / http://twitter.com/fleyta \ |-..-'`
/\/\ Solaris/BSD//C/C++ programmer /\/\
`--` `--`
Cedric Blancher
2013-07-11 07:36:23 UTC
Permalink
Post by ольга крыжановская
Why does ksh93 use SIGALRM internally to implement sleep? It looks a
bit byzantine, aside from the issue that the code in
if(shp->savesig)
{
/* critical region, save and process later */
if(!(shp->sigflag[sig]&SH_SIGIGNORE))
shp->savesig = sig;
return;
}
if(sig==SIGALRM && shp->bltinfun==b_sleep)
{
if(trap && *trap)
{
shp->trapnote |= SH_SIGTRAP;
shp->sigflag[sig] |= SH_SIGTRAP;
#ifdef _lib_sigaction
set_trapinfo(shp,sig,info);
#endif
}
return;
}
I can imagine so many problems caused by this.
1. if(shp->savesig)/return; - if this code is *ever* executed for a
signal we loose the siginfo data for this signal.
shp->savesig is used when the shell forks a subshell to prevent that
signals are processed. Unfortunately it's the wrong solution at the
worst possible place, at least since the day when signals are
considered to be *reliable*.

IMO a solution would be to add a label to the siginfo data and the
label describes the subshell level the shell is currently in. If they
do not match the siginfo data we have 3 choices:
1. If the siginfo data are for the parent shell wait for the current
subshell level to exit and process the siginfo data then
2. If the siginfo data are for the current subshell level then process them
3. If the siginfo data are for a sushell which is gone throw them away

Ced
--
Cedric Blancher <cedric.blancher at googlemail.com>
Institute Pasteur
Roland Mainz
2013-07-11 10:57:26 UTC
Permalink
On Thu, Jul 11, 2013 at 9:36 AM, Cedric Blancher
Post by Cedric Blancher
Post by ольга крыжановская
Why does ksh93 use SIGALRM internally to implement sleep? It looks a
bit byzantine, aside from the issue that the code in
if(shp->savesig)
{
/* critical region, save and process later */
if(!(shp->sigflag[sig]&SH_SIGIGNORE))
shp->savesig = sig;
return;
}
if(sig==SIGALRM && shp->bltinfun==b_sleep)
{
if(trap && *trap)
{
shp->trapnote |= SH_SIGTRAP;
shp->sigflag[sig] |= SH_SIGTRAP;
#ifdef _lib_sigaction
set_trapinfo(shp,sig,info);
#endif
}
return;
}
I can imagine so many problems caused by this.
1. if(shp->savesig)/return; - if this code is *ever* executed for a
signal we loose the siginfo data for this signal.
shp->savesig is used when the shell forks a subshell to prevent that
signals are processed. Unfortunately it's the wrong solution at the
worst possible place, at least since the day when signals are
considered to be *reliable*.
IMO a solution would be to add a label to the siginfo data and the
label describes the subshell level the shell is currently in. If they
1. If the siginfo data are for the parent shell wait for the current
subshell level to exit and process the siginfo data then
2. If the siginfo data are for the current subshell level then process them
3. If the siginfo data are for a sushell which is gone throw them away
The idea is good but IMO we need a subshell id (unique identifer) and
not a label which describes the nesting level... otherwise we end-up
with issues where signals created for one subshell may "bleed through"
into another subshell at the same nesting level, e.g. for $ ( ( sub1 )
( sub2 ) ( sub3 ) ) # signals created in "sub1" may bleed through to
"sub2".
Each subshell id should be "unique" for a given shell instance, e.g.
by using a |volatile int64_t| counter... each incoming siginfo data
package is then "tagged" with this subshell id and only the matching
level for which the signals arrived for should process it.

David... what do you think ?

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
Loading...