Stephane, let's change our deal... Here you have a patch with new
testcase included, you can use "hg import --no-commit
cpp_exc_nogil.diff" to apply the patch.

Try to run the test on your side (python runtests.py
cpp_exceptions_nogil), next test with your own code. Next try hard to
break my fix :-). If all is fine, I'll push it.


-- 
Lisandro Dalcin
---------------
CIMEC (INTEC/CONICET-UNL)
Predio CONICET-Santa Fe
Colectora RN 168 Km 472, Paraje El Pozo
Tel: +54-342-4511594 (ext 1011)
Tel/Fax: +54-342-4511169
diff -r 646494738535 Cython/Compiler/ExprNodes.py
--- a/Cython/Compiler/ExprNodes.py	Thu Sep 23 01:34:58 2010 -0700
+++ b/Cython/Compiler/ExprNodes.py	Fri Sep 24 12:06:57 2010 -0300
@@ -2863,6 +2863,7 @@
                  or func_type.exception_check:
             self.is_temp = 1
         # C++ exception handler
+        self.nogil = env.nogil
         if func_type.exception_check == '+':
             if func_type.exception_value is None:
                 env.use_utility_code(cpp_exception_utility_code)
@@ -2957,6 +2958,8 @@
                             func_type.exception_value.entry.cname)
                     else:
                         raise_py_exception = '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.")' % func_type.exception_value.entry.cname
+                    if self.nogil:
+                        raise_py_exception = 'Py_BLOCK_THREADS; %s; Py_UNBLOCK_THREADS' % raise_py_exception
                     code.putln(
                     "try {%s%s;} catch(...) {%s; %s}" % (
                         lhs,
diff -r 646494738535 tests/run/cpp_exceptions_nogil.pyx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/run/cpp_exceptions_nogil.pyx	Fri Sep 24 12:06:57 2010 -0300
@@ -0,0 +1,181 @@
+cdef int raise_TypeError() except *:
+    raise TypeError("custom")
+
+cdef extern from "cpp_exceptions_nogil_helper.h" nogil:
+    cdef void foo "foo"(int i) except +
+    cdef void bar "foo"(int i) except +ValueError
+    cdef void spam"foo"(int i) except +raise_TypeError
+
+def test_foo():
+    """
+    >>> test_foo()
+    """
+    #
+    foo(0)
+    foo(0)
+    with nogil:
+        foo(0)
+        foo(0)
+    #
+    try:
+        with nogil:
+            foo(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            foo(0)
+        with nogil:
+            foo(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            foo(0)
+        with nogil:
+            foo(1)
+    except:
+        with nogil:
+            foo(0)
+    finally:
+        with nogil:
+            foo(0)
+        pass
+    #
+    try:
+        with nogil:
+            foo(0)
+            foo(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            foo(0)
+            foo(1)
+    except:
+        with nogil:
+            foo(0)
+    finally:
+        with nogil:
+            foo(0)
+        pass
+    #
+
+def test_bar():
+    """
+    >>> test_bar()
+    """
+    #
+    bar(0)
+    bar(0)
+    with nogil:
+        bar(0)
+        bar(0)
+    #
+    try:
+        with nogil:
+            bar(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            bar(0)
+        with nogil:
+            bar(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            bar(0)
+        with nogil:
+            bar(1)
+    except ValueError:
+        with nogil:
+            bar(0)
+    finally:
+        with nogil:
+            bar(0)
+        pass
+    #
+    try:
+        with nogil:
+            bar(0)
+            bar(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            bar(0)
+            bar(1)
+    except ValueError:
+        with nogil:
+            bar(0)
+    finally:
+        with nogil:
+            bar(0)
+        pass
+    #
+
+def test_spam():
+    """
+    >>> test_spam()
+    """
+    #
+    spam(0)
+    spam(0)
+    with nogil:
+        spam(0)
+        spam(0)
+    #
+    try:
+        with nogil:
+            spam(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            spam(0)
+        with nogil:
+            spam(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            spam(0)
+        with nogil:
+            spam(1)
+    except TypeError:
+        with nogil:
+            spam(0)
+    finally:
+        with nogil:
+            spam(0)
+        pass
+    #
+    try:
+        with nogil:
+            spam(0)
+            spam(0)
+    finally:
+        pass
+    #
+    try:
+        with nogil:
+            spam(0)
+            spam(1)
+    except TypeError:
+        with nogil:
+            spam(0)
+    finally:
+        with nogil:
+            spam(0)
+        pass
+    #
diff -r 646494738535 tests/run/cpp_exceptions_nogil_helper.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/run/cpp_exceptions_nogil_helper.h	Fri Sep 24 12:06:57 2010 -0300
@@ -0,0 +1,6 @@
+void foo(int i) {
+  if (i==0)
+    return;
+  else
+    throw i;
+}
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to