@@ -101,37 +101,43 @@ def duplicate_for_child(self, handle):
101
101
return reduction .duplicate (handle , self .sentinel )
102
102
103
103
def wait (self , timeout = None ):
104
- if self .returncode is None :
105
- if timeout is None :
106
- msecs = _winapi .INFINITE
107
- else :
108
- msecs = max (0 , int (timeout * 1000 + 0.5 ))
109
-
110
- res = _winapi .WaitForSingleObject (int (self ._handle ), msecs )
111
- if res == _winapi .WAIT_OBJECT_0 :
112
- code = _winapi .GetExitCodeProcess (self ._handle )
113
- if code == TERMINATE :
114
- code = - signal .SIGTERM
115
- self .returncode = code
104
+ if self .returncode is not None :
105
+ return self .returncode
106
+
107
+ if timeout is None :
108
+ msecs = _winapi .INFINITE
109
+ else :
110
+ msecs = max (0 , int (timeout * 1000 + 0.5 ))
111
+
112
+ res = _winapi .WaitForSingleObject (int (self ._handle ), msecs )
113
+ if res == _winapi .WAIT_OBJECT_0 :
114
+ code = _winapi .GetExitCodeProcess (self ._handle )
115
+ if code == TERMINATE :
116
+ code = - signal .SIGTERM
117
+ self .returncode = code
116
118
117
119
return self .returncode
118
120
119
121
def poll (self ):
120
122
return self .wait (timeout = 0 )
121
123
122
124
def terminate (self ):
123
- if self .returncode is None :
124
- try :
125
- _winapi .TerminateProcess (int (self ._handle ), TERMINATE )
126
- except PermissionError :
127
- # ERROR_ACCESS_DENIED (winerror 5) is received when the
128
- # process already died.
129
- code = _winapi .GetExitCodeProcess (int (self ._handle ))
130
- if code == _winapi .STILL_ACTIVE :
131
- raise
132
- self .returncode = code
133
- else :
134
- self .returncode = - signal .SIGTERM
125
+ if self .returncode is not None :
126
+ return
127
+
128
+ try :
129
+ _winapi .TerminateProcess (int (self ._handle ), TERMINATE )
130
+ except PermissionError :
131
+ # ERROR_ACCESS_DENIED (winerror 5) is received when the
132
+ # process already died.
133
+ code = _winapi .GetExitCodeProcess (int (self ._handle ))
134
+ if code == _winapi .STILL_ACTIVE :
135
+ raise
136
+
137
+ # gh-113009: Don't set self.returncode. Even if GetExitCodeProcess()
138
+ # returns an exit code different than STILL_ACTIVE, the process can
139
+ # still be running. Only set self.returncode once WaitForSingleObject()
140
+ # returns WAIT_OBJECT_0 in wait().
135
141
136
142
kill = terminate
137
143
0 commit comments