1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-15 04:32:24 +00:00

rm bg job double-fork workaround (re: 50db00e1, ed9053ec, e3d7bf1d)

$ ksh -c '(sleep 1 & echo ${.sh.stats.forks}); :'
  2

The shell forks twice. A virtual subshell that launches a
background job forks first before forking the background job.

As discussed in the P.S. in e3d7bf1d, this is caused by the
following code in sh_exec() in xec.c (as since changed in 4ce486a7,
e40aaa8a, 88a1f3d6, and a2196f94):

1505:	if((type&(FAMP|TFORK))==(FAMP|TFORK))
1506:	{
1507:		if(sh.comsub && !(sh.fdstatus[1]&IONOSEEK))
1508:			unpipe = iousepipe();
1509:		if(!sh.subshare)
1510:			sh_subfork();
1511:	}

This smells like an ugly workaround. It forks a virtual subshell
whenever a background job is launched within it, whether there is
an actual reason to do this or not. Researching the ksh93-history
repo reveals that this workaround had already gone through many
different versions before we restarted ksh development.

In the e3d7bf1d P.S. discussion, four regression test failures were
caused by removing this workaround. I recently tried it again and
two of the failures were already gone. (Testing which commits fix
it would require recompiling every 93u+m commit with the workaround
patched out and I can't be bothered.) Two were left: the two
signal.sh failures. The last commit (50db00e1) fixed those as well.

So I believe we no longer need this workaround, which never did
make very much sense. Removing it significantly improves the
performance of ksh when launching background jobs from subshells.
This commit is contained in:
Martijn Dekker 2022-06-13 23:34:46 +01:00
parent 50db00e136
commit 4b22fd5d0f

View file

@ -1494,16 +1494,7 @@ int sh_exec(register const Shnode_t *t, int flags)
int no_fork,jobid;
int pipes[3];
if(sh.subshell)
{
sh_subtmpfile();
if((type&(FAMP|TFORK))==(FAMP|TFORK))
{
if(sh.comsub && !(sh.fdstatus[1]&IONOSEEK))
unpipe = iousepipe();
if(!sh.subshare)
sh_subfork();
}
}
no_fork = !(type&(FAMP|FPOU))
&& !sh.subshell
&& !(sh.st.trapcom[SIGINT] && *sh.st.trapcom[SIGINT])