mirror of
https://github.com/golang/go
synced 2024-11-18 08:54:45 -07:00
os: fix data race on Process.done
Fixes #3969. R=dvyukov, r, alex.brainman, minux.ma CC=golang-dev https://golang.org/cl/6462081
This commit is contained in:
parent
922056d410
commit
122a558f47
@ -6,6 +6,7 @@ package os
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
@ -13,7 +14,7 @@ import (
|
||||
type Process struct {
|
||||
Pid int
|
||||
handle uintptr
|
||||
done bool // process has been successfully waited on
|
||||
isdone uint32 // process has been successfully waited on, non zero if true
|
||||
}
|
||||
|
||||
func newProcess(pid int, handle uintptr) *Process {
|
||||
@ -22,6 +23,14 @@ func newProcess(pid int, handle uintptr) *Process {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Process) setDone() {
|
||||
atomic.StoreUint32(&p.isdone, 1)
|
||||
}
|
||||
|
||||
func (p *Process) done() bool {
|
||||
return atomic.LoadUint32(&p.isdone) > 0
|
||||
}
|
||||
|
||||
// ProcAttr holds the attributes that will be applied to a new process
|
||||
// started by StartProcess.
|
||||
type ProcAttr struct {
|
||||
|
@ -49,7 +49,7 @@ func (p *Process) writeProcFile(file string, data string) error {
|
||||
}
|
||||
|
||||
func (p *Process) signal(sig Signal) error {
|
||||
if p.done {
|
||||
if p.done() {
|
||||
return errors.New("os: process already finished")
|
||||
}
|
||||
if sig == Kill {
|
||||
@ -84,7 +84,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
}
|
||||
|
||||
if waitmsg.Pid == p.Pid {
|
||||
p.done = true
|
||||
p.setDone()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
return nil, NewSyscallError("wait", e)
|
||||
}
|
||||
if pid1 != 0 {
|
||||
p.done = true
|
||||
p.setDone()
|
||||
}
|
||||
ps = &ProcessState{
|
||||
pid: pid1,
|
||||
@ -35,7 +35,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
}
|
||||
|
||||
func (p *Process) signal(sig Signal) error {
|
||||
if p.done {
|
||||
if p.done() {
|
||||
return errors.New("os: process already finished")
|
||||
}
|
||||
s, ok := sig.(syscall.Signal)
|
||||
|
@ -32,7 +32,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
if e != nil {
|
||||
return nil, NewSyscallError("GetProcessTimes", e)
|
||||
}
|
||||
p.done = true
|
||||
p.setDone()
|
||||
// NOTE(brainman): It seems that sometimes process is not dead
|
||||
// when WaitForSingleObject returns. But we do not know any
|
||||
// other way to wait for it. Sleeping for a while seems to do
|
||||
@ -43,7 +43,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
|
||||
}
|
||||
|
||||
func (p *Process) signal(sig Signal) error {
|
||||
if p.done {
|
||||
if p.done() {
|
||||
return errors.New("os: process already finished")
|
||||
}
|
||||
if sig == Kill {
|
||||
|
Loading…
Reference in New Issue
Block a user