Skip to content

Commit 9a5a18f

Browse files
author
John Hixson
committed
Reimplement run using threads. Django does not like signals (except in main thread).
Ticket: # 10814 Merge-FN93: yes Merge-TN93: yes (cherry picked from commit 8a31ab9)
1 parent d791629 commit 9a5a18f

File tree

1 file changed

+35
-25
lines changed

1 file changed

+35
-25
lines changed

gui/common/pipesubr.py

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import logging
3333
import os
3434
import signal
35+
import threading
3536

3637

3738
logging.NOTICE = 60
@@ -78,39 +79,48 @@ def pipeopen(command, important=True, logger=log, allowfork=False, quiet=False):
7879
close_fds=False, preexec_fn=preexec_fn)
7980

8081

81-
def run(command, important=True, logger=log, allowfork=False, quiet=False, timeout=-1):
82-
class run_alarm:
83-
pass
84-
def run_alarm_handler(sig, frame):
85-
raise run_alarm
82+
class Command(object):
83+
def __init__(self, command):
84+
self.command = command
85+
self.process = None
86+
self.stdout = None
87+
self.stderr = None
8688

87-
stdout = stderr = None
89+
@property
90+
def returncode(self):
91+
ret = -1
92+
if self.process:
93+
ret = self.process.returncode
94+
return ret
8895

89-
try:
90-
timeout = long(timeout)
91-
except:
92-
timeout = -1
96+
def run(self, important=True, logger=log, allowfork=False, quiet=False, timeout=None):
97+
def target():
98+
self.process = pipeopen(self.command, important, logger, allowfork, quiet)
99+
(self.stdout, self.stderr) = self.process.communicate()
93100

94-
p = pipeopen(command, important, logger, allowfork, quiet)
95-
if timeout != -1:
96-
signal.signal(signal.SIGALRM, run_alarm_handler)
97-
signal.alarm(timeout)
101+
thread = threading.Thread(target=target)
102+
thread.start()
98103

99-
try:
100-
(stdout, stderr) = p.communicate()
101-
if timeout != -1:
102-
signal.alarm(0)
104+
thread.join(timeout)
105+
if thread.is_alive():
106+
self.process.terminate()
107+
thread.join()
103108

104-
except run_alarm:
105-
try:
106-
os.kill(p.pid, signal.SIGKILL)
109+
return (self.returncode, self.stdout, self.stderr)
107110

108-
except OSError:
109-
pass
110111

111-
return (-9, None, None)
112+
def run(command, important=True, logger=log, allowfork=False, quiet=False, timeout=-1):
113+
try:
114+
timeout = float(timeout)
115+
except:
116+
timeout = 0
117+
118+
if timeout <= 0:
119+
timeout = None
120+
121+
c = Command(command)
112122

113-
return (p.returncode, stdout, stderr)
123+
return c.run(important, logger, allowfork, quiet, timeout)
114124

115125

116126
def system(command, important=True, logger=log):

0 commit comments

Comments
 (0)