// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- // Copyright (c) 2001-2009 XORP, Inc. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License, Version // 2.1, June 1999 as published by the Free Software Foundation. // Redistribution and/or modification of this program under the terms of // any other version of the GNU Lesser General Public License is not // permitted. // // This program 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. For more details, // see the GNU Lesser General Public License, Version 2.1, a copy of // which can be found in the XORP LICENSE.lgpl file. // // XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; // http://xorp.net // $XORP: xorp/libxipc/finder_xrl_queue.hh,v 1.18 2009/01/05 18:30:56 jtc Exp $ #ifndef __LIBXIPC_FINDER_XRL_QUEUE_HH__ #define __LIBXIPC_FINDER_XRL_QUEUE_HH__ #include <list> #include "libxorp/ref_ptr.hh" class FinderXrlCommandBase; /** * @short Xrl Queue for Finder. * * The FinderXrlCommandQueue holds and dispatches Xrls for the Finder. * Commands are added with the @ref FinderXrlCommandQueue::enqueue * method and are serially dispatched without any additional * intervention. During the completion of each Xrl in the queue triggers * the sending of the next Xrl. */ class FinderXrlCommandQueue { public: typedef ref_ptr<FinderXrlCommandBase> Command; public: FinderXrlCommandQueue(FinderMessengerBase* messenger); FinderXrlCommandQueue(const FinderXrlCommandQueue& oq); ~FinderXrlCommandQueue(); FinderMessengerBase& messenger() { return *_m; } void enqueue(const Command& cmd); protected: void push(); void dispatch_one(); EventLoop& eventloop(); protected: friend class FinderXrlCommandBase; void crank(); void kill_messenger(); private: FinderXrlCommandQueue& operator=(const FinderXrlCommandQueue&); // no impl private: FinderMessengerBase* _m; list<Command> _cmds; bool _pending; XorpTimer _dispatcher; }; /** * @short Base class for Xrls sent from Finder. */ class FinderXrlCommandBase { public: FinderXrlCommandBase(FinderXrlCommandQueue& q) : _queue(q) {} virtual ~FinderXrlCommandBase() {} FinderXrlCommandQueue& queue() { return _queue; } FinderMessengerBase& messenger() { return _queue.messenger(); } virtual bool dispatch() = 0; void dispatch_cb(const XrlError& e) { if (e != XrlCmdError::OKAY()) { XLOG_ERROR("Sent xrl got response %s\n", e.str().c_str()); queue().kill_messenger(); return ; } queue().crank(); } protected: FinderXrlCommandQueue& _queue; }; #include "xrl/interfaces/finder_client_xif.hh" /** * @short Send "hello" Xrl to Client. */ class FinderSendHelloToClient : public FinderXrlCommandBase { public: FinderSendHelloToClient(FinderXrlCommandQueue& q, const string& tgtname) : FinderXrlCommandBase(q), _tgtname(tgtname) { } bool dispatch() { XrlFinderClientV0p2Client client(&(queue().messenger())); return client.send_hello(_tgtname.c_str(), callback(static_cast<FinderXrlCommandBase*>(this), &FinderXrlCommandBase::dispatch_cb)); } protected: string _tgtname; }; /** * @short Send "remove xrl" to client. */ class FinderSendRemoveXrl : public FinderXrlCommandBase { public: FinderSendRemoveXrl(FinderXrlCommandQueue& q, const string& tgtname, const string& xrl) : FinderXrlCommandBase(q), _tgtname(tgtname), _xrl(xrl) { } ~FinderSendRemoveXrl() { _tgtname = _xrl = "croak"; } bool dispatch() { XrlFinderClientV0p2Client client(&(queue().messenger())); return client.send_remove_xrl_from_cache(_tgtname.c_str(), _xrl, callback(static_cast<FinderXrlCommandBase*>(this), &FinderXrlCommandBase::dispatch_cb)); } protected: string _tgtname; string _xrl; }; /** * @short Send "remove xrls for target" to client. */ class FinderSendRemoveXrls : public FinderXrlCommandBase { public: FinderSendRemoveXrls(FinderXrlCommandQueue& q, const string& tgtname) : FinderXrlCommandBase(q), _tgtname(tgtname) { } ~FinderSendRemoveXrls() { _tgtname = "croak"; } bool dispatch() { XrlFinderClientV0p2Client client(&(queue().messenger())); return client.send_remove_xrls_for_target_from_cache( _tgtname.c_str(), _tgtname, callback(static_cast<FinderXrlCommandBase*>(this), &FinderXrlCommandBase::dispatch_cb)); } protected: string _tgtname; }; /** * @short Send tunneled Xrl to client. Client is expected to be * able to dispatch Xrl. */ class FinderSendTunneledXrl : public FinderXrlCommandBase { public: FinderSendTunneledXrl(FinderXrlCommandQueue& q, const string& tgtname, const string& xrl) : FinderXrlCommandBase(q), _tgtname(tgtname), _xrl(xrl) { } ~FinderSendTunneledXrl() { _tgtname = "croak"; } void dispatch_cb(const XrlError& e, const uint32_t* /* p_errno */, const string* /* p_errtxt */) { // if (e != XrlError::OKAY()) FinderXrlCommandBase::dispatch_cb(e); // TODO: XXX } bool dispatch() { XrlFinderClientV0p2Client client(&(queue().messenger())); return client.send_dispatch_tunneled_xrl(_tgtname.c_str(), _xrl, callback(this, &FinderSendTunneledXrl::dispatch_cb)); } protected: string _tgtname; string _xrl; }; #endif // __LIBXIPC_FINDER_XRL_QUEUE_HH__