Problem with gr_head in simple graph

Hi!

I am encountering a problem with gr_head. For my testcase, I set up a
flow graph:

(…)
tcp_src = qtblocks.tcp_source (gr.sizeof_char, “127.0.0.1”, 7777)
head = gr.head(gr.sizeof_char, 4)
vector_sink = gr.vector_sink_b()
self.fg.connect (tcp_src, head, vector_sink)
(…)

The logging in the single threaded scheduler is active. It outputs the
following:

— snip —
<gr_block tcp_source (5)> source
noutput_items = 32767
general_work: noutput_items = 32767 result = 0

<gr_block head (6)> regular 1:1
max_items_avail = 0
noutput_items = 32767
BLKD_IN

<gr_block vector_sink_b (7)> sink
max_items_avail = 0
noutput_items = 0
BLKD_IN

<gr_block tcp_source (5)> source
noutput_items = 32767
general_work: noutput_items = 32767 result = 12

<gr_block head (6)> regular 1:1
max_items_avail = 12
noutput_items = 32767
general_work: noutput_items = 12 result = 4

<gr_block vector_sink_b (7)> sink
max_items_avail = 4
noutput_items = 4
general_work: noutput_items = 4 result = 4

<gr_block tcp_source (5)> Skipping source

<gr_block head (6)> regular 1:1
max_items_avail = 8
noutput_items = 32767
general_work: noutput_items = 8 result = -1
were_done

<gr_block vector_sink_b (7)> sink
were_done

<gr_block tcp_source (5)> source
noutput_items = 32759
general_work: noutput_items = 32759 result = 0

<gr_block head (6)>
<gr_block vector_sink_b (7)>
<gr_block tcp_source (5)> source
noutput_items = 32759
general_work: noutput_items = 32759 result = 0
— snip —

The problem is that the graph does not stop. The source still outputs
items though its destination signaled done.

Greetings,
Dominik

On Wed, Mar 07, 2007 at 11:29:19AM +0100, Dominik A. wrote:

(…)

The logging in the single threaded scheduler is active. It outputs the
following:

— snip —
<gr_block tcp_source (5)> source
noutput_items = 32767
general_work: noutput_items = 32767 result = 0

This is the first odd thing, and I believe the cause of the problem.
Your source does not block until it receives something.
Generally speaking, returning 0 is a bad idea.

In the case of sources, you should block until you get something, then
return whatever you got.

What happens when any block declares that it is done, is that
everything is allowed to run until no further progress can be made.
In your case, the upstream block, the tcp_source, will run until it’s
finally “output blocked” because of “back pressure” that results
because gr.head is done. Given that your source produces 0 output,
it’ll never see any back pressure and thus will never end.

Philosophically, we don’t stop everything as soon as any block says
it’s done, because other blocks may have side effects that we are
still interested in (e.g., logging results), or are still able to make
progress.

Outside of your test case, what are you really trying to do?

Eric

Hi!

This is the first odd thing, and I believe the cause of the problem.
Your source does not block until it receives something.
Generally speaking, returning 0 is a bad idea.

In the case of sources, you should block until you get something, then
return whatever you got.
The source receives data from time to time. If I return -1 if there is
no new data, the scheduler marks my source as “done” and skips it
forever. How should I block?

What happens when any block declares that it is done, is that
everything is allowed to run until no further progress can be made.
In your case, the upstream block, the tcp_source, will run until it’s
finally “output blocked” because of “back pressure” that results
because gr.head is done. Given that your source produces 0 output,
it’ll never see any back pressure and thus will never end.
Ok. I understand that there should be some back pressure. But in this
case, back pressure is predictable. It is just a question of the buffer
size. gr.head owns more buffer space than it will ever process.

Philosophically, we don’t stop everything as soon as any block says
it’s done, because other blocks may have side effects that we are
still interested in (e.g., logging results), or are still able to make
progress.
How will a block make progress, especially a source, if his outputs are
blocked?
If all outputs of the source are blocked because they are done, I think
it is a good indication that signal processing is completed.

I do not really need this outside my testcase, since in a real
application, it should not quit when the graph stops.

Outside of your test case, what are you really trying to do?
Transferring status information in an evaluation system from a receiver
to the transmitter.

Thanks for your reply,
Dominik