mirror of https://github.com/golang/go.git
os: remove Process.mode field
It's now redundant with checking whether the handle field is nil. For #70907 Change-Id: I877f2a7c63d15ab5f8e3d2c9aa24776c2e3e2056 Reviewed-on: https://go-review.googlesource.com/c/go/+/638576 Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
5c2b5e02c4
commit
b485e5bceb
|
|
@ -17,26 +17,6 @@ import (
|
||||||
// ErrProcessDone indicates a [Process] has finished.
|
// ErrProcessDone indicates a [Process] has finished.
|
||||||
var ErrProcessDone = errors.New("os: process already finished")
|
var ErrProcessDone = errors.New("os: process already finished")
|
||||||
|
|
||||||
type processMode uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// modePID means that Process operations such use the raw PID from the
|
|
||||||
// Pid field. handle is not used.
|
|
||||||
//
|
|
||||||
// This may be due to the host not supporting handles, or because
|
|
||||||
// Process was created as a literal, leaving handle unset.
|
|
||||||
//
|
|
||||||
// This must be the zero value so Process literals get modePID.
|
|
||||||
modePID processMode = iota
|
|
||||||
|
|
||||||
// modeHandle means that Process operations use handle, which is
|
|
||||||
// initialized with an OS process handle.
|
|
||||||
//
|
|
||||||
// Note that Release and Wait will deactivate and eventually close the
|
|
||||||
// handle, so acquire may fail, indicating the reason.
|
|
||||||
modeHandle
|
|
||||||
)
|
|
||||||
|
|
||||||
type processStatus uint64
|
type processStatus uint64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -58,15 +38,13 @@ const (
|
||||||
type Process struct {
|
type Process struct {
|
||||||
Pid int
|
Pid int
|
||||||
|
|
||||||
mode processMode
|
|
||||||
|
|
||||||
// State contains the atomic process state.
|
// State contains the atomic process state.
|
||||||
//
|
//
|
||||||
// In modePID, this consists only of the processStatus fields, which
|
// If handle is nil, this consists only of the processStatus fields,
|
||||||
// indicate if the process is done/released.
|
// which indicate if the process is done/released.
|
||||||
//
|
//
|
||||||
// In modeHandle, the lower bits also contain a reference count for the
|
// In handle is not nil, the lower bits also contain a reference
|
||||||
// handle field.
|
// count for the handle field.
|
||||||
//
|
//
|
||||||
// The Process itself initially holds 1 persistent reference. Any
|
// The Process itself initially holds 1 persistent reference. Any
|
||||||
// operation that uses the handle with a system call temporarily holds
|
// operation that uses the handle with a system call temporarily holds
|
||||||
|
|
@ -87,7 +65,7 @@ type Process struct {
|
||||||
// errors returned by concurrent calls.
|
// errors returned by concurrent calls.
|
||||||
state atomic.Uint64
|
state atomic.Uint64
|
||||||
|
|
||||||
// Used only in modePID.
|
// Used only when handle is nil
|
||||||
sigMu sync.RWMutex // avoid race between wait and signal
|
sigMu sync.RWMutex // avoid race between wait and signal
|
||||||
|
|
||||||
// handle, if not nil, is a pointer to a struct
|
// handle, if not nil, is a pointer to a struct
|
||||||
|
|
@ -154,8 +132,7 @@ func (ph *processHandle) release() {
|
||||||
|
|
||||||
func newPIDProcess(pid int) *Process {
|
func newPIDProcess(pid int) *Process {
|
||||||
p := &Process{
|
p := &Process{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
mode: modePID,
|
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(p, (*Process).Release)
|
runtime.SetFinalizer(p, (*Process).Release)
|
||||||
return p
|
return p
|
||||||
|
|
@ -172,7 +149,6 @@ func newHandleProcess(pid int, handle uintptr) *Process {
|
||||||
|
|
||||||
p := &Process{
|
p := &Process{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
mode: modeHandle,
|
|
||||||
handle: ph,
|
handle: ph,
|
||||||
}
|
}
|
||||||
p.state.Store(1) // 1 persistent reference
|
p.state.Store(1) // 1 persistent reference
|
||||||
|
|
@ -182,8 +158,7 @@ func newHandleProcess(pid int, handle uintptr) *Process {
|
||||||
|
|
||||||
func newDoneProcess(pid int) *Process {
|
func newDoneProcess(pid int) *Process {
|
||||||
p := &Process{
|
p := &Process{
|
||||||
Pid: pid,
|
Pid: pid,
|
||||||
mode: modePID,
|
|
||||||
}
|
}
|
||||||
p.state.Store(uint64(statusDone)) // No persistent reference, as there is no handle.
|
p.state.Store(uint64(statusDone)) // No persistent reference, as there is no handle.
|
||||||
runtime.SetFinalizer(p, (*Process).Release)
|
runtime.SetFinalizer(p, (*Process).Release)
|
||||||
|
|
@ -191,7 +166,7 @@ func newDoneProcess(pid int) *Process {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
|
func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
|
||||||
if p.mode != modeHandle {
|
if p.handle == nil {
|
||||||
panic("handleTransientAcquire called in invalid mode")
|
panic("handleTransientAcquire called in invalid mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +188,7 @@ func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) handleTransientRelease() {
|
func (p *Process) handleTransientRelease() {
|
||||||
if p.mode != modeHandle {
|
if p.handle == nil {
|
||||||
panic("handleTransientRelease called in invalid mode")
|
panic("handleTransientRelease called in invalid mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +225,7 @@ func (p *Process) handleTransientRelease() {
|
||||||
// Returns the status prior to this call. If this is not statusOK, then the
|
// Returns the status prior to this call. If this is not statusOK, then the
|
||||||
// reference was not dropped or status changed.
|
// reference was not dropped or status changed.
|
||||||
func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
|
func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
|
||||||
if p.mode != modeHandle {
|
if p.handle == nil {
|
||||||
panic("handlePersistentRelease called in invalid mode")
|
panic("handlePersistentRelease called in invalid mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +255,7 @@ func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) pidStatus() processStatus {
|
func (p *Process) pidStatus() processStatus {
|
||||||
if p.mode != modePID {
|
if p.handle != nil {
|
||||||
panic("pidStatus called in invalid mode")
|
panic("pidStatus called in invalid mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,7 +263,7 @@ func (p *Process) pidStatus() processStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Process) pidDeactivate(reason processStatus) {
|
func (p *Process) pidDeactivate(reason processStatus) {
|
||||||
if p.mode != modePID {
|
if p.handle != nil {
|
||||||
panic("pidDeactivate called in invalid mode")
|
panic("pidDeactivate called in invalid mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,12 @@ const (
|
||||||
|
|
||||||
func (p *Process) wait() (ps *ProcessState, err error) {
|
func (p *Process) wait() (ps *ProcessState, err error) {
|
||||||
// Which type of Process do we have?
|
// Which type of Process do we have?
|
||||||
switch p.mode {
|
if p.handle != nil {
|
||||||
case modeHandle:
|
|
||||||
// pidfd
|
// pidfd
|
||||||
return p.pidfdWait()
|
return p.pidfdWait()
|
||||||
case modePID:
|
} else {
|
||||||
// Regular PID
|
// Regular PID
|
||||||
return p.pidWait()
|
return p.pidWait()
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,15 +82,12 @@ func (p *Process) signal(sig Signal) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Which type of Process do we have?
|
// Which type of Process do we have?
|
||||||
switch p.mode {
|
if p.handle != nil {
|
||||||
case modeHandle:
|
|
||||||
// pidfd
|
// pidfd
|
||||||
return p.pidfdSendSignal(s)
|
return p.pidfdSendSignal(s)
|
||||||
case modePID:
|
} else {
|
||||||
// Regular PID
|
// Regular PID
|
||||||
return p.pidSignal(s)
|
return p.pidSignal(s)
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,15 +125,14 @@ func (p *Process) release() error {
|
||||||
// solely on statusReleased to determine that the Process is released.
|
// solely on statusReleased to determine that the Process is released.
|
||||||
p.Pid = pidReleased
|
p.Pid = pidReleased
|
||||||
|
|
||||||
switch p.mode {
|
if p.handle != nil {
|
||||||
case modeHandle:
|
|
||||||
// Drop the Process' reference and mark handle unusable for
|
// Drop the Process' reference and mark handle unusable for
|
||||||
// future calls.
|
// future calls.
|
||||||
//
|
//
|
||||||
// Ignore the return value: we don't care if this was a no-op
|
// Ignore the return value: we don't care if this was a no-op
|
||||||
// racing with Wait, or a double Release.
|
// racing with Wait, or a double Release.
|
||||||
p.handlePersistentRelease(statusReleased)
|
p.handlePersistentRelease(statusReleased)
|
||||||
case modePID:
|
} else {
|
||||||
// Just mark the PID unusable.
|
// Just mark the PID unusable.
|
||||||
p.pidDeactivate(statusReleased)
|
p.pidDeactivate(statusReleased)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Note that Process.mode is always modeHandle because Windows always requires
|
// Note that Process.handle is never nil because Windows always requires
|
||||||
// a handle. A manually-created Process literal is not valid.
|
// a handle. A manually-created Process literal is not valid.
|
||||||
|
|
||||||
func (p *Process) wait() (ps *ProcessState, err error) {
|
func (p *Process) wait() (ps *ProcessState, err error) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue