Lisandro Dalcin wrote:
> > Note that you can restore at the end of the /*try:*/ block, instead of in
> > the /*finally:*/ block:
> >
> > { PyThreadState *_save;
> > Py_UNBLOCK_THREADS
> > /*try:*/ {
> > try {foo();} catch(...) {Py_BLOCK_THREADS __Pyx_CppExn2PyErr();
> > {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__;
> > goto __pyx_L6;}}
> > Py_BLOCK_THREADS
> > }
> > /*finally:*/ {
> > int __pyx_why;
> > __pyx_why = 0; goto __pyx_L7;
> > __pyx_L6: __pyx_why = 4; goto __pyx_L7;
> > __pyx_L7:;
> > switch (__pyx_why) {
> > case 4: goto __pyx_L1_error;
> > }
> > }
> > }
> >
> > (it's exactly equivalent to my original proposal, but maybe cleaner that
> > way...)
>
> Sorry, I'm still confused. In case of errors, your code does
> Py_BLOCK_THREADS twice! Is that fine? Isn't a matching
> Py_UNBLOCK_THREADS required after __Pyx_CppExn2PyErr()? In short, is
> the pure C code below right?
>
> Py_BLOCK_THREADS
> foo()
> Py_UNBLOCK_THREADS
> Py_UNBLOCK_THREADS
Py_UNBLOCK_THREADS and Py_BLOCK_THREADS are only called once each, whatever the
"route".
In case of no exceptions, the route is:
Py_UNBLOCK_THREADS
/*try:*/ {
foo();
Py_BLOCK_THREADS // The one at the end of the /*try:*/ block, not the one
in the catch block.
}
/*finally:*/ {
...
}
In case of an exception, the route is:
Py_UNBLOCK_THREADS
/*try:*/ {
try {foo();} catch(...) {Py_BLOCK_THREADS ... goto __pyx_L6;}}
}
/*finally:*/ {
__pyx_L6: ...
}
Py_BLOCK_THREADS is called from the catch block.
Due to "goto __pyx_L6", the Py_BLOCK_THREADS at the end of the /*try:*/ block
is skipped.
Stephane
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev