# Python-based sink block causes graph freeze under certain conditions

**URL:** <https://www.ruby-forum.com/t/python-based-sink-block-causes-graph-freeze-under-certain-conditions/246278>\
**Category:** GNU Radio\
**Created:** [September 25, 2013, 11:15pm UTC](https://www.ruby-forum.com/t/python-based-sink-block-causes-graph-freeze-under-certain-conditions/246278 "2013-09-25T23:15:56Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [September 25, 2013, 11:15pm UTC](https://www.ruby-forum.com/t/python-based-sink-block-causes-graph-freeze-under-certain-conditions/246278/1 "2013-09-25T23:15:56Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![Ethan\_Trewhitt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/ecb155/32.png) [@Ethan\_Trewhitt](https://www.ruby-forum.com/u/Ethan_Trewhitt)\
**Post date:** [September 25, 2013, 11:23pm UTC](https://www.ruby-forum.com/t/python-based-sink-block-causes-graph-freeze-under-certain-conditions/246278/2 "2013-09-25T23:23:33Z")

</div>

Apologies - this bug has been found already:  
[http://gnuradio.org/redmine/issues/594](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!
