Skip to content

Commit 68930b2

Browse files
Merge pull request #399 from theotherjimmy/no-mac-deadlock
Avoid deadlock on reading PList process output
2 parents 429d16a + 86cd383 commit 68930b2

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

mbed_lstools/darwin.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717

1818
import re
1919
import subprocess
20-
import plistlib
2120
import platform
21+
try:
22+
from plistlib import loads
23+
except ImportError:
24+
from plistlib import readPlistFromString as loads
25+
from xml.parsers.expat import ExpatError
2226

2327
from .lstools_base import MbedLsToolsBase
2428

@@ -30,6 +34,16 @@
3034

3135
mbed_volume_name_match = re.compile(r'\b(mbed|SEGGER MSD|ATMEL EDBG Media)\b', re.I)
3236

37+
38+
def _plist_from_popen(popen):
39+
out, _ = popen.communicate()
40+
if not out:
41+
return []
42+
try:
43+
return loads(out)
44+
except ExpatError:
45+
return []
46+
3347
def _find_TTY(obj):
3448
''' Find the first tty (AKA IODialinDevice) that we can find in the
3549
children of the specified object, or None if no tty is present.
@@ -121,8 +135,7 @@ def find_candidates(self):
121135
def _mount_points(self):
122136
''' Returns map {volume_id: mount_point} '''
123137
diskutil_ls = subprocess.Popen(['diskutil', 'list', '-plist'], stdout=subprocess.PIPE)
124-
disks = plistlib.readPlist(diskutil_ls.stdout)
125-
diskutil_ls.wait()
138+
disks = _plist_from_popen(diskutil_ls)
126139

127140
if logger.isEnabledFor(DEBUG):
128141
import pprint
@@ -152,11 +165,7 @@ def _volumes(self):
152165

153166
for usb_controller in usb_controllers:
154167
ioreg_usb = subprocess.Popen(['ioreg', '-a', '-r', cmp_par, usb_controller, '-l'], stdout=subprocess.PIPE)
155-
try:
156-
usb_tree = plistlib.readPlist(ioreg_usb.stdout)
157-
except:
158-
usb_tree = []
159-
ioreg_usb.wait()
168+
usb_tree = _plist_from_popen(ioreg_usb)
160169

161170
r = {}
162171

test/os_darwin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def do_popen(command, *args, **kwargs):
160160
'ioreg': usb_tree}[command[0]],
161161
to_ret.stdout)
162162
to_ret.stdout.seek(0)
163+
to_ret.communicate.return_value = (to_ret.stdout.getvalue(), "")
163164
return to_ret
164165
_popen.side_effect = do_popen
165166
candidates = self.darwin.find_candidates()

0 commit comments

Comments
 (0)