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
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.

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.