Add python-eventlet package to MOS 8.0 repository
[packages/trusty/python-eventlet.git] / python-eventlet / eventlet / green / thread.py
similarity index 68%
rename from eventlet/eventlet/green/thread.py
rename to python-eventlet/eventlet/green/thread.py
index 236031089521045f7c298c2b79ecba115f4639a7..5c7446fa2ba91926d5d07bb150a5bb59a1c34099 100644 (file)
@@ -3,6 +3,7 @@ from eventlet.support.six.moves import _thread as __thread
 from eventlet.support import greenlets as greenlet, six
 from eventlet import greenthread
 from eventlet.semaphore import Semaphore as LockType
 from eventlet.support import greenlets as greenlet, six
 from eventlet import greenthread
 from eventlet.semaphore import Semaphore as LockType
+import sys
 
 
 __patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
 
 
 __patched__ = ['get_ident', 'start_new_thread', 'start_new', 'allocate_lock',
@@ -43,6 +44,29 @@ def __thread_body(func, args, kwargs):
 
 
 def start_new_thread(function, args=(), kwargs=None):
 
 
 def start_new_thread(function, args=(), kwargs=None):
+    if (sys.version_info >= (3, 4)
+            and getattr(function, '__module__', '') == 'threading'
+            and hasattr(function, '__self__')):
+        # Since Python 3.4, threading.Thread uses an internal lock
+        # automatically released when the python thread state is deleted.
+        # With monkey patching, eventlet uses green threads without python
+        # thread state, so the lock is not automatically released.
+        #
+        # Wrap _bootstrap_inner() to release explicitly the thread state lock
+        # when the thread completes.
+        thread = function.__self__
+        bootstrap_inner = thread._bootstrap_inner
+
+        def wrap_bootstrap_inner():
+            try:
+                bootstrap_inner()
+            finally:
+                # The lock can be cleared (ex: by a fork())
+                if thread._tstate_lock is not None:
+                    thread._tstate_lock.release()
+
+        thread._bootstrap_inner = wrap_bootstrap_inner
+
     kwargs = kwargs or {}
     g = greenthread.spawn_n(__thread_body, function, args, kwargs)
     return get_ident(g)
     kwargs = kwargs or {}
     g = greenthread.spawn_n(__thread_body, function, args, kwargs)
     return get_ident(g)