title: Python PyGILState_{Ensure/Release} causes segfault while returning to C++ from Python code
body: <p><strong>UPDATE</strong> Well, it looks like adding PyEval_InitThreads() before the call to PyGILState_Ensure() does the trick. In my haste to figure things out I incorrectly attributed my "hanging" to PyEval_InitThreads().</p>
  
  <p>However, after reading some Python documentation I am wondering if this is the correct solution.</p>
  
  <blockquote>
    <p>It is not safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock.</p>
  </blockquote>
  
  <hr>
  
  <p>First of all, I am working on some modified GNU Radio code - particularly a modified gr_bin_statistics_f block. Now, there is a bug report (albeit an old one) which pretty much describes my exact situation.</p>
  
  <p><a href="http://gnuradio.org/redmine/issues/show/199" rel="noreferrer">http://gnuradio.org/redmine/issues/show/199</a></p>
  
  <p>Now, usrp_spectrum_sense.py which is mentioned in the bug report calls gr_bin_statistics_f (C++) which then calls back to Python periodically to re-tune the USRP (radio).</p>
  
  <p>Here is what happens when the Python code is called:</p>
  
  <pre><code>PyGILState_STATE d_gstate;
  d_gstate = PyGILState_Ensure();
  
  // call python code
  
  PyGILState_Release(d_gstate);
  </code></pre>
  
  <p>So, once we return from the Python code a segmentation fault occurs when PyGILState_Release(d_gstate) is called. While there are differences between my code and the original gr_bin_statistics_f, nothing seems to be remotely related to this.</p>
  
  <p>I read that calling PyEval_InitThreads() before PyGILState_Ensure() has solved the problem for some people, but it just causes my program to hang.</p>
  
  <p>Can anyone shed light on this for me? Or is it simply time to send a message to the GNU Radio mailing list?</p>
  
  <p>Using Python2.7 on Fedora 14 x86_64.</p>
  
  <p>Here is the GDB backtrace:</p>
  
  <pre><code>
  (gdb) c
  Continuing.
  [New Thread 0x7fabd3a8d700 (LWP 23969)]
  [New Thread 0x7fabd328c700 (LWP 23970)]
  [New Thread 0x7fabd2a8b700 (LWP 23971)]
  [New Thread 0x7fabd228a700 (LWP 23972)]
  [New Thread 0x7fabd1a89700 (LWP 23973)]
  [New Thread 0x7fabd1288700 (LWP 23974)]
  [New Thread 0x7fabd0a87700 (LWP 23975)]
  [New Thread 0x7fabbbfff700 (LWP 23976)]
  
  Program received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fabbbfff700 (LWP 23976)]
  0x00000036b3e0db00 in sem_post () from /lib64/libpthread.so.0
  (gdb) bt
  #0  0x00000036b3e0db00 in sem_post () from /lib64/libpthread.so.0
  #1  0x00000036c1317679 in PyThread_release_lock () from /usr/lib64/libpython2.7.so.1.0
  #2  0x00007fabd6159c1f in ~ensure_py_gil_state (this=0x2dc6fc0, x=887000000)
      at gnuradio_swig_py_general.cc:5593
  #3  gr_py_feval_dd::calleval (this=0x2dc6fc0, x=887000000) at gnuradio_swig_py_general.cc:5605
  #4  0x00007fabd77c4b6e in gr_noise_level_f::tune_window (this=0x2db3ca0, 
      target_freq=) at gr_noise_level_f.cc:97
  #5  0x00007fabd77c554b in gr_noise_level_f::work (this=0x2db3ca0, noutput_items=7, 
      input_items=, output_items=)
      at gr_noise_level_f.cc:115
  #6  0x00007fabd7860714 in gr_sync_block::general_work (this=0x2db3ca0, 
      noutput_items=, ninput_items=, 
      input_items=, output_items=) at gr_sync_block.cc:64
  #7  0x00007fabd7846ce4 in gr_block_executor::run_one_iteration (this=0x7fabbbffed90)
      at gr_block_executor.cc:299
  #8  0x00007fabd7864332 in gr_tpb_thread_body::gr_tpb_thread_body (this=0x7fabbbffed90, block=...)
      at gr_tpb_thread_body.cc:49
  #9  0x00007fabd785cce7 in operator() (function_obj_ptr=...) at gr_scheduler_tpb.cc:42
  #10 operator() (function_obj_ptr=...)
      at /home/tja/Research/energy/detector/gnuradio-3.3.0/gruel/src/include/gruel/thread_body_wrapper.h:49
  #11 boost::detail::function::void_function_obj_invoker0, void>::invoke (function_obj_ptr=...) at /usr/include/boost/function/function_template.hpp:153
  ---Type  to continue, or q  to quit---
  #12 0x00007fabd74914ef in operator() (this=)
      at /usr/include/boost/function/function_template.hpp:1013
  #13 boost::detail::thread_data >::run (this=)
      at /usr/include/boost/thread/detail/thread.hpp:61
  #14 0x00007fabd725ca55 in thread_proxy () from /usr/lib64/libboost_thread-mt.so.1.44.0
  #15 0x00000036b3e06d5b in start_thread () from /lib64/libpthread.so.0
  #16 0x00000036b3ae4a7d in clone () from /lib64/libc.so.6
  (gdb) 
  </code></pre>
  
  <p>Thanks for looking!</p>