1 |
commit: 1681309f252a4e91d7256b895a9af26ef82a9b30 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun Mar 1 18:28:21 2020 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Mar 1 18:36:04 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=1681309f |
7 |
|
8 |
_BinpkgFetcherProcess: fix async_lock event loop recursion (bug 711178) |
9 |
|
10 |
Make the async_lock method use the AsynchronousLock async_start |
11 |
method in order to avoid event loop recursion. |
12 |
|
13 |
Fixes: 5c40c3e7e ("SpawnProcess: use async_start method (bug 709746)") |
14 |
Bug: https://bugs.gentoo.org/711178 |
15 |
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> |
16 |
|
17 |
lib/_emerge/BinpkgFetcher.py | 32 +++++++++++++++++--------------- |
18 |
1 file changed, 17 insertions(+), 15 deletions(-) |
19 |
|
20 |
diff --git a/lib/_emerge/BinpkgFetcher.py b/lib/_emerge/BinpkgFetcher.py |
21 |
index 640eead91..e788cb05d 100644 |
22 |
--- a/lib/_emerge/BinpkgFetcher.py |
23 |
+++ b/lib/_emerge/BinpkgFetcher.py |
24 |
@@ -16,6 +16,7 @@ import portage |
25 |
from portage import os |
26 |
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture |
27 |
from portage.util._pty import _create_pty_or_pipe |
28 |
+from portage.util.futures import asyncio |
29 |
from portage.util.futures.compat_coroutine import coroutine |
30 |
|
31 |
if sys.hexversion >= 0x3000000: |
32 |
@@ -205,6 +206,7 @@ class _BinpkgFetcherProcess(SpawnProcess): |
33 |
except OSError: |
34 |
pass |
35 |
|
36 |
+ @coroutine |
37 |
def async_lock(self): |
38 |
""" |
39 |
This raises an AlreadyLocked exception if lock() is called |
40 |
@@ -215,22 +217,22 @@ class _BinpkgFetcherProcess(SpawnProcess): |
41 |
if self._lock_obj is not None: |
42 |
raise self.AlreadyLocked((self._lock_obj,)) |
43 |
|
44 |
- result = self.scheduler.create_future() |
45 |
- |
46 |
- def acquired_lock(async_lock): |
47 |
- if async_lock.wait() == os.EX_OK: |
48 |
- self.locked = True |
49 |
- result.set_result(None) |
50 |
- else: |
51 |
- result.set_exception(AssertionError( |
52 |
- "AsynchronousLock failed with returncode %s" |
53 |
- % (async_lock.returncode,))) |
54 |
- |
55 |
- self._lock_obj = AsynchronousLock(path=self.pkg_path, |
56 |
+ async_lock = self._lock_obj = AsynchronousLock(path=self.pkg_path, |
57 |
scheduler=self.scheduler) |
58 |
- self._lock_obj.addExitListener(acquired_lock) |
59 |
- self._lock_obj.start() |
60 |
- return result |
61 |
+ try: |
62 |
+ yield async_lock.async_start() |
63 |
+ yield async_lock.async_wait() |
64 |
+ except asyncio.CancelledError: |
65 |
+ if async_lock.poll() is None: |
66 |
+ async_lock.cancel() |
67 |
+ raise |
68 |
+ |
69 |
+ if async_lock.returncode != os.EX_OK: |
70 |
+ raise AssertionError( |
71 |
+ "AsynchronousLock failed with returncode %s" |
72 |
+ % (async_lock.returncode,)) |
73 |
+ |
74 |
+ self.locked = True |
75 |
|
76 |
class AlreadyLocked(portage.exception.PortageException): |
77 |
pass |