I'm running out the door and don't really have time to finish this patch.
But this is along the lines of what I'm really looking for.
thanks,
BMS
Index: libxipc/xrl_router.hh
===================================================================
--- libxipc/xrl_router.hh (revision 11686)
+++ libxipc/xrl_router.hh (working copy)
@@ -34,7 +34,10 @@
#include "finder_constants.hh"
#include "finder_client_observer.hh"
+#include <boost/shared_ptr.hpp>
+using boost::shared_ptr;
+
class DispatchState;
class FinderClient;
@@ -190,6 +193,7 @@
/**
* Send callback (fast path).
+ * FIXME: use smart ptr.
*/
void send_callback(const XrlError& e,
XrlArgs* reply,
@@ -211,6 +215,7 @@
uint16_t finder_port);
private:
+ // XXX
XrlPFSender& get_sender(const string& target);
XrlPFSender* get_sender(const Xrl& xrl, FinderDBEntry *dbe);
@@ -224,10 +229,12 @@
list<XrlPFListener*> _listeners; // listeners
list<XrlRouterDispatchState*> _dsl; // dispatch
state
- list<XrlPFSender*> _senders; // active senders
+ list< shared_ptr<XrlPFSender> > _senders; // active senders
static uint32_t _icnt; // instance count
+ // XXX the following are mostly only used by the incomplete
+ // batch support. Stick to using unchecked pointers for now --bms
private:
typedef map<string, XI*> XIM;
typedef map<string, XrlPFSender*> SENDERS;
Index: libxipc/xrl_pf_stcp.cc
===================================================================
--- libxipc/xrl_pf_stcp.cc (revision 11686)
+++ libxipc/xrl_pf_stcp.cc (working copy)
@@ -1083,12 +1083,17 @@
void
XrlPFSTCPSender::batch_start()
{
+#if 0
_batching = true;
+#else
+ XLOG_UNREACHABLE();
+#endif
}
void
XrlPFSTCPSender::batch_stop()
{
+#if 0
_batching = false;
// If we aint got no requests, we may not be able to signal to the receiver
@@ -1100,4 +1105,7 @@
if (_writer->running() == false)
_writer->start();
+#else
+ XLOG_UNREACHABLE();
+#endif
}
Index: libxipc/xrl_pf_factory.hh
===================================================================
--- libxipc/xrl_pf_factory.hh (revision 11686)
+++ libxipc/xrl_pf_factory.hh (working copy)
@@ -27,19 +27,20 @@
#include "xrl_error.hh"
#include "xrl_pf.hh"
+#include <boost/shared_ptr.hpp>
+
+using boost::shared_ptr;
+
class XrlPFSenderFactory {
public:
static void startup();
static void shutdown();
- static XrlPFSender* create_sender(EventLoop& eventloop,
- const char* proto_colon_addr);
+ static shared_ptr<XrlPFSender> create_sender(
+ EventLoop& eventloop, const char* proto_colon_addr);
- static XrlPFSender* create_sender(EventLoop& e,
- const char* protocol,
- const char* address);
-
- static void destroy_sender(XrlPFSender* s);
+ static shared_ptr<XrlPFSender> create_sender(EventLoop& e,
+ const char* protocol, const char* address);
};
#endif // __LIBXIPC_XRL_PF_FACTORY_HH__
Index: libxipc/xrl.cc
===================================================================
--- libxipc/xrl.cc (revision 11686)
+++ libxipc/xrl.cc (working copy)
@@ -76,7 +76,7 @@
const XrlArgs& args)
: _protocol(protocol), _target(protocol_target), _command(command),
_args(args), _sna_atom(NULL), _packed_bytes(0), _argp(&_args),
- _to_finder(-1), _resolved(false), _resolved_sender(NULL)
+ _to_finder(-1), _resolved(false)
{
}
@@ -85,7 +85,7 @@
const XrlArgs& args)
: _protocol(_finder_protocol), _target(target), _command(command),
_args(args), _sna_atom(NULL), _packed_bytes(0), _argp(&_args),
- _to_finder(-1), _resolved(false), _resolved_sender(NULL)
+ _to_finder(-1), _resolved(false)
{
}
@@ -94,7 +94,7 @@
const string& command)
: _protocol(protocol), _target(protocol_target), _command(command),
_sna_atom(NULL), _packed_bytes(0), _argp(&_args), _to_finder(-1),
- _resolved(false), _resolved_sender(NULL)
+ _resolved(false)
{
}
@@ -102,7 +102,7 @@
const string& command)
: _protocol(_finder_protocol), _target(target), _command(command),
_sna_atom(NULL), _packed_bytes(0), _argp(&_args), _to_finder(-1),
- _resolved(false), _resolved_sender(NULL)
+ _resolved(false)
{
}
@@ -110,13 +110,13 @@
const char* command)
: _protocol(_finder_protocol), _target(target), _command(command),
_sna_atom(NULL), _packed_bytes(0), _argp(&_args), _to_finder(-1),
- _resolved(false), _resolved_sender(NULL)
+ _resolved(false)
{
}
Xrl::Xrl(const char* c_str) throw (InvalidString)
: _sna_atom(NULL), _packed_bytes(0), _argp(&_args),
- _to_finder(-1), _resolved(false), _resolved_sender(NULL)
+ _to_finder(-1), _resolved(false)
{
if (0 == c_str)
xorp_throw0(InvalidString);
@@ -136,7 +136,7 @@
Xrl::Xrl()
: _sna_atom(0), _packed_bytes(0), _argp(&_args), _to_finder(-1),
- _resolved(false), _resolved_sender(NULL)
+ _resolved(false)
{
}
@@ -335,8 +335,9 @@
_packed_bytes = 0;
_to_finder = -1;
_resolved = false;
- _resolved_sender = NULL;
+ _resolved_sender.reset();
+
delete _sna_atom;
_sna_atom = NULL;
}
Index: libxipc/xrl_pf.cc
===================================================================
--- libxipc/xrl_pf.cc (revision 11686)
+++ libxipc/xrl_pf.cc (working copy)
@@ -55,4 +55,5 @@
XrlPFSender::~XrlPFSender()
{
+ // XXX put a debug_msg() here; we are now deleted through shared_ptr.
}
Index: libxipc/xrl.hh
===================================================================
--- libxipc/xrl.hh (revision 11686)
+++ libxipc/xrl.hh (working copy)
@@ -26,11 +26,15 @@
#include <string>
+#include <boost/weak_ptr.hpp>
+
#include "libxorp/exceptions.hh"
#include "xrl_atom.hh"
#include "xrl_args.hh"
#include "xrl_tokens.hh"
+using boost::weak_ptr;
+
class XrlPFSender;
/**
@@ -169,9 +173,15 @@
bool resolved() const { return _resolved; }
void set_resolved(bool r) const { _resolved = r; }
- XrlPFSender *resolved_sender() const { return _resolved_sender; }
- void set_resolved_sender(XrlPFSender *s) const { _resolved_sender = s; }
+ // XXX Don't declare these two const until shared_ptr is worked out --bms
+ weak_ptr<XrlPFSender> resolved_sender() {
+ return _resolved_sender;
+ }
+ void set_resolved_sender(weak_ptr<XrlPFSender> s) {
+ _resolved_sender = s;
+ }
+
void set_target(const char* target);
private:
@@ -194,7 +204,7 @@
mutable XrlArgs* _argp; // XXX shouldn't be mutable
mutable int _to_finder;
mutable bool _resolved; // XXX ditto
- mutable XrlPFSender* _resolved_sender; // XXX ditto
+ mutable weak_ptr<XrlPFSender> _resolved_sender; // XXX ditto
static const string _finder_protocol;
};
Index: libxipc/xrl_pf.hh
===================================================================
--- libxipc/xrl_pf.hh (revision 11686)
+++ libxipc/xrl_pf.hh (working copy)
@@ -105,7 +105,15 @@
virtual bool sends_pending() const = 0;
virtual const char* protocol() const = 0;
+
+ /**
+ * Determine if the underlying transport is still open.
+ *
+ * @return true if the transport is alive.
+ */
virtual bool alive() const = 0;
+
+ // XXX Unfinished support for XRL batching.
virtual void batch_start() {}
virtual void batch_stop() {}
Index: libxipc/xrl_router.cc
===================================================================
--- libxipc/xrl_router.cc (revision 11686)
+++ libxipc/xrl_router.cc (working copy)
@@ -38,6 +38,10 @@
#include "sockutil.hh"
+// XXX should be included nested above.
+//#include <boost/shared_ptr.hpp>
+//#include <boost/weak_ptr.hpp>
+
//
// Enable this macro to enable Xrl callback checker that checks each Xrl
// callback is dispatched just once.
@@ -273,10 +277,8 @@
_fc->detach_observer(this);
_fac->set_enabled(false);
- while (_senders.empty() == false) {
- XrlPFSenderFactory::destroy_sender(_senders.front());
+ while (_senders.empty() == false)
_senders.pop_front();
- }
while (_dsl.empty() == false) {
delete _dsl.front();
@@ -389,7 +391,8 @@
bool direct_call)
{
try {
- XrlPFSender* s = get_sender(xrl, const_cast<FinderDBEntry*>(dbe));
+ shared_ptr<XrlPFSender> s =
+ get_sender(xrl, const_cast<FinderDBEntry*>(dbe));
if (s == 0) {
// Notify Finder client that result was bad.
_fc->uncache_result(dbe);
@@ -400,10 +403,11 @@
const Xrl& x = dbe->xrls().front();
x.set_args(xrl);
- if (s) {
+ if (s != 0) {
trace_xrl("Sending ", x);
return s->send(x, direct_call,
- callback(this, &XrlRouter::send_callback, s, cb));
+ callback(this, &XrlRouter::send_callback,
+ s.get(), cb));
}
cb->dispatch(XrlError(SEND_FAILED, "sender not instantiated"), 0);
} catch (const InvalidString&) {
@@ -412,24 +416,37 @@
return false;
}
-XrlPFSender*
+// Return 0 or locked shared_ptr.
+
+shared_ptr<XrlPFSender>
XrlRouter::get_sender(const Xrl& xrl, FinderDBEntry* dbe)
{
const Xrl& x = dbe->xrls().front();
- XrlPFSender* s = NULL;
+ shared_ptr<XrlPFSender> s;
- // Use the cache pointer to the sender.
+ // Try to use the cached pointer to the sender.
if (xrl.resolved()) {
- s = xrl.resolved_sender();
+ weak_ptr<XrlPFSender> w = xrl.resolved_sender();
- if (s->alive())
+ // Check if cached weak_ptr to sender is still valid; we may
+ // have lost a race on the XRLDB.
+ // Check if transport layer is still up for this sender.
+ // If good to go, return shared pointer for which we
+ // still hold the lock.
+ s = w.lock();
+ if (s != 0 && s->alive())
return s;
+ // We lost the race.
+
+ // XXX Sanity check that this sender's protocol and endpoint
+ // addresses are the same as they were when the Xrl was
+ // instantiated.
XLOG_ASSERT(s->protocol() == x.protocol());
XLOG_ASSERT(s->address() == x.target());
xrl.set_resolved(false);
- xrl.set_resolved_sender(NULL);
+ xrl.set_resolved_sender(0);
}
// Find a new sender.
@@ -448,13 +465,13 @@
XLOG_INFO("Sender died (protocol = \"%s\", address = \"%s\")",
s->protocol(), s->address().c_str());
- XrlPFSenderFactory::destroy_sender(s);
+
_senders.erase(i);
_senders2.erase(xrl.target());
break;
}
- s = NULL;
+ s.reset();
// create sender
while (dbe->xrls().size()) {
@@ -462,7 +479,7 @@
s = XrlPFSenderFactory::create_sender(_e, x.protocol().c_str(),
x.target().c_str());
- if (s)
+ if (s != 0)
break;
XLOG_ERROR("Could not create XrlPFSender for protocol = \"%s\" "
@@ -471,15 +488,18 @@
dbe->pop_front();
}
- if (!s)
- return NULL;
+ // Unable to instantiate.
+ if (s == 0)
+ return 0;
+
+ // New sender instantiated, take lock and record state.
const Xrl& front = dbe->xrls().front();
XLOG_ASSERT(s->protocol() == front.protocol());
XLOG_ASSERT(s->address() == front.target());
_senders.push_back(s);
- _senders2[xrl.target()] = s;
+ _senders2[xrl.target()] = s.get();
// Don't do this here as it is set in the Xrl that is stored with
// the finder client, so is not used. But if the connection needs
@@ -506,7 +526,7 @@
if (e == XrlError::OKAY()) {
const Xrl& xrl = ds->xrl();
xrl.set_resolved(false);
- xrl.set_resolved_sender(NULL);
+ xrl.set_resolved_sender(0);
if (send_resolved(xrl, dbe, ds->cb(), false) == false) {
// We tried to force sender to send xrl and it declined the
// opportunity. This should only happen when it's out of buffer
@@ -710,25 +730,44 @@
debug_msg("Finder target ready event: \"%s\"\n", tgt_name.c_str());
}
+//
+// XXX This is unfinished code related to a batch XRL implementation.
+// It is unfortunately incompatible, straight off, with using refcounts to
+// manage XrlPFSender's lifecycle, so it needs to be revisited later by
+// an interested party.
+// Also, the overloading of the get_sender() method name is potentially
+// confusing. --bms
+
void
XrlRouter::batch_start(const string& target)
{
+#if 0
XrlPFSender& sender = get_sender(target);
sender.batch_start();
+#else
+ XLOG_UNREACHABLE();
+ UNUSED(target);
+#endif
}
void
XrlRouter::batch_stop(const string& target)
{
+#if 0
XrlPFSender& sender = get_sender(target);
sender.batch_stop();
+#else
+ XLOG_UNREACHABLE();
+ UNUSED(target);
+#endif
}
XrlPFSender&
XrlRouter::get_sender(const string& target)
{
+#if 0
XrlPFSender* s = 0;
SENDERS::iterator i = _senders2.find(target);
@@ -737,6 +776,12 @@
s = i->second;
return *s;
+#else
+ XLOG_UNREACHABLE();
+ XrlPFSender* s = 0;
+ return *s;
+ UNUSED(target);
+#endif
}
Index: libxipc/xrl_pf_factory.cc
===================================================================
--- libxipc/xrl_pf_factory.cc (revision 11686)
+++ libxipc/xrl_pf_factory.cc (working copy)
@@ -38,7 +38,7 @@
// real cost, unlike InProc and SUDP, so we maintain a cache of
// STCP senders with one per sender destination address.
-XrlPFSender*
+shared_ptr<XrlPFSender>
XrlPFSenderFactory::create_sender(EventLoop& eventloop,
const char* protocol,
const char* address)
@@ -58,7 +58,7 @@
return 0;
}
-XrlPFSender*
+shared_ptr<XrlPFSender>
XrlPFSenderFactory::create_sender(EventLoop& eventloop,
const char* protocol_colon_address)
{
@@ -74,15 +74,6 @@
}
void
-XrlPFSenderFactory::destroy_sender(XrlPFSender* s)
-{
- debug_msg("destroying sender pf = \"%s\", addr = \"%s\"\n",
- s->protocol(), s->address().c_str());
-
- delete s;
-}
-
-void
XrlPFSenderFactory::startup()
{
}
_______________________________________________
Xorp-hackers mailing list
[email protected]
http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers