Ticket #137 (defect)

Opened 2 years ago

Last modified 2 months ago

Sort out signal handling interaction (mostly SIGINT) between Python and C++ threads

Status: closed (fixed)

Reported by: eb Assigned to: eb
Priority: normal Milestone: release-3.2
Component: gnuradio-core Version: 3.0svn
Keywords: Cc:

When C++ code is blocked in a system call, it often takes two control-C's to kill the process, and then the return path seems a bit odd.

> This is the same reason we need the break. Without a timeout, the blocking
> call hangs completely and it takes two Ctrl-C hits to kill the application
> (and then, it kills it with an error (RuntimeError: not running).

If each thread has its own table of handlers, then this should be easy to fix. We can use the gr_local_sighandler class, and install the handler at the top of the main loop of gr_single_threaded_scheduler. When the signal is caught, it should propagate the information such that all instances of gr_single_threaded_scheduler return cleanly, possibly indicating that they were stopped with a SIGINT.

We'll need to investigate the interaction of signal handlers and threads under at least Linux, *BSD and OS/X.

Change History

02/09/07 10:55:57: Modified by eb

  • description changed.

02/09/07 10:58:26: Modified by eb

  • status changed from new to assigned.
  • description changed.

02/09/07 10:59:02: Modified by eb

  • type changed from enhancement to defect.

02/09/07 11:01:11: Modified by eb

  • description changed.

07/26/07 09:08:48: Modified by jcorgan

  • owner changed from eb to jcorgan.
  • status changed from assigned to new.
  • milestone changed from to-be-decided to release-3.2.

08/04/07 12:06:04: Modified by jcorgan

  • status changed from new to assigned.
  • milestone changed from release-3.2 to release-3.1.

08/23/07 14:29:03: Modified by eb

  • owner changed from jcorgan to eb.
  • status changed from assigned to new.

08/23/07 14:29:11: Modified by eb

  • status changed from new to assigned.

08/28/07 18:42:36: Modified by eb

Each thread doesn't have its own table of handlers, only its own set of signal masks. See pthread_sigmask. r6201 implements a (fragile) trial fix. Fixing this robustly requires a substantial reworking of all of the thread management code, and most likely requires using sigwait(2) as described in http://www.serpentine.com/blog/threads-faq/mixing-threads-and-signals-unix and http://www.linuxjournal.com/article/2121.

Done properly, a solution should handle mblocks and flowgraphs at the same time, preferably with a single piece of code.

10/16/07 12:13:24: Modified by jcorgan

  • milestone changed from release-3.1 to release-3.2.

For Release 3.1 branch, the implementation works as follows:

* A SIGINT handler is installed in gr_top_block::start(), which is also called by gr_top_block::run().

* A call to join() occurs for each flowgraph thread when gr_top_block::wait() is called. This method gets called from gr_top_block.run() as well.

* The SIGINT handler will clear the enable flag for each flowgraph thread, causing them to eventually fall out the bottom of there thread function

* When all flowgraph threads have exited, the join() call returns.

If the gr.top_block() is used with start() and stop(), such as from within a GUI, then it is the user's responsibility to ensure that stop() and wait() is actually called.

A completel reworking of this code will happen for release 3.1 as part of the C++ only work.

07/24/08 09:23:01: Modified by eb

  • status changed from assigned to closed.
  • resolution set to fixed.

Fixed in mp-sched feature branch.