"""
Helpers for running tests for which Twisted reactor in execcuted in a
separate thread.

This code is under based on nose/twistedtools.py which is under LGPL license.
"""
from threading import Thread

from twisted.python import threadable
threadable.registerAsIOThread()

_twisted_thread = None


def threaded_reactor():
    """
    Start the Twisted reactor in a separate thread, if not already done.
    Returns the reactor.
    The thread will automatically be destroyed when all the tests are done.
    """
    global _twisted_thread
    try:
        from twisted.internet import reactor
        # This is ugly and stupid, but I have no idea how to reset
        # the reactor.
        reactor.__init__()
    except ImportError:
        return None, None
    if not _twisted_thread:

        _twisted_thread = Thread(target=lambda: reactor.run(
                installSignalHandlers=False))
        _twisted_thread.setDaemon(True)
        _twisted_thread.start()
    return reactor, _twisted_thread


def stop_reactor():
    """
    Stop the reactor and join the reactor thread until it stops.
    Call this function in teardown at the module or package level to
    reset the twisted system after your tests. You *must* do this if
    you mix tests using these tools and tests using twisted.trial.
    """
    global _twisted_thread

    def stop_reactor():
        '''Helper for calling stop from withing the thread.'''
        reactor.stop()
        for p in reactor.getDelayedCalls():
            if p.active():
                p.cancel()

    reactor.callFromThread(stop_reactor)
    reactor_thread.join()
    _twisted_thread = None


# Export global reactor variable, as Twisted does
reactor, reactor_thread = threaded_reactor()

@@ -200,78 +200,19 @@
 ead%0A
-%0Afrom twisted.python import threadable%0Athreadable.registerAsIOThread()
+import time
 %0A%0A_t
@@ -236,22 +236,33 @@
 one%0A
+_reactor = None
 %0A%0A
+%0A
 def 
-threaded
+get
 _rea
@@ -489,62 +489,84 @@
 read
-%0A    try:%0A        from twisted.internet import
+, _reactor%0A%0A    if _twisted_thread:%0A        return _reactor%0A%0A    def
  reactor
 %0A   
@@ -561,16 +561,23 @@
  reactor
+_run():
 %0A       
@@ -581,66 +581,67 @@
     
-# This is ugly and stupid, but I have no idea how to re
+_reactor.__init__()%0A        _reactor._startedBefore = Fal
 se
-t
 %0A   
@@ -649,22 +649,17 @@
     
-# the 
+_
 reactor.
 %0A   
@@ -650,24 +650,40 @@
    _reactor.
+_started = False
 %0A        rea
@@ -679,24 +679,25 @@
         
+_
 reactor.
 __init__
@@ -692,89 +692,125 @@
 tor.
-__init__(
+run(installSignalHandlers=False
 )%0A
+%0A
     
-except I
+from twisted.internet i
 mport
-Error:%0A        return None, None%0A    if not _
+ reactor as twisted_reactor%0A    _reactor = 
 twisted_
 thre
@@ -809,21 +809,17 @@
 ted_
-th
 rea
-d:%0A%0A    
+ctor%0A%0A
     
@@ -854,79 +854,69 @@
 get=
-lambda: 
 reactor
-.run(%0A                installSignalHandlers=False))%0A    
+_run)%0A    _twisted_thread.setName('threaded_reactor')%0A
     
@@ -947,20 +947,16 @@
 n(True)%0A
-    
     _twi
@@ -979,43 +979,92 @@
 t()%0A
+%0A
     
-return reactor, _twisted_thread
+# Wait a bit for the reactor to start.%0A    time.sleep(0.01)%0A    return _reactor
 %0A%0A%0Ad
@@ -1394,16 +1394,70 @@
 d_thread
+, _reactor%0A%0A    if not _twisted_thread:%0A        return
 %0A%0A    de
@@ -1541,24 +1541,25 @@
 '''%0A        
+_
 reactor.stop
@@ -1565,294 +1565,228 @@
 p()%0A
-        for p in reactor.getDelayedCalls():%0A            if p.active():%0A                p.cancel()%0A%0A    reactor.callFromThread(stop_reactor)%0A    reactor_thread.join()%0A    _twisted_thread = None%0A%0A%0A# Export global reactor variable, as Twisted does%0Areactor, reactor_thread = threaded_reactor()
+%0A    _reactor.callFromThread(stop_reactor)%0A    _twisted_thread.join(2)%0A    if _twisted_thread.isAlive():%0A        _twisted_thread = None%0A        raise AssertionError('Failed to stop the reactor.')%0A%0A    _twisted_thread = None
 %0A

Refactor threaded reactor.