summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/python
diff options
context:
space:
mode:
authoreb2009-03-19 19:57:46 +0000
committereb2009-03-19 19:57:46 +0000
commit06d584f74eb9407d804ce9d560c31d7c240b086f (patch)
treeee5d1f437be328c95d46e30cdd5d3d93dd522f1e /gnuradio-core/src/python
parentf430647f21ae456591e2f8152e6234cf8752f245 (diff)
downloadgnuradio-06d584f74eb9407d804ce9d560c31d7c240b086f.tar.gz
gnuradio-06d584f74eb9407d804ce9d560c31d7c240b086f.tar.bz2
gnuradio-06d584f74eb9407d804ce9d560c31d7c240b086f.zip
Fix for ticket:348, Stopping a process does not properly terminate USRP1.
This is a partial merge from eb/t348 10637:10648, and contains the actual fix. The next commit will contain the rest of the merge which adds a -N <nsamples> argument to usrp_siggen.py, usrp_siggen.cc and test_usrp_standard_tx.cc. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10649 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/python')
-rw-r--r--gnuradio-core/src/python/gnuradio/gr/top_block.py27
1 files changed, 25 insertions, 2 deletions
diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py
index a3161170a..b9c436a0a 100644
--- a/gnuradio-core/src/python/gnuradio/gr/top_block.py
+++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py
@@ -32,6 +32,25 @@ import gr_threading as _threading
#
# This kludge allows ^C to interrupt top_block.run and top_block.wait
#
+# The problem that we are working around is that Python only services
+# signals (e.g., KeyboardInterrupt) in its main thread. If the main
+# thread is blocked in our C++ version of wait, even though Python's
+# SIGINT handler fires, and even though there may be other python
+# threads running, no one will know. Thus instead of directly waiting
+# in the thread that calls wait (which is likely to be the Python main
+# thread), we create a separate thread that does the blocking wait,
+# and then use the thread that called wait to do a slow poll of an
+# event queue. That thread, which is executing "wait" below is
+# interruptable, and if it sees a KeyboardInterrupt, executes a stop
+# on the top_block, then goes back to waiting for it to complete.
+# This ensures that the unlocked wait that was in progress (in the
+# _top_block_waiter thread) can complete, release its mutex and back
+# out. If we don't do that, we are never able to clean up, and nasty
+# things occur like leaving the USRP transmitter sending a carrier.
+#
+# See also top_block.wait (below), which uses this class to implement
+# the interruptable wait.
+#
class _top_block_waiter(_threading.Thread):
def __init__(self, tb):
_threading.Thread.__init__(self)
@@ -45,8 +64,12 @@ class _top_block_waiter(_threading.Thread):
self.event.set()
def wait(self):
- while not self.event.isSet():
- self.event.wait(0.100)
+ try:
+ while not self.event.isSet():
+ self.event.wait(0.100)
+ except KeyboardInterrupt:
+ self.tb.stop()
+ self.wait()
#