1   
 2   
 3   
 4  from twisted.internet import reactor, defer 
 5  from twisted.python import log 
 6   
 8   
 9      _reactor = reactor 
10   
12          self._events = [] 
13          self._flushObservers = [] 
14          self._timer = None 
15          self._in_turn = False 
 16   
17 -    def append(self, cb, args, kwargs): 
 18          self._events.append((cb, args, kwargs)) 
19          if not self._timer: 
20              self._timer = self._reactor.callLater(0, self._turn) 
 21   
23          self._timer = None 
24          self._in_turn = True 
25           
26           
27           
28          events, self._events = self._events, [] 
29          for cb, args, kwargs in events: 
30              try: 
31                  cb(*args, **kwargs) 
32              except: 
33                  log.err() 
34          self._in_turn = False 
35          if self._events and not self._timer: 
36              self._timer = self._reactor.callLater(0, self._turn) 
37          if not self._events: 
38              observers, self._flushObservers = self._flushObservers, [] 
39              for o in observers: 
40                  o.callback(None) 
 41   
43          """Return a Deferred that will fire (with None) when the call queue 
44          is completely empty.""" 
45          if not self._events and not self._in_turn: 
46              return defer.succeed(None) 
47          d = defer.Deferred() 
48          self._flushObservers.append(d) 
49          return d 
  50   
51   
52  _theSimpleQueue = _SimpleCallQueue() 
53   
55      """This is the eventual-send operation, used as a plan-coordination 
56      primitive. The callable will be invoked (with args and kwargs) in a later 
57      reactor turn. Doing 'eventually(a); eventually(b)' guarantees that a will 
58      be called before b. 
59   
60      Any exceptions that occur in the callable will be logged with log.err(). 
61      If you really want to ignore them, be sure to provide a callable that 
62      catches those exceptions. 
63   
64      This function returns None. If you care to know when the callable was 
65      run, be sure to provide a callable that notifies somebody. 
66      """ 
67      _theSimpleQueue.append(cb, args, kwargs) 
 68   
69   
71      """This returns a Deferred which will fire in a later reactor turn, after 
72      the current call stack has been completed, and after all other deferreds 
73      previously scheduled with callEventually(). 
74      """ 
75      d = defer.Deferred() 
76      eventually(d.callback, value) 
77      return d 
 78   
80      """This returns a Deferred which fires when the eventual-send queue is 
81      finally empty. This is useful to wait upon as the last step of a Trial 
82      test method. 
83      """ 
84      return _theSimpleQueue.flush() 
 85   
87      """This sets the reactor used to schedule future events to r.  If r is None 
88      (the default), the reactor is reset to its default value. 
89   
90      This should only be used for unit tests. 
91      """ 
92      if r is None: 
93          r = reactor 
94      _theSimpleQueue._reactor = r 
 95