1 |
On Fri, May 5, 2017 at 10:51 AM, Brian Dolbec <dolsen@g.o> wrote: |
2 |
|
3 |
> On Fri, 5 May 2017 02:12:53 -0700 |
4 |
> Zac Medico <zmedico@g.o> wrote: |
5 |
> |
6 |
> > Guarantee that newly added idle_add/call_soon callbacks have an |
7 |
> > opportunity to execute before the event loop decides to wait on |
8 |
> > self._thread_condition without a timeout. This fixes a case where |
9 |
> > the event loop would wait on self._thread_condition indefinitely, |
10 |
> > even though a callback scheduled by the AsynchronousTask._async_wait |
11 |
> > method needed to be executed first. |
12 |
> > |
13 |
> > X-Gentoo-bug: 617550 |
14 |
> > X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=617550 |
15 |
> > --- |
16 |
> > pym/portage/util/_eventloop/EventLoop.py | 18 ++++++++++++++++-- |
17 |
> > 1 file changed, 16 insertions(+), 2 deletions(-) |
18 |
> > |
19 |
> > diff --git a/pym/portage/util/_eventloop/EventLoop.py |
20 |
> > b/pym/portage/util/_eventloop/EventLoop.py index 712838e..b7c8762 |
21 |
> > 100644 --- a/pym/portage/util/_eventloop/EventLoop.py |
22 |
> > +++ b/pym/portage/util/_eventloop/EventLoop.py |
23 |
> > @@ -108,6 +108,15 @@ class EventLoop(object): |
24 |
> > self._poll_event_handler_ids = {} |
25 |
> > # Increment id for each new handler. |
26 |
> > self._event_handler_id = 0 |
27 |
> > + # New call_soon callbacks must have an opportunity to |
28 |
> > + # execute before it's safe to wait on |
29 |
> > self._thread_condition |
30 |
> > + # without a timeout, since delaying its execution |
31 |
> > indefinitely |
32 |
> > + # could lead to a deadlock. The following attribute |
33 |
> > stores the |
34 |
> > + # event handler id of the most recently added |
35 |
> > call_soon callback. |
36 |
> > + # If this attribute has changed since the last time |
37 |
> > that the |
38 |
> > + # call_soon callbacks have been called, then it's |
39 |
> > not safe to |
40 |
> > + # wait on self._thread_condition without a timeout. |
41 |
> > + self._call_soon_id = 0 |
42 |
> > # Use OrderedDict in order to emulate the FIFO queue |
43 |
> > behavior # of the AbstractEventLoop.call_soon method. |
44 |
> > self._idle_callbacks = OrderedDict() |
45 |
> > @@ -250,10 +259,15 @@ class EventLoop(object): |
46 |
> > |
47 |
> > if not event_handlers: |
48 |
> > with self._thread_condition: |
49 |
> > + prev_call_soon_id = |
50 |
> > self._call_soon_id if self._run_timeouts(): |
51 |
> > events_handled += 1 |
52 |
> > timeouts_checked = True |
53 |
> > - if not event_handlers and not |
54 |
> > events_handled and may_block: + |
55 |
> > + call_soon = |
56 |
> > bool(prev_call_soon_id != self._call_soon_id) + |
57 |
> > + if (not call_soon and not |
58 |
> > event_handlers |
59 |
> > + and not events_handled and |
60 |
> > may_block): # Block so that we don't waste cpu time by looping too |
61 |
> > # quickly. This makes |
62 |
> > EventLoop useful for code that needs # to wait for timeout callbacks |
63 |
> > regardless of whether or @@ -457,7 +471,7 @@ class EventLoop(object): |
64 |
> > @return: an integer ID |
65 |
> > """ |
66 |
> > with self._thread_condition: |
67 |
> > - source_id = self._new_source_id() |
68 |
> > + source_id = self._call_soon_id = |
69 |
> > self._new_source_id() self._idle_callbacks[source_id] = |
70 |
> > self._idle_callback_class( args=args, callback=callback, |
71 |
> > source_id=source_id) self._thread_condition.notify() |
72 |
> |
73 |
> |
74 |
> looks good |
75 |
> |
76 |
|
77 |
Thanks, merged: |
78 |
|
79 |
https://gitweb.gentoo.org/proj/portage.git/commit/?id=dac5089eb7908e9fd643f46c913515082077281e |
80 |
-- |
81 |
Thanks, |
82 |
Zac |