Changes between and of Initial VersionVersion 15Ticket #1997


Ignore:
Timestamp:
09/11/2006 09:17:25 PM (8 years ago)
Author:
glyph
Comment:

Changing the description too, since apparently we're repurposing this ticket for a minor change rather than the actual fix:

The original description (thanks trac) was:

reactor.iterate() is defined like this:

    def iterate(self, delay=0):
       """See twisted.internet.interfaces.IReactorCore.iterate.
       """
       self.runUntilCurrent()
       self.doIteration(delay)

runUntilCurrent runs all the procs on the threadCallQueue. So if
something is added to the threadCallQueue between runUntilCurrent()
and doIteration(), the reactor needs to have an fd ready for reading
to shortcut the select(). This is done by callFromThread() calling
reactor.wakeUp(), which will write on the wakeup FD.

HOWEVER. For some reason reactor.wakeUp() only writes on the fd if it
is being called from another thread. This is obviously borked in the
signal-handling case, when a signal arrives between runUntilCurrent()
and doIteration(), and is processed via reactor.callFromThread(), as
is the case with SIGCHLD.

Solution: have reactor.wakeUp() always wake the waker, regardless of
the thread it comes from.

The solution is incorrect, for reasons given above.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #1997

    • Property Cc spiv jknight exarkun glyph added
    • Property Summary changed from signals handled via callFromThread, yet the reactor still drops into select() to perhaps wakeUp could be slightly simpler
    • Property Priority changed from normal to lowest
    • Property Owner glyph deleted
  • Ticket #1997 – Description

    initial v15  
    1 {{{ 
    2 reactor.iterate() is defined like this: 
     1The test for what thread we're in is unnecessary, and slightly worsens a race with {{{select()}}} because the handler could be called after processing events in the queue but before entering {{{select()}}}. 
    32 
    4     def iterate(self, delay=0): 
    5        """See twisted.internet.interfaces.IReactorCore.iterate. 
    6        """ 
    7        self.runUntilCurrent() 
    8        self.doIteration(delay) 
     3We're leaving it this way for now, because the race is easier to trigger in its current configuration (and still exists in other configurations), but will be removing this redundant and unnecessary code either after or during the fix for the real underlying issue. 
    94 
    10 runUntilCurrent runs all the procs on the threadCallQueue. So if 
    11 something is added to the threadCallQueue between runUntilCurrent() 
    12 and doIteration(), the reactor needs to have an fd ready for reading 
    13 to shortcut the select(). This is done by callFromThread() calling 
    14 reactor.wakeUp(), which will write on the wakeup FD. 
    15  
    16 HOWEVER. For some reason reactor.wakeUp() only writes on the fd if it 
    17 is being called from another thread. This is obviously borked in the 
    18 signal-handling case, when a signal arrives between runUntilCurrent() 
    19 and doIteration(), and is processed via reactor.callFromThread(), as 
    20 is the case with SIGCHLD. 
    21  
    22 Solution: have reactor.wakeUp() always wake the waker, regardless of 
    23 the thread it comes from. 
    24 }}} 
     5See #791.