Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH 6/6] EbuildBuildDir: remove synchronous lock method (bug 614112)
Date: Sat, 21 Apr 2018 08:28:52
Message-Id: 20180421082440.32706-7-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH 0/6] EbuildBuildDir: add async_lock method (bug 614112) by Zac Medico
1 The synchronous lock method can trigger event loop recursion if the
2 event loop is already running, which is incompatible with asyncio's
3 default event loop. Therefore, migrate the last consumers to use the
4 async_lock method, and remove the synchronous lock method.
5
6 Bug: https://bugs.gentoo.org/614112
7 Bug: https://bugs.gentoo.org/649588
8 ---
9 pym/_emerge/EbuildBuildDir.py | 47 -----------------------------
10 pym/_emerge/Scheduler.py | 2 +-
11 pym/portage/dbapi/vartree.py | 2 +-
12 pym/portage/package/ebuild/doebuild.py | 9 ++++--
13 pym/portage/tests/ebuild/test_ipc_daemon.py | 2 +-
14 5 files changed, 9 insertions(+), 53 deletions(-)
15
16 diff --git a/pym/_emerge/EbuildBuildDir.py b/pym/_emerge/EbuildBuildDir.py
17 index 9163deacf..477113db8 100644
18 --- a/pym/_emerge/EbuildBuildDir.py
19 +++ b/pym/_emerge/EbuildBuildDir.py
20 @@ -19,53 +19,6 @@ class EbuildBuildDir(SlotObject):
21 SlotObject.__init__(self, **kwargs)
22 self.locked = False
23
24 - def lock(self):
25 - """
26 - This raises an AlreadyLocked exception if lock() is called
27 - while a lock is already held. In order to avoid this, call
28 - unlock() or check whether the "locked" attribute is True
29 - or False before calling lock().
30 - """
31 - if self._lock_obj is not None:
32 - raise self.AlreadyLocked((self._lock_obj,))
33 -
34 - dir_path = self.settings.get('PORTAGE_BUILDDIR')
35 - if not dir_path:
36 - raise AssertionError('PORTAGE_BUILDDIR is unset')
37 - catdir = os.path.dirname(dir_path)
38 - self._catdir = catdir
39 -
40 - try:
41 - portage.util.ensure_dirs(os.path.dirname(catdir),
42 - gid=portage.portage_gid,
43 - mode=0o70, mask=0)
44 - except PortageException:
45 - if not os.path.isdir(os.path.dirname(catdir)):
46 - raise
47 - catdir_lock = AsynchronousLock(path=catdir, scheduler=self.scheduler)
48 - catdir_lock.start()
49 - catdir_lock.wait()
50 - self._assert_lock(catdir_lock)
51 -
52 - try:
53 - try:
54 - portage.util.ensure_dirs(catdir,
55 - gid=portage.portage_gid,
56 - mode=0o70, mask=0)
57 - except PortageException:
58 - if not os.path.isdir(catdir):
59 - raise
60 - builddir_lock = AsynchronousLock(path=dir_path,
61 - scheduler=self.scheduler)
62 - builddir_lock.start()
63 - builddir_lock.wait()
64 - self._assert_lock(builddir_lock)
65 - self._lock_obj = builddir_lock
66 - self.settings['PORTAGE_BUILDDIR_LOCKED'] = '1'
67 - finally:
68 - self.locked = self._lock_obj is not None
69 - catdir_lock.unlock()
70 -
71 def _assert_lock(self, async_lock):
72 if async_lock.returncode != os.EX_OK:
73 # TODO: create a better way to propagate this error to the caller
74 diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
75 index a248f5974..71fe3e07d 100644
76 --- a/pym/_emerge/Scheduler.py
77 +++ b/pym/_emerge/Scheduler.py
78 @@ -799,7 +799,7 @@ class Scheduler(PollScheduler):
79 settings["PORTAGE_BUILDDIR"] = build_dir_path
80 build_dir = EbuildBuildDir(scheduler=sched_iface,
81 settings=settings)
82 - build_dir.lock()
83 + sched_iface.run_until_complete(build_dir.async_lock())
84 current_task = None
85
86 try:
87 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
88 index 8ad6957a3..1a86940f1 100644
89 --- a/pym/portage/dbapi/vartree.py
90 +++ b/pym/portage/dbapi/vartree.py
91 @@ -2081,7 +2081,7 @@ class dblink(object):
92 builddir_lock = EbuildBuildDir(
93 scheduler=scheduler,
94 settings=self.settings)
95 - builddir_lock.lock()
96 + scheduler.run_until_complete(builddir_lock.async_lock())
97 prepare_build_dirs(settings=self.settings, cleanup=True)
98 log_path = self.settings.get("PORTAGE_LOG_FILE")
99
100 diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
101 index bdcdfbe87..3c8414387 100644
102 --- a/pym/portage/package/ebuild/doebuild.py
103 +++ b/pym/portage/package/ebuild/doebuild.py
104 @@ -813,7 +813,8 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
105 scheduler=(portage._internal_caller and
106 global_event_loop() or EventLoop(main=False)),
107 settings=mysettings)
108 - builddir_lock.lock()
109 + builddir_lock.scheduler.run_until_complete(
110 + builddir_lock.async_lock())
111 try:
112 return _spawn_phase(mydo, mysettings,
113 fd_pipes=fd_pipes, returnpid=returnpid)
114 @@ -939,7 +940,8 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
115 scheduler=(portage._internal_caller and
116 global_event_loop() or EventLoop(main=False)),
117 settings=mysettings)
118 - builddir_lock.lock()
119 + builddir_lock.scheduler.run_until_complete(
120 + builddir_lock.async_lock())
121 try:
122 _spawn_phase("clean", mysettings)
123 finally:
124 @@ -963,7 +965,8 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
125 scheduler=(portage._internal_caller and
126 global_event_loop() or EventLoop(main=False)),
127 settings=mysettings)
128 - builddir_lock.lock()
129 + builddir_lock.scheduler.run_until_complete(
130 + builddir_lock.async_lock())
131 mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
132 if mystatus:
133 return mystatus
134 diff --git a/pym/portage/tests/ebuild/test_ipc_daemon.py b/pym/portage/tests/ebuild/test_ipc_daemon.py
135 index b45177f7e..bc18cdf64 100644
136 --- a/pym/portage/tests/ebuild/test_ipc_daemon.py
137 +++ b/pym/portage/tests/ebuild/test_ipc_daemon.py
138 @@ -60,7 +60,7 @@ class IpcDaemonTestCase(TestCase):
139 build_dir = EbuildBuildDir(
140 scheduler=event_loop,
141 settings=env)
142 - build_dir.lock()
143 + event_loop.run_until_complete(build_dir.async_lock())
144 ensure_dirs(env['PORTAGE_BUILDDIR'])
145
146 input_fifo = os.path.join(env['PORTAGE_BUILDDIR'], '.ipc_in')
147 --
148 2.13.6