00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef ROSCPP_XMLRPC_MANAGER_H
00029 #define ROSCPP_XMLRPC_MANAGER_H
00030
00031 #include <string>
00032 #include <set>
00033 #include <boost/function.hpp>
00034 #include <boost/thread/mutex.hpp>
00035 #include <boost/thread/thread.hpp>
00036 #include <boost/enable_shared_from_this.hpp>
00037
00038 #include "XmlRpc.h"
00039
00040 #include <ros/time.h>
00041
00042
00043 namespace ros
00044 {
00045
00049 namespace xmlrpc
00050 {
00051 XmlRpc::XmlRpcValue responseStr(int code, const std::string& msg, const std::string& response);
00052 XmlRpc::XmlRpcValue responseInt(int code, const std::string& msg, int response);
00053 XmlRpc::XmlRpcValue responseBool(int code, const std::string& msg, bool response);
00054 }
00055
00056 class XMLRPCCallWrapper;
00057 typedef boost::shared_ptr<XMLRPCCallWrapper> XMLRPCCallWrapperPtr;
00058
00059 class ASyncXMLRPCConnection : public boost::enable_shared_from_this<ASyncXMLRPCConnection>
00060 {
00061 public:
00062 virtual ~ASyncXMLRPCConnection() {}
00063
00064 virtual void addToDispatch(XmlRpc::XmlRpcDispatch* disp) = 0;
00065 virtual void removeFromDispatch(XmlRpc::XmlRpcDispatch* disp) = 0;
00066
00067 virtual bool check() = 0;
00068 };
00069 typedef boost::shared_ptr<ASyncXMLRPCConnection> ASyncXMLRPCConnectionPtr;
00070 typedef std::set<ASyncXMLRPCConnectionPtr> S_ASyncXMLRPCConnection;
00071
00072 class CachedXmlRpcClient
00073 {
00074 public:
00075 CachedXmlRpcClient(XmlRpc::XmlRpcClient *c)
00076 : in_use_(false)
00077 , client_(c)
00078 {
00079 }
00080
00081 bool in_use_;
00082 ros::WallTime last_use_time_;
00083 XmlRpc::XmlRpcClient* client_;
00084
00085 static const ros::WallDuration s_zombie_time_;
00086 };
00087
00088 class XMLRPCManager;
00089 typedef boost::shared_ptr<XMLRPCManager> XMLRPCManagerPtr;
00090
00091 typedef boost::function<void(XmlRpc::XmlRpcValue&, XmlRpc::XmlRpcValue&)> XMLRPCFunc;
00092
00093 class XMLRPCManager
00094 {
00095 public:
00096 static const XMLRPCManagerPtr& instance();
00097
00098 XMLRPCManager();
00099 ~XMLRPCManager();
00100
00111 bool validateXmlrpcResponse(const std::string& method, XmlRpc::XmlRpcValue &response, XmlRpc::XmlRpcValue &payload);
00112
00116 inline const std::string& getServerURI() const { return uri_; }
00117 inline uint32_t getServerPort() const { return port_; }
00118
00119 XmlRpc::XmlRpcClient* getXMLRPCClient(const std::string& host, const int port, const std::string& uri);
00120 void releaseXMLRPCClient(XmlRpc::XmlRpcClient* c);
00121
00122 void addASyncConnection(const ASyncXMLRPCConnectionPtr& conn);
00123 void removeASyncConnection(const ASyncXMLRPCConnectionPtr& conn);
00124
00125 bool bind(const std::string& function_name, const XMLRPCFunc& cb);
00126 void unbind(const std::string& function_name);
00127
00128 void start();
00129 void shutdown();
00130
00131 bool isShuttingDown() { return shutting_down_; }
00132
00133 private:
00134 void serverThreadFunc();
00135
00136 std::string uri_;
00137 int port_;
00138 boost::thread server_thread_;
00139
00140 #if defined(__APPLE__)
00141
00142 boost::mutex xmlrpc_call_mutex_;
00143 #endif
00144 XmlRpc::XmlRpcServer server_;
00145 typedef std::vector<CachedXmlRpcClient> V_CachedXmlRpcClient;
00146 V_CachedXmlRpcClient clients_;
00147 boost::mutex clients_mutex_;
00148
00149 bool shutting_down_;
00150
00151 ros::WallDuration master_retry_timeout_;
00152
00153 S_ASyncXMLRPCConnection added_connections_;
00154 boost::mutex added_connections_mutex_;
00155 S_ASyncXMLRPCConnection removed_connections_;
00156 boost::mutex removed_connections_mutex_;
00157
00158 S_ASyncXMLRPCConnection connections_;
00159
00160
00161 struct FunctionInfo
00162 {
00163 std::string name;
00164 XMLRPCFunc function;
00165 XMLRPCCallWrapperPtr wrapper;
00166 };
00167 typedef std::map<std::string, FunctionInfo> M_StringToFuncInfo;
00168 boost::mutex functions_mutex_;
00169 M_StringToFuncInfo functions_;
00170
00171 volatile bool unbind_requested_;
00172 };
00173
00174 }
00175
00176 #endif