equal
deleted
inserted
replaced
26 from __future__ import absolute_import |
26 from __future__ import absolute_import |
27 import os |
27 import os |
28 import sys |
28 import sys |
29 import subprocess |
29 import subprocess |
30 import ctypes |
30 import ctypes |
31 from threading import Timer, Lock, Thread, Semaphore |
31 import time |
|
32 from threading import Timer, Lock, Thread, Semaphore, Condition |
32 import signal |
33 import signal |
33 |
34 |
34 _debug = os.path.exists("BEREMIZ_DEBUG") |
35 _debug = os.path.exists("BEREMIZ_DEBUG") |
35 |
36 |
36 class outputThread(Thread): |
37 class outputThread(Thread): |
152 self.Proc.stderr, |
153 self.Proc.stderr, |
153 self.errors) |
154 self.errors) |
154 self.errt.start() |
155 self.errt.start() |
155 self.startsem.release() |
156 self.startsem.release() |
156 |
157 |
|
158 self.spinwakeuplock = Lock() |
|
159 self.spinwakeupcond = Condition(self.spinwakeuplock) |
|
160 self.spinwakeuptimer = None |
|
161 |
157 def output(self, v): |
162 def output(self, v): |
158 if v and self.output_encoding: |
163 if v and self.output_encoding: |
159 v = v.decode(self.output_encoding) |
164 v = v.decode(self.output_encoding) |
160 self.outdata.append(v) |
165 self.outdata.append(v) |
161 self.outlen += 1 |
166 self.outlen += 1 |
190 self.log_the_end(ecode, pid) |
195 self.log_the_end(ecode, pid) |
191 if self.finish_callback is not None: |
196 if self.finish_callback is not None: |
192 self.finish_callback(self, ecode, pid) |
197 self.finish_callback(self, ecode, pid) |
193 self.errt.join() |
198 self.errt.join() |
194 self.finishsem.release() |
199 self.finishsem.release() |
|
200 self.spinwakeup() |
195 |
201 |
196 def kill(self, gently=True): |
202 def kill(self, gently=True): |
197 # avoid running kill before start is finished |
203 # avoid running kill before start is finished |
198 self.startsem.acquire() |
204 self.startsem.acquire() |
199 self.startsem.release() |
205 self.startsem.release() |
220 def endlog(self): |
226 def endlog(self): |
221 if self.endlock.acquire(False): |
227 if self.endlock.acquire(False): |
222 if not self.outt.finished and self.kill_it: |
228 if not self.outt.finished and self.kill_it: |
223 self.kill() |
229 self.kill() |
224 self.finishsem.release() |
230 self.finishsem.release() |
|
231 self.spinwakeup() |
|
232 |
|
233 def spinwakeup(self): |
|
234 with self.spinwakeuplock: |
|
235 if self.spinwakeuptimer is not None: |
|
236 self.spinwakeuptimer.cancel() |
|
237 self.spinwakeuptimer = None |
|
238 self.spinwakeupcond.notify() |
225 |
239 |
226 def spin(self): |
240 def spin(self): |
227 self.finishsem.acquire() |
241 start = time.time() |
|
242 while not self.finishsem.acquire(0): |
|
243 with self.spinwakeuplock: |
|
244 self.spinwakeuptimer = Timer(0.1, self.spinwakeup) |
|
245 self.spinwakeuptimer.start() |
|
246 self.spinwakeupcond.wait() |
|
247 self.logger.progress("%.3fs"%(time.time() - start)) |
|
248 |
228 return [self.exitcode, "".join(self.outdata), "".join(self.errdata)] |
249 return [self.exitcode, "".join(self.outdata), "".join(self.errdata)] |