commit:     1ee8971ba1cb34e6b3cd3d5fda23066b24630e3a
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 16 08:29:36 2018 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Apr 16 08:46:21 2018 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=1ee8971b

EventLoop: eliminate thread safety from call_soon

The call_soon method is used heavily by asyncio.Task to execute
coroutine steps, so it's important to eliminate the overhead
associated with thread safety.

 pym/portage/util/_eventloop/EventLoop.py | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/pym/portage/util/_eventloop/EventLoop.py 
b/pym/portage/util/_eventloop/EventLoop.py
index 38e735999..4ef600a5b 100644
--- a/pym/portage/util/_eventloop/EventLoop.py
+++ b/pym/portage/util/_eventloop/EventLoop.py
@@ -506,12 +506,17 @@ class EventLoop(object):
                @return: an integer ID
                """
                with self._thread_condition:
-                       source_id = self._call_soon_id = self._new_source_id()
-                       self._idle_callbacks[source_id] = 
self._idle_callback_class(
-                               args=args, callback=callback, 
source_id=source_id)
+                       source_id = self._idle_add(callback, *args)
                        self._thread_condition.notify()
                return source_id
 
+       def _idle_add(self, callback, *args):
+               """Like idle_add(), but without thread safety."""
+               source_id = self._call_soon_id = self._new_source_id()
+               self._idle_callbacks[source_id] = self._idle_callback_class(
+                       args=args, callback=callback, source_id=source_id)
+               return source_id
+
        def _run_idle_callbacks(self):
                # assumes caller has acquired self._thread_rlock
                if not self._idle_callbacks:
@@ -810,11 +815,14 @@ class EventLoop(object):
                @return: a handle which can be used to cancel the callback
                @rtype: asyncio.Handle (or compatible)
                """
-               return self._handle(self.idle_add(
+               return self._handle(self._idle_add(
                        self._call_soon_callback(callback, args)), self)
 
-       # The call_soon method inherits thread safety from the idle_add method.
-       call_soon_threadsafe = call_soon
+       def call_soon_threadsafe(self, callback, *args):
+               """Like call_soon(), but thread safe."""
+               # idle_add provides thread safety
+               return self._handle(self.idle_add(
+                       self._call_soon_callback(callback, args)), self)
 
        def time(self):
                """Return the time according to the event loop's clock.

Reply via email to