Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r72182:1befc86bfa19
Date: 2014-06-23 22:46 +0200
http://bitbucket.org/pypy/pypy/changeset/1befc86bfa19/

Log:    Fix a latent memory leak: in a cffi callback invoked in an
        "unexpected" thread, always unregister newly registered
        ExecutionContext.

        Fixes cffi_tests/test_verify's test_callback_in_thread.

diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py
--- a/pypy/interpreter/miscutils.py
+++ b/pypy/interpreter/miscutils.py
@@ -17,6 +17,9 @@
     def enter_thread(self, space):
         self._value = space.createexecutioncontext()
 
+    def try_enter_thread(self, space):
+        return False
+
     def signals_enabled(self):
         return True
 
diff --git a/pypy/module/_cffi_backend/ccallback.py 
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -183,9 +183,12 @@
         misc._raw_memclear(ll_res, SIZE_OF_FFI_ARG)
         return
     #
+    must_leave = False
     ec = None
+    space = callback.space
     try:
-        ec = cerrno.get_errno_container(callback.space)
+        must_leave = space.threadlocals.try_enter_thread(space)
+        ec = cerrno.get_errno_container(space)
         cerrno.save_errno_into(ec, e)
         extra_line = ''
         try:
@@ -206,5 +209,7 @@
         except OSError:
             pass
         callback.write_error_return_value(ll_res)
+    if must_leave:
+        space.threadlocals.leave_thread(space)
     if ec is not None:
         cerrno.restore_errno_from(ec)
diff --git a/pypy/module/thread/threadlocals.py 
b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -27,6 +27,12 @@
         "Notification that the current thread is about to start running."
         self._set_ec(space.createexecutioncontext())
 
+    def try_enter_thread(self, space):
+        if rthread.get_ident() in self._valuedict:
+            return False
+        self.enter_thread(space)
+        return True
+
     def _set_ec(self, ec):
         ident = rthread.get_ident()
         if self._mainthreadident == 0 or self._mainthreadident == ident:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to