1 |
Thanks Zac! |
2 |
|
3 |
On 04-12-2020 14:58:22 -0800, Zac Medico wrote: |
4 |
> Ensure that _get_lock_fn arguments to multiprocessing.Process will |
5 |
> successfully pickle, as required by the spawn start method, which |
6 |
> is the default for macOS since Python 3.8. |
7 |
> |
8 |
> Since file descriptors are not inherited unless the fork start |
9 |
> method is used, the subprocess should only try to close an |
10 |
> inherited file descriptor for the fork start method. |
11 |
> |
12 |
> Bug: https://bugs.gentoo.org/758230 |
13 |
> Signed-off-by: Zac Medico <zmedico@g.o> |
14 |
> --- |
15 |
> lib/portage/locks.py | 36 +++++++++++++++++++++++------------- |
16 |
> 1 file changed, 23 insertions(+), 13 deletions(-) |
17 |
> |
18 |
> diff --git a/lib/portage/locks.py b/lib/portage/locks.py |
19 |
> index 1073343be..193045c03 100644 |
20 |
> --- a/lib/portage/locks.py |
21 |
> +++ b/lib/portage/locks.py |
22 |
> @@ -44,18 +44,7 @@ def _get_lock_fn(): |
23 |
> if _lock_fn is not None: |
24 |
> return _lock_fn |
25 |
> |
26 |
> - def _test_lock(fd, lock_path): |
27 |
> - os.close(fd) |
28 |
> - try: |
29 |
> - with open(lock_path, 'a') as f: |
30 |
> - fcntl.lockf(f.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) |
31 |
> - except EnvironmentError as e: |
32 |
> - if e.errno == errno.EAGAIN: |
33 |
> - # Parent process holds lock, as expected. |
34 |
> - sys.exit(0) |
35 |
> |
36 |
> - # Something went wrong. |
37 |
> - sys.exit(1) |
38 |
> |
39 |
> fd, lock_path = tempfile.mkstemp() |
40 |
> try: |
41 |
> @@ -64,8 +53,16 @@ def _get_lock_fn(): |
42 |
> except EnvironmentError: |
43 |
> pass |
44 |
> else: |
45 |
> - proc = multiprocessing.Process(target=_test_lock, |
46 |
> - args=(fd, lock_path)) |
47 |
> + proc = multiprocessing.Process( |
48 |
> + target=_subprocess_test_lock, |
49 |
> + args=( |
50 |
> + # Since file descriptors are not inherited unless the fork start |
51 |
> + # method is used, the subprocess should only try to close an |
52 |
> + # inherited file descriptor for the fork start method. |
53 |
> + fd if multiprocessing.get_start_method() == "fork" else None, |
54 |
> + lock_path, |
55 |
> + ), |
56 |
> + ) |
57 |
> proc.start() |
58 |
> proc.join() |
59 |
> if proc.exitcode == os.EX_OK: |
60 |
> @@ -80,6 +77,19 @@ def _get_lock_fn(): |
61 |
> _lock_fn = fcntl.flock |
62 |
> return _lock_fn |
63 |
> |
64 |
> +def _subprocess_test_lock(fd, lock_path): |
65 |
> + if fd is not None: |
66 |
> + os.close(fd) |
67 |
> + try: |
68 |
> + with open(lock_path, 'a') as f: |
69 |
> + fcntl.lockf(f.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) |
70 |
> + except EnvironmentError as e: |
71 |
> + if e.errno == errno.EAGAIN: |
72 |
> + # Parent process holds lock, as expected. |
73 |
> + sys.exit(0) |
74 |
> + |
75 |
> + # Something went wrong. |
76 |
> + sys.exit(1) |
77 |
> |
78 |
> _open_fds = {} |
79 |
> _open_inodes = {} |
80 |
> -- |
81 |
> 2.26.2 |
82 |
> |
83 |
> |
84 |
|
85 |
-- |
86 |
Fabian Groffen |
87 |
Gentoo on a different level |