summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/runtime')
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am4
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.i6
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i5
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_executor.cc3
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.cc25
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.h2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc5
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.h2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.i7
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.i65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i3
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.cc6
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.h7
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.i43
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc8
-rw-r--r--gnuradio-core/src/lib/runtime/gr_unittests.h9
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.cc4
-rw-r--r--gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc85
-rw-r--r--gnuradio-core/src/lib/runtime/qa_set_msg_handler.h43
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i7
22 files changed, 352 insertions, 45 deletions
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
index dd9a8ea64..3dd2b42f5 100644
--- a/gnuradio-core/src/lib/runtime/Makefile.am
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -81,6 +81,7 @@ libruntime_qa_la_SOURCES = \
qa_gr_io_signature.cc \
qa_gr_vmcircbuf.cc \
qa_block_tags.cc \
+ qa_set_msg_handler.cc \
qa_runtime.cc
grinclude_HEADERS = \
@@ -140,9 +141,9 @@ noinst_HEADERS = \
qa_gr_top_block.h \
qa_gr_vmcircbuf.h \
qa_block_tags.h \
+ qa_set_msg_handler.h \
qa_runtime.h
-if PYTHON
swiginclude_HEADERS = \
gr_basic_block.i \
gr_block.i \
@@ -162,4 +163,3 @@ swiginclude_HEADERS = \
gr_sync_interpolator.i \
gr_top_block.i \
runtime.i
-endif
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
index 2fa1066cb..0e0dad16b 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
@@ -56,7 +56,7 @@ gr_basic_block::~gr_basic_block()
}
gr_basic_block_sptr
-gr_basic_block::basic_block()
+gr_basic_block::to_basic_block()
{
return shared_from_this();
}
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
index b8797fdc6..ce7a1aa1d 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2008,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2008,2009,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,6 +26,7 @@
#include <gr_runtime_types.h>
#include <gr_sptr_magic.h>
#include <boost/enable_shared_from_this.hpp>
+#include <boost/function.hpp>
#include <gr_msg_accepter.h>
#include <string>
@@ -42,9 +43,27 @@
class gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block>
{
+ typedef boost::function<void(pmt::pmt_t)> msg_handler_t;
+
+private:
+ /*
+ * This function is called by the runtime system to dispatch messages.
+ *
+ * The thread-safety guarantees mentioned in set_msg_handler are implemented
+ * by the callers of this method.
+ */
+ void dispatch_msg(pmt::pmt_t msg)
+ {
+ if (d_msg_handler) // Is there a handler?
+ d_msg_handler(msg); // Yes, invoke it.
+ };
+
+ msg_handler_t d_msg_handler;
+
protected:
friend class gr_flowgraph;
friend class gr_flat_flowgraph; // TODO: will be redundant
+ friend class gr_tpb_thread_body;
enum vcolor { WHITE, GREY, BLACK };
@@ -81,7 +100,7 @@ public:
std::string name() const { return d_name; }
gr_io_signature_sptr input_signature() const { return d_input_signature; }
gr_io_signature_sptr output_signature() const { return d_output_signature; }
- gr_basic_block_sptr basic_block(); // Needed for Python type coercion
+ gr_basic_block_sptr to_basic_block(); // Needed for Python/Guile type coercion
/*!
* \brief Confirm that ninputs and noutputs is an acceptable combination.
@@ -99,15 +118,34 @@ public:
virtual bool check_topology(int ninputs, int noutputs) { return true; }
/*!
- * \brief Block message handler.
- *
- * \param msg Arbitrary message encapsulated as pmt::pmt_t
+ * \brief Set the callback that is fired when messages are available.
*
- * This function is called by the runtime system whenever there are
- * messages in its queue. Blocks should override this to receive
- * messages; the default behavior is to drop them on the floor.
+ * \p msg_handler can be any kind of function pointer or function object
+ * that has the signature:
+ * <pre>
+ * void msg_handler(pmt::pmt msg);
+ * </pre>
+ *
+ * (You may want to use boost::bind to massage your callable into the
+ * correct form. See gr_nop.{h,cc} for an example that sets up a class
+ * method as the callback.)
+ *
+ * Blocks that desire to handle messages must call this method in their
+ * constructors to register the handler that will be invoked when messages
+ * are available.
+ *
+ * If the block inherits from gr_block, the runtime system will ensure that
+ * msg_handler is called in a thread-safe manner, such that work and
+ * msg_handler will never be called concurrently. This allows msg_handler
+ * to update state variables without having to worry about thread-safety
+ * issues with work, general_work or another invocation of msg_handler.
+ *
+ * If the block inherits from gr_hier_block2, the runtime system will
+ * ensure that no reentrant calls are made to msg_handler.
*/
- virtual void handle_msg(pmt::pmt_t msg) { };
+ template <typename T> void set_msg_handler(T msg_handler){
+ d_msg_handler = msg_handler_t(msg_handler);
+ }
};
inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs)
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i
index 60e08aac3..03d4725d5 100644
--- a/gnuradio-core/src/lib/runtime/gr_basic_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -40,13 +40,15 @@ public:
gr_io_signature_sptr input_signature() const;
gr_io_signature_sptr output_signature() const;
long unique_id() const;
- gr_basic_block_sptr basic_block();
+ gr_basic_block_sptr to_basic_block();
bool check_topology (int ninputs, int noutputs);
};
%rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated;
long gr_basic_block_ncurrently_allocated();
+#ifdef SWIGPYTHON
%pythoncode %{
gr_basic_block_sptr.__repr__ = lambda self: "<gr_basic_block %s (%d)>" % (self.name(), self.unique_id ())
%}
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
index 2de354878..bb0c5f221 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -56,8 +56,3 @@ class gr_block : public gr_basic_block {
gr_block_detail_sptr detail () const { return d_detail; }
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
};
-
-%pythoncode %{
-gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
-gr_block_sptr.block = lambda self: self
-%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
index 112150235..a8d0bc1c8 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc
@@ -93,8 +93,7 @@ propagate_tags(gr_block::tag_propagation_policy_t policy, gr_block_detail *d,
std::vector<pmt::pmt_t> &rtags)
{
// Move tags downstream
- // if a sink, we don't need to move downstream;
- // and do not bother if block uses TAGS_NONE attribute
+ // if a sink, we don't need to move downstream
if(d->sink_p()) {
return true;
}
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc
index 0b2eb52a0..03d5a8738 100644
--- a/gnuradio-core/src/lib/runtime/gr_buffer.cc
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc
@@ -80,7 +80,8 @@ minimum_buffer_items (long type_size, long page_size)
gr_buffer::gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link)
: d_base (0), d_bufsize (0), d_vmcircbuf (0),
d_sizeof_item (sizeof_item), d_link(link),
- d_write_index (0), d_abs_write_offset(0), d_done (false)
+ d_write_index (0), d_abs_write_offset(0), d_done (false),
+ d_last_min_items_read(0)
{
if (!allocate_buffer (nitems, sizeof_item))
throw std::bad_alloc ();
@@ -162,7 +163,10 @@ gr_buffer::space_available ()
min_items_read = std::min(min_items_read, d_readers[i]->nitems_read());
}
- prune_tags(min_items_read);
+ if(min_items_read != d_last_min_items_read) {
+ prune_tags(d_last_min_items_read);
+ d_last_min_items_read = min_items_read;
+ }
// The -1 ensures that the case d_write_index == d_read_index is
// unambiguous. It indicates that there is no data for the reader
@@ -240,18 +244,23 @@ gr_buffer::prune_tags(uint64_t max_time)
buffer's mutex al la the scoped_lock line below.
*/
//gruel::scoped_lock guard(*mutex());
+ std::deque<pmt::pmt_t>::iterator itr = d_item_tags.begin();
- int n = 0;
uint64_t item_time;
- std::deque<pmt::pmt_t>::iterator itr = d_item_tags.begin();
+ // Since tags are not guarenteed to be in any particular order,
+ // we need to erase here instead of pop_front. An erase in the
+ // middle invalidates all iterators; so this resets the iterator
+ // to find more. Mostly, we wil be erasing from the front and
+ // therefore lose little time this way.
while(itr != d_item_tags.end()) {
item_time = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*itr, 0));
if(item_time < max_time) {
- d_item_tags.pop_front();
- n++;
+ d_item_tags.erase(itr);
+ itr = d_item_tags.begin();
}
- itr++;
+ else
+ itr++;
}
}
@@ -310,7 +319,7 @@ gr_buffer_reader::get_tags_in_range(std::vector<pmt::pmt_t> &v,
while(itr != d_buffer->get_tags_end()) {
item_time = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*itr, 0));
- if((item_time >= abs_start) && (item_time <= abs_end)) {
+ if((item_time >= abs_start) && (item_time < abs_end)) {
v.push_back(*itr);
}
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h
index fe0e7585d..aa26f1e09 100644
--- a/gnuradio-core/src/lib/runtime/gr_buffer.h
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.h
@@ -135,7 +135,7 @@ class gr_buffer {
uint64_t d_abs_write_offset; // num items written since the start
bool d_done;
std::deque<pmt::pmt_t> d_item_tags;
-
+ uint64_t d_last_min_items_read;
unsigned
index_add (unsigned a, unsigned b)
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
index e3a25e1a8..d6e317136 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -61,6 +61,11 @@ gr_hier_block2::self()
return shared_from_this();
}
+gr_hier_block2_sptr
+gr_hier_block2::to_hier_block2()
+{
+ return cast_to_hier_block2_sptr(shared_from_this());
+}
void
gr_hier_block2::connect(gr_basic_block_sptr block)
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
index f50b1cb94..0a40c36b7 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.h
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
@@ -147,6 +147,8 @@ public:
// This is a public method for ease of code organization, but should be
// ignored by the user.
gr_flat_flowgraph_sptr flatten() const;
+
+ gr_hier_block2_sptr to_hier_block2(); // Needed for Python/Guile type coercion
};
inline gr_hier_block2_sptr cast_to_hier_block2_sptr(gr_basic_block_sptr block) {
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
index a62f50e84..32b656e24 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.i
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
@@ -34,6 +34,11 @@ gr_hier_block2_sptr gr_make_hier_block2(const std::string name,
gr_io_signature_sptr output_signature)
throw (std::runtime_error);
+// Rename connect and disconnect so that we can more easily build a
+// better interface in scripting land.
+%rename(primitive_connect) gr_hier_block2::connect;
+%rename(primitive_disconnect) gr_hier_block2::disconnect;
+
class gr_hier_block2 : public gr_basic_block
{
private:
@@ -57,4 +62,6 @@ public:
void disconnect_all();
void lock();
void unlock();
+
+ gr_hier_block2_sptr to_hier_block2(); // Needed for Python/Guile type coercion
};
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.i b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
index 9ca92b6ec..c9214bef3 100644
--- a/gnuradio-core/src/lib/runtime/gr_msg_queue.i
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005,2009 Free Software Foundation, Inc.
+ * Copyright 2005,2009,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -81,6 +81,7 @@ public:
* functions into the gr.msg_queue wrapper class, so that everything
* appears normal. (An evil laugh is heard in the distance...)
*/
+#ifdef SWIGPYTHON
%inline %{
gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) {
gr_message_sptr msg;
@@ -103,3 +104,65 @@ gr_msg_queue_sptr.delete_head = gr_py_msg_queue__delete_head
gr_msg_queue_sptr.insert_tail = gr_py_msg_queue__insert_tail
gr_msg_queue_sptr.handle = gr_py_msg_queue__insert_tail
%}
+#endif // SWIGPYTHON
+
+/*
+ * Similar trickery as above, only this time for Guile
+ */
+#ifdef SWIGGUILE
+
+%{
+ struct arg_holder {
+ gr_msg_queue_sptr q;
+ gr_message_sptr msg;
+ };
+
+ static void *
+ insert_tail_shim(void *arg)
+ {
+ arg_holder *a = (arg_holder *)arg;
+ a->q->insert_tail(a->msg);
+ return 0;
+ }
+
+ static void *
+ delete_head_shim(void *arg)
+ {
+ arg_holder *a = (arg_holder *)arg;
+ a->msg = a->q->delete_head();
+ return 0;
+ }
+%}
+
+%inline %{
+
+ // handle and insert_tail are equivalent
+ static void
+ handle(gr_msg_queue_sptr q, gr_message_sptr msg)
+ {
+ arg_holder a;
+ a.q = q;
+ a.msg = msg;
+ scm_without_guile(insert_tail_shim, (void *) &a);
+ }
+
+ static void
+ insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg)
+ {
+ arg_holder a;
+ a.q = q;
+ a.msg = msg;
+ scm_without_guile(insert_tail_shim, (void *) &a);
+ }
+
+ static gr_message_sptr
+ delete_head(gr_msg_queue_sptr q)
+ {
+ arg_holder a;
+ a.q = q;
+ scm_without_guile(delete_head_shim, (void *) &a);
+ return a.msg;
+ }
+%}
+
+#endif // SWIGGUILE
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
index 5e9032449..2378a1880 100644
--- a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
@@ -42,6 +42,7 @@ class gr_single_threaded_scheduler {
gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
};
+#ifdef SWIGPYTHON
%inline %{
void sts_pyrun (gr_single_threaded_scheduler_sptr s) {
Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
@@ -49,3 +50,5 @@ class gr_single_threaded_scheduler {
Py_END_ALLOW_THREADS; // acquire global interpreter lock
}
%}
+#endif
+
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc
index 09e46dfbb..f341525c0 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc
@@ -95,3 +95,9 @@ gr_top_block::dump()
{
d_impl->dump();
}
+
+gr_top_block_sptr
+gr_top_block::to_top_block()
+{
+ return cast_to_top_block_sptr(shared_from_this());
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.h b/gnuradio-core/src/lib/runtime/gr_top_block.h
index 8052954e3..ed244cb7c 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.h
@@ -105,6 +105,13 @@ public:
* Displays flattened flowgraph edges and block connectivity
*/
void dump();
+
+ gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion
};
+inline gr_top_block_sptr cast_to_top_block_sptr(gr_basic_block_sptr block) {
+ return boost::dynamic_pointer_cast<gr_top_block, gr_basic_block>(block);
+}
+
+
#endif /* INCLUDED_GR_TOP_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i
index 670e5b5e5..90fa18b94 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007,2008 Free Software Foundation, Inc.
+ * Copyright 2007,2008,2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -42,13 +42,17 @@ public:
void start() throw (std::runtime_error);
void stop();
- void wait();
- void run();
+ //void wait();
+ //void run() throw (std::runtime_error);
void lock();
void unlock() throw (std::runtime_error);
void dump();
+
+ gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion
};
+#ifdef SWIGPYTHON
+
%inline %{
void top_block_run_unlocked(gr_top_block_sptr r) throw (std::runtime_error)
{
@@ -64,3 +68,36 @@ void top_block_wait_unlocked(gr_top_block_sptr r) throw (std::runtime_error)
Py_END_ALLOW_THREADS; // acquire global interpreter lock
}
%}
+
+#endif
+
+#ifdef SWIGGUILE
+
+%{
+ struct tb_arg_holder {
+ gr_top_block_sptr tb;
+ };
+
+ static void *
+ tb_wait_shim(void *arg)
+ {
+ tb_arg_holder *a = (tb_arg_holder *)arg;
+ a->tb->wait();
+ return 0;
+ }
+
+%}
+
+%inline %{
+
+ static void
+ top_block_wait_unlocked(gr_top_block_sptr r) throw (std::runtime_error)
+ {
+ tb_arg_holder a;
+ a.tb = r;
+ scm_without_guile(tb_wait_shim, (void *) &a);
+ }
+
+%}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
index 03eef17d9..faa888697 100644
--- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
+++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -43,7 +43,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
// handle any queued up messages
while ((msg = d->d_tpb.delete_head_nowait()))
- block->handle_msg(msg);
+ block->dispatch_msg(msg);
d->d_tpb.clear_changed();
s = d_exec.run_one_iteration();
@@ -73,7 +73,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
// handle all pending messages
while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
guard.unlock(); // release lock while processing msg
- block->handle_msg(msg);
+ block->dispatch_msg(msg);
guard.lock();
}
}
@@ -93,7 +93,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block)
// handle all pending messages
while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){
guard.unlock(); // release lock while processing msg
- block->handle_msg(msg);
+ block->dispatch_msg(msg);
guard.lock();
}
}
diff --git a/gnuradio-core/src/lib/runtime/gr_unittests.h b/gnuradio-core/src/lib/runtime/gr_unittests.h
index 680e59ca4..70aa6f294 100644
--- a/gnuradio-core/src/lib/runtime/gr_unittests.h
+++ b/gnuradio-core/src/lib/runtime/gr_unittests.h
@@ -45,14 +45,13 @@
*/
static void
-ensure_unittest_path (const char *grpath, const char *path)
+ensure_unittest_path (const char *path)
{
struct stat statbuf;
if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
return;
// blindly try to make it // FIXME make this robust. C++ SUCKS!
- gr_mkdir (grpath, 0750);
gr_mkdir (path, 0750);
}
@@ -60,11 +59,9 @@ static void
get_unittest_path (const char *filename, char *fullpath, size_t pathsize)
{
char path[200];
- char grpath[200];
- snprintf (grpath, sizeof(grpath), "%s/.gnuradio", getenv ("HOME"));
- snprintf (path, sizeof(path), "%s/unittests", grpath);
+ snprintf (path, sizeof(path), "./.unittests");
snprintf (fullpath, pathsize, "%s/%s", path, filename);
- ensure_unittest_path(grpath, path);
+ ensure_unittest_path(path);
}
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
index 967d4bfa8..c0bee8ea0 100644
--- a/gnuradio-core/src/lib/runtime/qa_runtime.cc
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2002,2007 Free Software Foundation, Inc.
+ * Copyright 2002,2007,2011 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -39,6 +39,7 @@
#include <qa_gr_hier_block2_derived.h>
#include <qa_gr_buffer.h>
#include <qa_block_tags.h>
+#include <qa_set_msg_handler.h>
CppUnit::TestSuite *
qa_runtime::suite ()
@@ -54,6 +55,7 @@ qa_runtime::suite ()
s->addTest (qa_gr_hier_block2_derived::suite ());
s->addTest (qa_gr_buffer::suite ());
s->addTest (qa_block_tags::suite ());
+ s->addTest (qa_set_msg_handler::suite ());
return s;
}
diff --git a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc
new file mode 100644
index 000000000..d52ca78b9
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_set_msg_handler.h>
+#include <gr_top_block.h>
+#include <gr_head.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <gr_nop.h>
+#include <gruel/msg_passing.h>
+#include <iostream>
+#include <boost/thread/thread.hpp>
+
+
+#define VERBOSE 0
+
+using namespace pmt;
+
+/*
+ * The gr_nop block has been instrumented so that it counts
+ * the number of messages sent to it. We use this feature
+ * to confirm that gr_nop's call to set_msg_handler is working
+ * correctly.
+ */
+
+void qa_set_msg_handler::t0()
+{
+ static const int NMSGS = 10;
+
+ if (VERBOSE) std::cout << "qa_set_msg_handler::t0()\n";
+
+ gr_top_block_sptr tb = gr_make_top_block("top");
+
+ gr_block_sptr src = gr_make_null_source(sizeof(int));
+ gr_nop_sptr nop = gr_make_nop(sizeof(int));
+ gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+ tb->connect(src, 0, nop, 0);
+ tb->connect(nop, 0, dst, 0);
+
+ // Must start graph before sending messages
+ tb->start();
+
+ // Send them...
+ for (int i = 0; i < NMSGS; i++){
+ send(nop, mp(mp("example-msg"), mp(i)));
+ }
+
+ // And send a message to null_source to confirm that the default
+ // message handling action (which should be a nop) doesn't dump
+ // core.
+ send(src, mp(mp("example-msg"), mp(0)));
+
+ // Surrender our CPU for a bit
+ boost::this_thread::yield();
+
+ tb->stop();
+ tb->wait();
+
+ // Confirm that the nop block received the right number of messages.
+ CPPUNIT_ASSERT_EQUAL(NMSGS, nop->nmsgs_received());
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h
new file mode 100644
index 000000000..e73fffbcd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_SET_MSG_HANDLER_H
+#define INCLUDED_QA_SET_MSG_HANDLER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_set_msg_handler : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_set_msg_handler);
+
+ CPPUNIT_TEST(t0);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ void t0();
+};
+
+#endif /* INCLUDED_QA_SET_MSG_HANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
index 20cf68a03..ca89b8fbd 100644
--- a/gnuradio-core/src/lib/runtime/runtime.i
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -40,6 +40,13 @@
#include <gr_top_block.h>
%}
+%constant int sizeof_char = sizeof(char);
+%constant int sizeof_short = sizeof(short);
+%constant int sizeof_int = sizeof(int);
+%constant int sizeof_float = sizeof(float);
+%constant int sizeof_double = sizeof(double);
+%constant int sizeof_gr_complex = sizeof(gr_complex);
+
%include <gr_io_signature.i>
%include <gr_buffer.i>
%include <gr_basic_block.i>