* [gentoo-commits] proj/portage:master commit in: pym/portage/tests/locks/, pym/_emerge/
@ 2011-05-17 21:26 Zac Medico
0 siblings, 0 replies; 4+ messages in thread
From: Zac Medico @ 2011-05-17 21:26 UTC (permalink / raw
To: gentoo-commits
commit: 1650ac2944b7cbd5a462d2ce39993e2f202807c4
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Tue May 17 21:25:47 2011 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue May 17 21:25:47 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=1650ac29
AsynchronousLock: implement _poll() and test
---
pym/_emerge/AsynchronousLock.py | 10 ++++++++++
pym/_emerge/AsynchronousTask.py | 2 ++
pym/portage/tests/locks/test_asynchronous_lock.py | 2 ++
3 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py
index 1135df7..86b102b 100644
--- a/pym/_emerge/AsynchronousLock.py
+++ b/pym/_emerge/AsynchronousLock.py
@@ -73,6 +73,11 @@ class AsynchronousLock(AsynchronousTask):
if self._imp is not None:
self._imp.cancel()
+ def _poll(self):
+ if self._imp is not None:
+ return self._imp.poll()
+ return self.returncode
+
def _wait(self):
if self.returncode is not None:
return self.returncode
@@ -232,6 +237,11 @@ class _LockProcess(AbstractPollTask):
if self._proc is not None:
self._proc.cancel()
+ def _poll(self):
+ if self._proc is not None:
+ return self._proc.poll()
+ return self.returncode
+
def _wait(self):
if self.returncode is not None:
return self.returncode
diff --git a/pym/_emerge/AsynchronousTask.py b/pym/_emerge/AsynchronousTask.py
index 2b654ec..cac1d55 100644
--- a/pym/_emerge/AsynchronousTask.py
+++ b/pym/_emerge/AsynchronousTask.py
@@ -32,6 +32,8 @@ class AsynchronousTask(SlotObject):
def poll(self):
self._wait_hook()
+ if self.returncode is not None:
+ return self.returncode
return self._poll()
def _poll(self):
diff --git a/pym/portage/tests/locks/test_asynchronous_lock.py b/pym/portage/tests/locks/test_asynchronous_lock.py
index d592f4b..50b9c93 100644
--- a/pym/portage/tests/locks/test_asynchronous_lock.py
+++ b/pym/portage/tests/locks/test_asynchronous_lock.py
@@ -56,6 +56,7 @@ class AsynchronousLockTestCase(TestCase):
_force_async=True, _force_process=True)
lock2.start()
# lock2 should we waiting for lock1 to release
+ self.assertEqual(lock2.poll(), None)
self.assertEqual(lock2.returncode, None)
lock1.unlock()
@@ -78,6 +79,7 @@ class AsynchronousLockTestCase(TestCase):
_force_async=True, _force_process=True)
lock2.start()
# lock2 should we waiting for lock1 to release
+ self.assertEqual(lock2.poll(), None)
self.assertEqual(lock2.returncode, None)
# Cancel lock2 and then check wait() and returncode results.
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/portage:master commit in: pym/portage/tests/locks/, pym/_emerge/
@ 2011-05-17 22:20 Zac Medico
0 siblings, 0 replies; 4+ messages in thread
From: Zac Medico @ 2011-05-17 22:20 UTC (permalink / raw
To: gentoo-commits
commit: a9df8e0f5d49921974ed360a1277f14168aa5101
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Tue May 17 22:19:20 2011 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue May 17 22:19:20 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=a9df8e0f
test_asynchronous_lock: simulate SIGINT from tty
---
pym/_emerge/AsynchronousLock.py | 4 +-
pym/portage/tests/locks/test_asynchronous_lock.py | 34 ++++++++++++++++++++-
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py
index 86b102b..3e7600f 100644
--- a/pym/_emerge/AsynchronousLock.py
+++ b/pym/_emerge/AsynchronousLock.py
@@ -184,7 +184,7 @@ class _LockProcess(AbstractPollTask):
"""
__slots__ = ('path', 'scheduler',) + \
- ('_acquired', '_proc', '_files', '_reg_id', '_unlocked')
+ ('_acquired', '_kill_test', '_proc', '_files', '_reg_id', '_unlocked')
def _start(self):
in_pr, in_pw = os.pipe()
@@ -216,7 +216,7 @@ class _LockProcess(AbstractPollTask):
# If the lock hasn't been aquired yet, the
# caller can check the returncode and handle
# this failure appropriately.
- if not self.cancelled:
+ if not (self.cancelled or self._kill_test):
writemsg_level("_LockProcess: %s\n" % \
_("failed to acquire lock on '%s'") % (self.path,),
level=logging.ERROR, noiselevel=-1)
diff --git a/pym/portage/tests/locks/test_asynchronous_lock.py b/pym/portage/tests/locks/test_asynchronous_lock.py
index 50b9c93..6e8bc0a 100644
--- a/pym/portage/tests/locks/test_asynchronous_lock.py
+++ b/pym/portage/tests/locks/test_asynchronous_lock.py
@@ -1,7 +1,8 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import shutil
+import signal
import tempfile
from portage import os
@@ -90,3 +91,34 @@ class AsynchronousLockTestCase(TestCase):
lock1.unlock()
finally:
shutil.rmtree(tempdir)
+
+ def testAsynchronousLockWaitKill(self):
+ scheduler = PollScheduler().sched_iface
+ tempdir = tempfile.mkdtemp()
+ try:
+ path = os.path.join(tempdir, 'lock_me')
+ lock1 = AsynchronousLock(path=path, scheduler=scheduler)
+ lock1.start()
+ self.assertEqual(lock1.wait(), os.EX_OK)
+ self.assertEqual(lock1.returncode, os.EX_OK)
+ lock2 = AsynchronousLock(path=path, scheduler=scheduler,
+ _force_async=True, _force_process=True)
+ lock2.start()
+ # lock2 should we waiting for lock1 to release
+ self.assertEqual(lock2.poll(), None)
+ self.assertEqual(lock2.returncode, None)
+
+ # Kill lock2's process and then check wait() and
+ # returncode results. This is intended to simulate
+ # a SIGINT sent via the controlling tty.
+ self.assertEqual(lock2._imp is not None, True)
+ self.assertEqual(lock2._imp._proc is not None, True)
+ self.assertEqual(lock2._imp._proc.pid is not None, True)
+ lock2._imp._kill_test = True
+ os.kill(lock2._imp._proc.pid, signal.SIGTERM)
+ self.assertEqual(lock2.wait() == os.EX_OK, False)
+ self.assertEqual(lock2.returncode == os.EX_OK, False)
+ self.assertEqual(lock2.returncode is None, False)
+ lock1.unlock()
+ finally:
+ shutil.rmtree(tempdir)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/portage:master commit in: pym/portage/tests/locks/, pym/_emerge/
@ 2017-04-03 20:09 Zac Medico
0 siblings, 0 replies; 4+ messages in thread
From: Zac Medico @ 2017-04-03 20:09 UTC (permalink / raw
To: gentoo-commits
commit: 916a0733c7201b7a8b22f5262bd5be8cbc8992a6
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 2 20:50:09 2017 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Apr 3 20:07:59 2017 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=916a0733
AsynchronousLock: add async_unlock method (bug 614108)
Add an async_unlock method, in order to avoid event loop
recursion which is incompatible with asyncio.
X-Gentoo-bug: 614108
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=614108
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>
pym/_emerge/AsynchronousLock.py | 89 +++++++++++++++++++++--
pym/portage/tests/locks/test_asynchronous_lock.py | 15 +++-
2 files changed, 92 insertions(+), 12 deletions(-)
diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py
index c0b9b26dc..6a32d2d40 100644
--- a/pym/_emerge/AsynchronousLock.py
+++ b/pym/_emerge/AsynchronousLock.py
@@ -35,7 +35,7 @@ class AsynchronousLock(AsynchronousTask):
__slots__ = ('path', 'scheduler',) + \
('_imp', '_force_async', '_force_dummy', '_force_process', \
- '_force_thread')
+ '_force_thread', '_unlock_future')
_use_process_by_default = True
@@ -84,6 +84,11 @@ class AsynchronousLock(AsynchronousTask):
return self.returncode
def unlock(self):
+ """
+ This method is deprecated in favor of async_unlock, since waiting
+ for the child process to respond can trigger event loop recursion
+ which is incompatible with asyncio.
+ """
if self._imp is None:
raise AssertionError('not locked')
if isinstance(self._imp, (_LockProcess, _LockThread)):
@@ -92,6 +97,28 @@ class AsynchronousLock(AsynchronousTask):
unlockfile(self._imp)
self._imp = None
+ def async_unlock(self):
+ """
+ Release the lock asynchronously. Release notification is available
+ via the add_done_callback method of the returned Future instance.
+
+ @returns: Future, result is None
+ """
+ if self._imp is None:
+ raise AssertionError('not locked')
+ if self._unlock_future is not None:
+ raise AssertionError("already unlocked")
+ if isinstance(self._imp, (_LockProcess, _LockThread)):
+ unlock_future = self._imp.async_unlock()
+ else:
+ unlockfile(self._imp)
+ unlock_future = self.scheduler.create_future()
+ self.scheduler.call_soon(unlock_future.set_result, None)
+ self._imp = None
+ self._unlock_future = unlock_future
+ return unlock_future
+
+
class _LockThread(AbstractPollTask):
"""
This uses the portage.locks module to acquire a lock asynchronously,
@@ -105,7 +132,7 @@ class _LockThread(AbstractPollTask):
"""
__slots__ = ('path',) + \
- ('_force_dummy', '_lock_obj', '_thread',)
+ ('_force_dummy', '_lock_obj', '_thread', '_unlock_future')
def _start(self):
self._registered = True
@@ -132,13 +159,35 @@ class _LockThread(AbstractPollTask):
pass
def unlock(self):
+ """
+ This method is deprecated in favor of async_unlock, for compatibility
+ with _LockProcess.
+ """
+ self._unlock()
+ self._unlock_future.set_result(None)
+
+ def _unlock(self):
if self._lock_obj is None:
raise AssertionError('not locked')
if self.returncode is None:
raise AssertionError('lock not acquired yet')
+ if self._unlock_future is not None:
+ raise AssertionError("already unlocked")
+ self._unlock_future = self.scheduler.create_future()
unlockfile(self._lock_obj)
self._lock_obj = None
+ def async_unlock(self):
+ """
+ Release the lock asynchronously. Release notification is available
+ via the add_done_callback method of the returned Future instance.
+
+ @returns: Future, result is None
+ """
+ self._unlock()
+ self.scheduler.call_soon(self._unlock_future.set_result, None)
+ return self._unlock_future
+
def _unregister(self):
self._registered = False
@@ -156,7 +205,8 @@ class _LockProcess(AbstractPollTask):
"""
__slots__ = ('path',) + \
- ('_acquired', '_kill_test', '_proc', '_files', '_reg_id', '_unlocked')
+ ('_acquired', '_kill_test', '_proc', '_files',
+ '_reg_id','_unlock_future')
def _start(self):
in_pr, in_pw = os.pipe()
@@ -223,13 +273,16 @@ class _LockProcess(AbstractPollTask):
return
if not self.cancelled and \
- not self._unlocked:
+ self._unlock_future is None:
# We don't want lost locks going unnoticed, so it's
# only safe to ignore if either the cancel() or
# unlock() methods have been previously called.
raise AssertionError("lock process failed with returncode %s" \
% (proc.returncode,))
+ if self._unlock_future is not None:
+ self._unlock_future.set_result(None)
+
def _cancel(self):
if self._proc is not None:
self._proc.cancel()
@@ -271,16 +324,36 @@ class _LockProcess(AbstractPollTask):
os.close(pipe_in)
def unlock(self):
+ """
+ This method is deprecated in favor of async_unlock, since waiting
+ for the child process to respond can trigger event loop recursion
+ which is incompatible with asyncio.
+ """
+ self._unlock()
+ self._proc.wait()
+ self._proc = None
+
+ def _unlock(self):
if self._proc is None:
raise AssertionError('not locked')
- if self.returncode is None:
+ if not self._acquired:
raise AssertionError('lock not acquired yet')
if self.returncode != os.EX_OK:
raise AssertionError("lock process failed with returncode %s" \
% (self.returncode,))
- self._unlocked = True
+ if self._unlock_future is not None:
+ raise AssertionError("already unlocked")
+ self._unlock_future = self.scheduler.create_future()
os.write(self._files['pipe_out'], b'\0')
os.close(self._files['pipe_out'])
self._files = None
- self._proc.wait()
- self._proc = None
+
+ def async_unlock(self):
+ """
+ Release the lock asynchronously. Release notification is available
+ via the add_done_callback method of the returned Future instance.
+
+ @returns: Future, result is None
+ """
+ self._unlock()
+ return self._unlock_future
diff --git a/pym/portage/tests/locks/test_asynchronous_lock.py b/pym/portage/tests/locks/test_asynchronous_lock.py
index 3a2ccfb84..ab67242d5 100644
--- a/pym/portage/tests/locks/test_asynchronous_lock.py
+++ b/pym/portage/tests/locks/test_asynchronous_lock.py
@@ -1,6 +1,7 @@
# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import itertools
import signal
import tempfile
@@ -17,7 +18,8 @@ class AsynchronousLockTestCase(TestCase):
tempdir = tempfile.mkdtemp()
try:
path = os.path.join(tempdir, 'lock_me')
- for force_async in (True, False):
+ for force_async, async_unlock in itertools.product(
+ (True, False), repeat=2):
for force_dummy in (True, False):
async_lock = AsynchronousLock(path=path,
scheduler=scheduler, _force_async=force_async,
@@ -26,7 +28,10 @@ class AsynchronousLockTestCase(TestCase):
async_lock.start()
self.assertEqual(async_lock.wait(), os.EX_OK)
self.assertEqual(async_lock.returncode, os.EX_OK)
- async_lock.unlock()
+ if async_unlock:
+ scheduler.run_until_complete(async_lock.async_unlock())
+ else:
+ async_lock.unlock()
async_lock = AsynchronousLock(path=path,
scheduler=scheduler, _force_async=force_async,
@@ -34,8 +39,10 @@ class AsynchronousLockTestCase(TestCase):
async_lock.start()
self.assertEqual(async_lock.wait(), os.EX_OK)
self.assertEqual(async_lock.returncode, os.EX_OK)
- async_lock.unlock()
-
+ if async_unlock:
+ scheduler.run_until_complete(async_lock.async_unlock())
+ else:
+ async_lock.unlock()
finally:
shutil.rmtree(tempdir)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/portage:master commit in: pym/portage/tests/locks/, pym/_emerge/
@ 2017-09-11 21:52 Zac Medico
0 siblings, 0 replies; 4+ messages in thread
From: Zac Medico @ 2017-09-11 21:52 UTC (permalink / raw
To: gentoo-commits
commit: 504f66b0e25281e4465ebeceb799c3e54ff2b884
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 11 21:01:39 2017 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Sep 11 21:07:30 2017 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=504f66b0
AsynchronousLock: allow missing dummy_threading for Python 3.7
Python 3.7 does not support thread-less builds.
Reported-by: Arfrever Frehtes Taifersar Arahesis <Arfrever <AT> Apache.Org>
See: https://bugs.python.org/issue31370
X-Gentoo-bug: 630730
X-Gentoo-bug-url: https://bugs.gentoo.org/630730
pym/_emerge/AsynchronousLock.py | 6 +++++-
pym/portage/tests/locks/test_asynchronous_lock.py | 8 +++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py
index 6a32d2d40..fb0c2b30d 100644
--- a/pym/_emerge/AsynchronousLock.py
+++ b/pym/_emerge/AsynchronousLock.py
@@ -1,13 +1,17 @@
# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import dummy_threading
import fcntl
import errno
import logging
import sys
try:
+ import dummy_threading
+except ImportError:
+ dummy_threading = None
+
+try:
import threading
except ImportError:
threading = dummy_threading
diff --git a/pym/portage/tests/locks/test_asynchronous_lock.py b/pym/portage/tests/locks/test_asynchronous_lock.py
index ab67242d5..6493b6da6 100644
--- a/pym/portage/tests/locks/test_asynchronous_lock.py
+++ b/pym/portage/tests/locks/test_asynchronous_lock.py
@@ -5,6 +5,11 @@ import itertools
import signal
import tempfile
+try:
+ import dummy_threading
+except ImportError:
+ dummy_threading = None
+
from portage import os
from portage import shutil
from portage.tests import TestCase
@@ -20,7 +25,8 @@ class AsynchronousLockTestCase(TestCase):
path = os.path.join(tempdir, 'lock_me')
for force_async, async_unlock in itertools.product(
(True, False), repeat=2):
- for force_dummy in (True, False):
+ for force_dummy in ((False,) if dummy_threading is None
+ else (True, False)):
async_lock = AsynchronousLock(path=path,
scheduler=scheduler, _force_async=force_async,
_force_thread=True,
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-09-11 21:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-17 22:20 [gentoo-commits] proj/portage:master commit in: pym/portage/tests/locks/, pym/_emerge/ Zac Medico
-- strict thread matches above, loose matches on Subject: below --
2017-09-11 21:52 Zac Medico
2017-04-03 20:09 Zac Medico
2011-05-17 21:26 Zac Medico
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox