]> Cypherpunks repositories - gostls13.git/commitdiff
os: simplify process status
authorIan Lance Taylor <iant@golang.org>
Mon, 23 Dec 2024 05:15:30 +0000 (21:15 -0800)
committerGopher Robot <gobot@golang.org>
Fri, 7 Feb 2025 01:14:46 +0000 (17:14 -0800)
Since it no longer holds a reference count, just use values.

For #70907

Change-Id: I19a42583988d4f8a9133b1c837356ca0179d688c
Reviewed-on: https://go-review.googlesource.com/c/go/+/638578
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
src/os/exec.go
src/os/export_linux_test.go

index f3cede299673aa04e1a0042847153b1fabdd0230..3f83139da5b2ff1056f46eeb2a91902e8ef23326 100644 (file)
@@ -17,21 +17,19 @@ import (
 // ErrProcessDone indicates a [Process] has finished.
 var ErrProcessDone = errors.New("os: process already finished")
 
-type processStatus uint64
+type processStatus uint32
 
 const (
-       // PID/handle OK to use.
-       statusOK processStatus = 0
+       // statusOK means that the Process is ready to use.
+       statusOK processStatus = iota
 
        // statusDone indicates that the PID/handle should not be used because
        // the process is done (has been successfully Wait'd on).
-       statusDone processStatus = 1 << 62
+       statusDone
 
        // statusReleased indicates that the PID/handle should not be used
        // because the process is released.
-       statusReleased processStatus = 1 << 63
-
-       processStatusMask = 0x3 << 62
+       statusReleased
 )
 
 // Process stores the information about a process created by [StartProcess].
@@ -42,7 +40,7 @@ type Process struct {
        //
        // This consists of the processStatus fields,
        // which indicate if the process is done/released.
-       state atomic.Uint64
+       state atomic.Uint32
 
        // Used only when handle is nil
        sigMu sync.RWMutex // avoid race between wait and signal
@@ -138,7 +136,7 @@ func newDoneProcess(pid int) *Process {
        p := &Process{
                Pid: pid,
        }
-       p.state.Store(uint64(statusDone)) // No persistent reference, as there is no handle.
+       p.state.Store(uint32(statusDone)) // No persistent reference, as there is no handle.
        runtime.SetFinalizer(p, (*Process).Release)
        return p
 }
@@ -148,9 +146,9 @@ func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
                panic("handleTransientAcquire called in invalid mode")
        }
 
-       state := p.state.Load()
-       if state&processStatusMask != 0 {
-               return 0, processStatus(state & processStatusMask)
+       status := processStatus(p.state.Load())
+       if status != statusOK {
+               return 0, status
        }
        h, ok := p.handle.acquire()
        if ok {
@@ -161,11 +159,11 @@ func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
        // We always set the status to non-zero before closing the handle.
        // If we get here the status must have been set non-zero after
        // we just checked it above.
-       state = p.state.Load()
-       if state&processStatusMask == 0 {
+       status = processStatus(p.state.Load())
+       if status == statusOK {
                panic("inconsistent process status")
        }
-       return 0, processStatus(state & processStatusMask)
+       return 0, status
 }
 
 func (p *Process) handleTransientRelease() {
@@ -187,7 +185,7 @@ func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
 
        for {
                state := p.state.Load()
-               status := processStatus(state & processStatusMask)
+               status := processStatus(state)
                if status != statusOK {
                        // Both Release and successful Wait will drop the
                        // Process' persistent reference on the handle. We
@@ -196,7 +194,7 @@ func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
                        // reference is dropped exactly once.
                        return status
                }
-               if !p.state.CompareAndSwap(state, uint64(reason)) {
+               if !p.state.CompareAndSwap(state, uint32(reason)) {
                        continue
                }
                p.handle.release()
@@ -225,7 +223,7 @@ func (p *Process) pidDeactivate(reason processStatus) {
        // racing Release and Wait, Wait may successfully wait on the process,
        // returning the wait status, while future calls error with "process
        // released" rather than "process done".
-       p.state.CompareAndSwap(0, uint64(reason))
+       p.state.CompareAndSwap(0, uint32(reason))
 }
 
 // ProcAttr holds the attributes that will be applied to a new process
index 12434cb42671efb369d5752ea5284fb758d1e8d3..4ace32bb5b2c0bc3b569db87478d199246f94d5a 100644 (file)
@@ -14,5 +14,5 @@ var (
 const StatusDone = statusDone
 
 func (p *Process) Status() processStatus {
-       return processStatus(p.state.Load() & processStatusMask)
+       return processStatus(p.state.Load())
 }