Merged r7478:7608 from michaelld/t186 into trunk. Adds ability to compile GNU Radio...
[debian/gnuradio] / mblock / src / lib / mb_port_simple.cc
index 1315b617223c5f21b1e7b91183a0b88c12ee87b3..24a01b562899e7b60b83e7b82007b5fff5e4330f 100644 (file)
@@ -6,7 +6,7 @@
  * 
  * 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 2, or (at your option)
+ * 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,
@@ -29,6 +29,7 @@
 #include <mb_mblock.h>
 #include <mb_mblock_impl.h>
 #include <assert.h>
+#include <mbi_runtime_lock.h>
 
 
 mb_port_simple::mb_port_simple(mb_mblock *mblock,
@@ -36,7 +37,8 @@ mb_port_simple::mb_port_simple(mb_mblock *mblock,
                               const std::string &protocol_class_name,
                               bool conjugated,
                               mb_port::port_type_t port_type)
-  : mb_port(mblock, port_name, protocol_class_name, conjugated, port_type)
+  : mb_port(mblock, port_name, protocol_class_name, conjugated, port_type),
+    d_cache_valid(false)
 {
 }
 
@@ -49,7 +51,7 @@ void
 mb_port_simple::send(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority)
 {
   if (port_type() == mb_port::RELAY)  // Can't send directly to a RELAY port
-    throw mbe_invalid_port_type(mblock(), mblock()->fullname(), port_name());
+    throw mbe_invalid_port_type(mblock(), mblock()->instance_name(), port_name());
 
   mb_msg_accepter_sptr  accepter = find_accepter(this);
   if (accepter)
@@ -66,6 +68,11 @@ mb_port_simple::find_accepter(mb_port_simple *start)
   mb_endpoint          peer_ep;
   mb_msg_accepter_sptr r;
 
+  if (start->d_cache_valid)
+    return start->d_cached_accepter;
+
+  mbi_runtime_lock     l(p->mblock());
+
   // Set up initial context.
 
   switch(p->port_type()){
@@ -75,6 +82,8 @@ mb_port_simple::find_accepter(mb_port_simple *start)
 
   case mb_port::EXTERNAL:      // binding is in parent's name space
     context = p->mblock()->parent();
+    if (!context)                      // can't be bound if there's no parent
+      return mb_msg_accepter_sptr();   // not bound
     break;
 
   default:
@@ -94,7 +103,11 @@ mb_port_simple::find_accepter(mb_port_simple *start)
   case mb_port::INTERNAL:      // Terminate here.
   case mb_port::EXTERNAL:
     r = pp->make_accepter();
-    // FIXME cache the result
+
+    // cache the result
+
+    start->d_cached_accepter = r;
+    start->d_cache_valid = true;
     return r;
 
   case mb_port::RELAY:         // Traverse to other side of relay port.
@@ -127,5 +140,12 @@ mb_port_simple::find_accepter(mb_port_simple *start)
 mb_msg_accepter_sptr
 mb_port_simple::make_accepter()
 {
-  return d_mblock->impl()->make_accepter(port_name());
+  return d_mblock->impl()->make_accepter(port_symbol());
+}
+
+void
+mb_port_simple::invalidate_cache()
+{
+  d_cache_valid = false;
+  d_cached_accepter.reset();
 }