mirror of
https://github.com/ARM-software/devlib.git
synced 2025-02-07 13:40:48 +00:00
utis/misc: make check_output thread-safe
subprocess.Popen (used internally by check_output) is not thread-safe and may cause a thread to lock up if called simultaneously from multiple threads. See https://bugs.python.org/issue12739 This is fixed in Python 3.2, but since we're currently still on 2.7, work around the issue by protecting the call with a lock.
This commit is contained in:
parent
b88b400d8d
commit
87b235638a
@ -30,6 +30,7 @@ import pkgutil
|
||||
import logging
|
||||
import random
|
||||
import ctypes
|
||||
import threading
|
||||
from operator import itemgetter
|
||||
from itertools import groupby
|
||||
from functools import partial
|
||||
@ -135,6 +136,9 @@ def preexec_function():
|
||||
|
||||
|
||||
check_output_logger = logging.getLogger('check_output')
|
||||
# Popen is not thread safe. If two threads attempt to call it at the same time,
|
||||
# one may lock up. See https://bugs.python.org/issue12739.
|
||||
check_output_lock = threading.Lock()
|
||||
|
||||
|
||||
def check_output(command, timeout=None, ignore=None, inputtext=None, **kwargs):
|
||||
@ -158,9 +162,13 @@ def check_output(command, timeout=None, ignore=None, inputtext=None, **kwargs):
|
||||
except OSError:
|
||||
pass # process may have already terminated.
|
||||
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
with check_output_lock:
|
||||
process = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE,
|
||||
preexec_fn=preexec_function, **kwargs)
|
||||
preexec_fn=preexec_function,
|
||||
**kwargs)
|
||||
|
||||
if timeout:
|
||||
timer = threading.Timer(timeout, callback, [process.pid, ])
|
||||
|
Loading…
x
Reference in New Issue
Block a user