On Fri, May 5, 2017 at 10:51 AM, Brian Dolbec <dol...@gentoo.org> wrote:

> On Fri,  5 May 2017 02:12:53 -0700
> Zac Medico <zmed...@gentoo.org> wrote:
>
> > Guarantee that newly added idle_add/call_soon callbacks have an
> > opportunity to execute before the event loop decides to wait on
> > self._thread_condition without a timeout. This fixes a case where
> > the event loop would wait on self._thread_condition indefinitely,
> > even though a callback scheduled by the AsynchronousTask._async_wait
> > method needed to be executed first.
> >
> > X-Gentoo-bug: 617550
> > X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=617550
> > ---
> >  pym/portage/util/_eventloop/EventLoop.py | 18 ++++++++++++++++--
> >  1 file changed, 16 insertions(+), 2 deletions(-)
> >
> > diff --git a/pym/portage/util/_eventloop/EventLoop.py
> > b/pym/portage/util/_eventloop/EventLoop.py index 712838e..b7c8762
> > 100644 --- a/pym/portage/util/_eventloop/EventLoop.py
> > +++ b/pym/portage/util/_eventloop/EventLoop.py
> > @@ -108,6 +108,15 @@ class EventLoop(object):
> >               self._poll_event_handler_ids = {}
> >               # Increment id for each new handler.
> >               self._event_handler_id = 0
> > +             # New call_soon callbacks must have an opportunity to
> > +             # execute before it's safe to wait on
> > self._thread_condition
> > +             # without a timeout, since delaying its execution
> > indefinitely
> > +             # could lead to a deadlock. The following attribute
> > stores the
> > +             # event handler id of the most recently added
> > call_soon callback.
> > +             # If this attribute has changed since the last time
> > that the
> > +             # call_soon callbacks have been called, then it's
> > not safe to
> > +             # wait on self._thread_condition without a timeout.
> > +             self._call_soon_id = 0
> >               # Use OrderedDict in order to emulate the FIFO queue
> > behavior # of the AbstractEventLoop.call_soon method.
> >               self._idle_callbacks = OrderedDict()
> > @@ -250,10 +259,15 @@ class EventLoop(object):
> >
> >               if not event_handlers:
> >                       with self._thread_condition:
> > +                             prev_call_soon_id =
> > self._call_soon_id if self._run_timeouts():
> >                                       events_handled += 1
> >                               timeouts_checked = True
> > -                             if not event_handlers and not
> > events_handled and may_block: +
> > +                             call_soon =
> > bool(prev_call_soon_id != self._call_soon_id) +
> > +                             if (not call_soon and not
> > event_handlers
> > +                                     and not events_handled and
> > may_block): # Block so that we don't waste cpu time by looping too
> >                                       # quickly. This makes
> > EventLoop useful for code that needs # to wait for timeout callbacks
> > regardless of whether or @@ -457,7 +471,7 @@ class EventLoop(object):
> >               @return: an integer ID
> >               """
> >               with self._thread_condition:
> > -                     source_id = self._new_source_id()
> > +                     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) self._thread_condition.notify()
>
>
> looks good
>

Thanks, merged:

https://gitweb.gentoo.org/proj/portage.git/commit/?id=dac5089eb7908e9fd643f46c913515082077281e
-- 
Thanks,
Zac

Reply via email to