summaryrefslogtreecommitdiff
path: root/gnuradio-core
diff options
context:
space:
mode:
authorEric Blossom2011-01-06 21:39:10 -0800
committerEric Blossom2011-01-06 21:39:10 -0800
commitb6005d9e5823d871c091f3b4a048ca67cd885821 (patch)
treefbda33459df200f159cafe8dd44d428b5566e7ca /gnuradio-core
parent2073fa2c09aab3c6ec20f7e75f210cacf243fa44 (diff)
downloadgnuradio-b6005d9e5823d871c091f3b4a048ca67cd885821.tar.gz
gnuradio-b6005d9e5823d871c091f3b4a048ca67cd885821.tar.bz2
gnuradio-b6005d9e5823d871c091f3b4a048ca67cd885821.zip
Change pmt message handling interface in gr_basic_block.h
Change the API such that the message handler is now implemented with a callback, not an overridden virtual function. The callback is now set using gr_basic_block::set_msg_handler, which will accept pretty much any kind of callable. This change allows us to split the machinery for message handling out from the block inheritance hierarchy, and provides a foundation that can be used to build or experiment with arbitrary message dispatching techniques.
Diffstat (limited to 'gnuradio-core')
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h54
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc8
2 files changed, 50 insertions, 12 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
index d059a4bd3..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 };
@@ -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_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();
}
}