Skip to content

Commit b3599aa

Browse files
committed
parallel get_wheel_elfdata
1 parent b586739 commit b3599aa

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed

src/auditwheel/pool.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import time
21
from concurrent.futures import Future, ThreadPoolExecutor
32
from pathlib import Path
43
from typing import Any, Callable, Optional
@@ -21,30 +20,28 @@ class FileTaskExecutor:
2120
>>> executor.wait() # Wait for all tasks to complete
2221
"""
2322

24-
def __init__(self, concurrent: int = 1):
23+
def __init__(self, concurrent: int = 0):
2524
self.executor = (
2625
None
2726
if concurrent == 1
2827
else ThreadPoolExecutor(concurrent if concurrent > 1 else None)
2928
)
30-
self.working_map: dict[Path, Future[tuple[str, str]]] = {}
29+
self.working_map: dict[Path, Future[Any]] = {}
3130

3231
def submit(
33-
self, path: Path, fn: Callable[[Any], Any], /, *args: Any, **kwargs: Any
32+
self, path: Path, fn: Callable[..., Any], /, *args: Any, **kwargs: Any
3433
) -> None:
3534
if not path.is_absolute():
3635
path = path.absolute()
3736

3837
future: Future[Any]
3938
if self.executor is None:
40-
future = Future()
41-
future.set_result(fn(*args, **kwargs))
42-
return None
39+
fn(*args, **kwargs)
40+
return
4341

4442
assert path not in self.working_map, "path already in working_map"
4543
future = self.executor.submit(fn, *args, **kwargs)
4644
self.working_map[path] = future
47-
return future
4845

4946
def wait(self, path: Optional[Path] = None) -> None:
5047
"""Wait for tasks to complete.
@@ -62,18 +59,8 @@ def wait(self, path: Optional[Path] = None) -> None:
6259
for future in self.working_map.values():
6360
future.result()
6461
self.working_map.clear()
65-
elif future := self.working_map.pop(path, None):
66-
future.result()
67-
68-
69-
def fake_job(i: int) -> int:
70-
print(f"start {i}")
71-
time.sleep(i)
72-
print(f"end {i}")
62+
elif path in self.working_map:
63+
self.working_map.pop(path).result()
7364

7465

75-
if __name__ == "__main__":
76-
executor = FileTaskExecutor(concurrent=0)
77-
for i in range(10):
78-
executor.submit(Path(f"test{i}.txt"), fake_job, i)
79-
executor.wait()
66+
POOL = FileTaskExecutor(2)

src/auditwheel/wheel_abi.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
from pathlib import Path
1111
from typing import Optional, TypeVar
1212

13+
from elftools.elf.elffile import ELFFile
14+
15+
from auditwheel.pool import POOL
16+
1317
from . import json
1418
from .architecture import Architecture
1519
from .elfutils import (
@@ -94,19 +98,19 @@ def get_wheel_elfdata(
9498
shared_libraries_with_invalid_machine = []
9599

96100
platform_wheel = False
97-
for fn, elf in elf_file_filter(ctx.iter_files()):
98-
# Check for invalid binary wheel format: no shared library should
99-
# be found in purelib
100-
so_name = fn.name
101101

102-
# If this is in purelib, add it to the list of shared libraries in
103-
# purelib
104-
if any(p.name == "purelib" for p in fn.parents):
105-
shared_libraries_in_purelib.append(so_name)
102+
def inner(fn: Path) -> None:
103+
nonlocal \
104+
platform_wheel, \
105+
shared_libraries_in_purelib, \
106+
uses_ucs2_symbols, \
107+
uses_PyFPE_jbuf
108+
109+
with open(fn, "rb") as f:
110+
elf = ELFFile(f)
111+
112+
so_name = fn.name
106113

107-
# If at least one shared library exists in purelib, this is going
108-
# to fail and there's no need to do further checks
109-
if not shared_libraries_in_purelib:
110114
log.debug("processing: %s", fn)
111115
elftree = ldd(fn, exclude=exclude)
112116

@@ -115,11 +119,11 @@ def get_wheel_elfdata(
115119
if arch != wheel_policy.architecture.baseline:
116120
shared_libraries_with_invalid_machine.append(so_name)
117121
log.warning("ignoring: %s with %s architecture", so_name, arch)
118-
continue
122+
return
119123
except ValueError:
120124
shared_libraries_with_invalid_machine.append(so_name)
121125
log.warning("ignoring: %s with unknown architecture", so_name)
122-
continue
126+
return
123127

124128
platform_wheel = True
125129

@@ -148,6 +152,19 @@ def get_wheel_elfdata(
148152
# its internal references later.
149153
nonpy_elftree[fn] = elftree
150154

155+
for fn, _elf in elf_file_filter(ctx.iter_files()):
156+
# Check for invalid binary wheel format: no shared library should
157+
# be found in purelib
158+
so_name = fn.name
159+
160+
# If this is in purelib, add it to the list of shared libraries in
161+
# purelib
162+
if any(p.name == "purelib" for p in fn.parents):
163+
shared_libraries_in_purelib.append(so_name)
164+
165+
if not shared_libraries_in_purelib:
166+
POOL.submit(fn, inner, fn)
167+
151168
# If at least one shared library exists in purelib, raise an error
152169
if shared_libraries_in_purelib:
153170
libraries = "\n\t".join(shared_libraries_in_purelib)
@@ -159,6 +176,8 @@ def get_wheel_elfdata(
159176
)
160177
raise RuntimeError(msg)
161178

179+
POOL.wait()
180+
162181
if not platform_wheel:
163182
raise NonPlatformWheel(
164183
wheel_policy.architecture, shared_libraries_with_invalid_machine

0 commit comments

Comments
 (0)