mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
syscall: fix fork-exec/wait inconsistencies for Plan 9
Fixes the fork-exec/wait race condition for ForkExec as well, by making it use startProcess. This makes the comment for StartProcess consistent as well. Further, the passing of Waitmsg data in startProcess and WaitProcess is protected against possible forks from outside of ForkExec and StartProcess, which might cause interference with the Await call. R=rsc, rminnich, npe, ality CC=golang-dev https://golang.org/cl/7128059
This commit is contained in:
parent
522562e712
commit
7f0d1652a4
1 changed files with 10 additions and 8 deletions
|
|
@ -495,11 +495,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
|
||||||
return pid, nil
|
return pid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combination of fork and exec, careful to be thread safe.
|
|
||||||
func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
|
|
||||||
return forkExec(argv0, argv, attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
type waitErr struct {
|
type waitErr struct {
|
||||||
Waitmsg
|
Waitmsg
|
||||||
err error
|
err error
|
||||||
|
|
@ -551,7 +546,9 @@ func startProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, err err
|
||||||
forkc <- ret
|
forkc <- ret
|
||||||
|
|
||||||
var w waitErr
|
var w waitErr
|
||||||
w.err = Await(&w.Waitmsg)
|
for w.err == nil && w.Pid != ret.pid {
|
||||||
|
w.err = Await(&w.Waitmsg)
|
||||||
|
}
|
||||||
waitc <- &w
|
waitc <- &w
|
||||||
close(waitc)
|
close(waitc)
|
||||||
}()
|
}()
|
||||||
|
|
@ -559,6 +556,11 @@ func startProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, err err
|
||||||
return ret.pid, ret.err
|
return ret.pid, ret.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Combination of fork and exec, careful to be thread safe.
|
||||||
|
func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
|
||||||
|
return startProcess(argv0, argv, attr)
|
||||||
|
}
|
||||||
|
|
||||||
// StartProcess wraps ForkExec for package os.
|
// StartProcess wraps ForkExec for package os.
|
||||||
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
|
func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
|
||||||
pid, err = startProcess(argv0, argv, attr)
|
pid, err = startProcess(argv0, argv, attr)
|
||||||
|
|
@ -612,8 +614,8 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
|
||||||
// WaitProcess waits until the pid of a
|
// WaitProcess waits until the pid of a
|
||||||
// running process is found in the queue of
|
// running process is found in the queue of
|
||||||
// wait messages. It is used in conjunction
|
// wait messages. It is used in conjunction
|
||||||
// with StartProcess to wait for a running
|
// with ForkExec/StartProcess to wait for a
|
||||||
// process to exit.
|
// running process to exit.
|
||||||
func WaitProcess(pid int, w *Waitmsg) (err error) {
|
func WaitProcess(pid int, w *Waitmsg) (err error) {
|
||||||
procs.Lock()
|
procs.Lock()
|
||||||
ch := procs.waits[pid]
|
ch := procs.waits[pid]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue