[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Discuss-gnuradio] Python-based sink block causes graph freeze under
From: |
Ethan Trewhitt |
Subject: |
Re: [Discuss-gnuradio] Python-based sink block causes graph freeze under certain conditions |
Date: |
Wed, 25 Sep 2013 17:22:12 -0400 |
Apologies - this bug has been found already:
http://gnuradio.org/redmine/issues/594
I tracked down the freeze to the "unlock()" call in selector.py, which
led me to the bug report. Hope it gets fixed soon :)
Until then, no graph changes!
On Wed, Sep 25, 2013 at 5:08 PM, Ethan Trewhitt <address@hidden> wrote:
> I created a Python-based sink block that works well in most cases. I
> started having problems when I created a GUI checkbox (using GRC) to
> control a Selector or Valve block in a separate subgraph. As soon as I
> change the checkbox, the whole graph freezes.
>
> So far I have tracked this down to the Python sink block. I grabbed
> one of the built-in blocks and build a test that demonstrates the
> problem in the simplest way. The graph looks like this (there are two
> separate subgraphs):
>
> Subgraph 1:
> Constant Source #1 -> Throttle -> Python test sink
>
> Subgraph 2:
> Constant Source #2 -> Selector -> Throttle -> Null sink
> Constant Source #3 -> ^ (points to the selector, also)
>
> The checkbox switches the selector between Constant Source #2 and #3.
> Whenever the Python test sink is part of the upper graph, switching
> the lower graph (using the checkbox) causes everything to freeze.
>
> Debugging steps:
>
> I ran this graph via GDB and watched threads being created/destroyed.
> Whenever the checkbox is changed, a bunch of threads are killed. I'm
> guessing this is GR shutting down a bunch of blocks and trying to
> restart them with different connections, but something in the Python
> block isn't getting shut down, so everything stalls.
>
> In the code below, if you replace the reference to "self.sink" with
> "self.blocks_null_sink_1" in the connection setup, the problem goes
> away.
>
> Here's the code:
>
>
> #!/usr/bin/env python
>
> from gnuradio import blocks
> from gnuradio import gr
> from gnuradio.wxgui import forms
> from grc_gnuradio import blks2 as grc_blks2
> from grc_gnuradio import wxgui as grc_wxgui
> import numpy
>
> import wx
>
> class sink_test(grc_wxgui.top_block_gui):
>
> def __init__(self):
> grc_wxgui.top_block_gui.__init__(self, title="Sink Test")
> self.check = check = True
>
> ##################################################
> # Blocks
> ##################################################
> self._check_check_box = forms.check_box(
> parent=self.GetWin(),
> value=self.check,
> callback=self.set_check,
> label="check",
> true=True,
> false=False,
> )
> self.Add(self._check_check_box)
> self.const_source_x_0_1 = gr.sig_source_c(0, gr.GR_CONST_WAVE, 0, 0,
> 12)
> self.const_source_x_0_0 = gr.sig_source_c(0, gr.GR_CONST_WAVE, 0, 0,
> 0)
> self.const_source_x_0 = gr.sig_source_f(0, gr.GR_CONST_WAVE, 0, 0, 0)
> self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, 1000)
> self.blocks_throttle_1 = blocks.throttle(gr.sizeof_gr_complex*1, 1000)
> self.blocks_null_sink_0 = blocks.null_sink(gr.sizeof_gr_complex*1)
> self.blocks_null_sink_1 = blocks.null_sink(gr.sizeof_float*1)
> # not used by default. enable by connecting below
> self.blks2_selector_0 = grc_blks2.selector(
> item_size=gr.sizeof_gr_complex*1,
> num_inputs=2,
> num_outputs=1,
> input_index=0 if check else 1,
> output_index=0,
> )
> self.sink = test_sink()
>
> ##################################################
> # Connections
> ##################################################
> self.connect((self.const_source_x_0, 0), (self.blocks_throttle_0, 0))
> self.connect((self.blocks_throttle_0, 0), (self.sink, 0))
> # change this from self.sink to self.blocks_null_sink_1 to see the
> problem go away
> self.connect((self.const_source_x_0_0, 0), (self.blks2_selector_0, 1))
> self.connect((self.blks2_selector_0, 0), (self.blocks_throttle_1, 0))
> self.connect((self.blocks_throttle_1, 0), (self.blocks_null_sink_0,
> 0))
> self.connect((self.const_source_x_0_1, 0), (self.blks2_selector_0, 0))
>
>
> def get_check(self):
> return self.check
>
> def set_check(self, check):
> self.check = check
> self._check_check_box.set_value(self.check)
> self.blks2_selector_0.set_input_index(int(0 if self.check else 1))
>
> # Python block
> class test_sink(gr.sync_block):
> def __init__(self):
> gr.sync_block.__init__(
> self,
> name = "test_sink",
> in_sig = [numpy.float32],
> out_sig = None,
> )
> self.key = None
>
> def work(self, input_items, output_items):
> return len(input_items[0])
>
> if __name__ == '__main__':
> tb = sink_test()
> tb.Run(True)