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

Reply via email to