@@ -17,21 +17,19 @@ import (
17
17
// ErrProcessDone indicates a [Process] has finished.
18
18
var ErrProcessDone = errors .New ("os: process already finished" )
19
19
20
- type processStatus uint64
20
+ type processStatus uint32
21
21
22
22
const (
23
- // PID/handle OK to use.
24
- statusOK processStatus = 0
23
+ // statusOK means that the Process is ready to use.
24
+ statusOK processStatus = iota
25
25
26
26
// statusDone indicates that the PID/handle should not be used because
27
27
// the process is done (has been successfully Wait'd on).
28
- statusDone processStatus = 1 << 62
28
+ statusDone
29
29
30
30
// statusReleased indicates that the PID/handle should not be used
31
31
// because the process is released.
32
- statusReleased processStatus = 1 << 63
33
-
34
- processStatusMask = 0x3 << 62
32
+ statusReleased
35
33
)
36
34
37
35
// Process stores the information about a process created by [StartProcess].
@@ -42,7 +40,7 @@ type Process struct {
42
40
//
43
41
// This consists of the processStatus fields,
44
42
// which indicate if the process is done/released.
45
- state atomic.Uint64
43
+ state atomic.Uint32
46
44
47
45
// Used only when handle is nil
48
46
sigMu sync.RWMutex // avoid race between wait and signal
@@ -138,7 +136,7 @@ func newDoneProcess(pid int) *Process {
138
136
p := & Process {
139
137
Pid : pid ,
140
138
}
141
- p .state .Store (uint64 (statusDone )) // No persistent reference, as there is no handle.
139
+ p .state .Store (uint32 (statusDone )) // No persistent reference, as there is no handle.
142
140
runtime .SetFinalizer (p , (* Process ).Release )
143
141
return p
144
142
}
@@ -148,9 +146,9 @@ func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
148
146
panic ("handleTransientAcquire called in invalid mode" )
149
147
}
150
148
151
- state := p .state .Load ()
152
- if state & processStatusMask != 0 {
153
- return 0 , processStatus ( state & processStatusMask )
149
+ status := processStatus ( p .state .Load () )
150
+ if status != statusOK {
151
+ return 0 , status
154
152
}
155
153
h , ok := p .handle .acquire ()
156
154
if ok {
@@ -161,11 +159,11 @@ func (p *Process) handleTransientAcquire() (uintptr, processStatus) {
161
159
// We always set the status to non-zero before closing the handle.
162
160
// If we get here the status must have been set non-zero after
163
161
// we just checked it above.
164
- state = p .state .Load ()
165
- if state & processStatusMask == 0 {
162
+ status = processStatus ( p .state .Load () )
163
+ if status == statusOK {
166
164
panic ("inconsistent process status" )
167
165
}
168
- return 0 , processStatus ( state & processStatusMask )
166
+ return 0 , status
169
167
}
170
168
171
169
func (p * Process ) handleTransientRelease () {
@@ -187,7 +185,7 @@ func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
187
185
188
186
for {
189
187
state := p .state .Load ()
190
- status := processStatus (state & processStatusMask )
188
+ status := processStatus (state )
191
189
if status != statusOK {
192
190
// Both Release and successful Wait will drop the
193
191
// Process' persistent reference on the handle. We
@@ -196,7 +194,7 @@ func (p *Process) handlePersistentRelease(reason processStatus) processStatus {
196
194
// reference is dropped exactly once.
197
195
return status
198
196
}
199
- if ! p .state .CompareAndSwap (state , uint64 (reason )) {
197
+ if ! p .state .CompareAndSwap (state , uint32 (reason )) {
200
198
continue
201
199
}
202
200
p .handle .release ()
@@ -225,7 +223,7 @@ func (p *Process) pidDeactivate(reason processStatus) {
225
223
// racing Release and Wait, Wait may successfully wait on the process,
226
224
// returning the wait status, while future calls error with "process
227
225
// released" rather than "process done".
228
- p .state .CompareAndSwap (0 , uint64 (reason ))
226
+ p .state .CompareAndSwap (0 , uint32 (reason ))
229
227
}
230
228
231
229
// ProcAttr holds the attributes that will be applied to a new process
0 commit comments