2015-08-13 13:12:15 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Copyright (c) FIRST 2015. All Rights Reserved. */
|
|
|
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
|
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
|
|
|
/* the project. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#ifndef NT_RPCSERVER_H_
|
|
|
|
|
#define NT_RPCSERVER_H_
|
|
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
|
#include <condition_variable>
|
|
|
|
|
#include <mutex>
|
|
|
|
|
#include <queue>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
#include "llvm/DenseMap.h"
|
2016-07-27 00:39:38 -07:00
|
|
|
#include "support/atomic_static.h"
|
|
|
|
|
#include "support/SafeThread.h"
|
2015-08-13 13:12:15 -07:00
|
|
|
#include "Message.h"
|
|
|
|
|
#include "ntcore_cpp.h"
|
|
|
|
|
|
|
|
|
|
namespace nt {
|
|
|
|
|
|
|
|
|
|
class RpcServer {
|
|
|
|
|
friend class RpcServerTest;
|
2016-11-03 21:03:45 -07:00
|
|
|
|
2015-08-13 13:12:15 -07:00
|
|
|
public:
|
|
|
|
|
static RpcServer& GetInstance() {
|
|
|
|
|
ATOMIC_STATIC(RpcServer, instance);
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
~RpcServer();
|
|
|
|
|
|
|
|
|
|
typedef std::function<void(std::shared_ptr<Message>)> SendMsgFunc;
|
|
|
|
|
|
|
|
|
|
void Start();
|
|
|
|
|
void Stop();
|
|
|
|
|
|
2015-12-28 08:28:24 -08:00
|
|
|
void SetOnStart(std::function<void()> on_start) { m_on_start = on_start; }
|
|
|
|
|
void SetOnExit(std::function<void()> on_exit) { m_on_exit = on_exit; }
|
2015-08-13 13:12:15 -07:00
|
|
|
|
|
|
|
|
void ProcessRpc(StringRef name, std::shared_ptr<Message> msg,
|
|
|
|
|
RpcCallback func, unsigned int conn_id,
|
2016-11-03 21:03:45 -07:00
|
|
|
SendMsgFunc send_response, const ConnectionInfo& conn_info);
|
2015-08-13 13:12:15 -07:00
|
|
|
|
|
|
|
|
bool PollRpc(bool blocking, RpcCallInfo* call_info);
|
2016-08-15 20:24:07 -07:00
|
|
|
bool PollRpc(bool blocking, double time_out, RpcCallInfo* call_info);
|
2015-08-13 13:12:15 -07:00
|
|
|
void PostRpcResponse(unsigned int rpc_id, unsigned int call_uid,
|
|
|
|
|
llvm::StringRef result);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
RpcServer();
|
|
|
|
|
|
2015-12-28 08:28:24 -08:00
|
|
|
class Thread;
|
2016-07-27 00:39:38 -07:00
|
|
|
wpi::SafeThreadOwner<Thread> m_owner;
|
2015-08-13 13:12:15 -07:00
|
|
|
|
|
|
|
|
struct RpcCall {
|
|
|
|
|
RpcCall(StringRef name_, std::shared_ptr<Message> msg_, RpcCallback func_,
|
2016-10-03 10:04:30 -07:00
|
|
|
unsigned int conn_id_, SendMsgFunc send_response_,
|
|
|
|
|
const ConnectionInfo conn_info_)
|
2015-08-13 13:12:15 -07:00
|
|
|
: name(name_),
|
|
|
|
|
msg(msg_),
|
|
|
|
|
func(func_),
|
|
|
|
|
conn_id(conn_id_),
|
2016-10-03 10:04:30 -07:00
|
|
|
send_response(send_response_),
|
|
|
|
|
conn_info(conn_info_) {}
|
2015-08-13 13:12:15 -07:00
|
|
|
|
|
|
|
|
std::string name;
|
|
|
|
|
std::shared_ptr<Message> msg;
|
|
|
|
|
RpcCallback func;
|
|
|
|
|
unsigned int conn_id;
|
|
|
|
|
SendMsgFunc send_response;
|
2016-10-03 10:04:30 -07:00
|
|
|
ConnectionInfo conn_info;
|
2015-08-13 13:12:15 -07:00
|
|
|
};
|
|
|
|
|
|
2015-12-28 08:28:24 -08:00
|
|
|
std::mutex m_mutex;
|
|
|
|
|
|
|
|
|
|
std::queue<RpcCall> m_poll_queue;
|
2015-08-13 13:12:15 -07:00
|
|
|
llvm::DenseMap<std::pair<unsigned int, unsigned int>, SendMsgFunc>
|
|
|
|
|
m_response_map;
|
|
|
|
|
|
2015-12-28 08:28:24 -08:00
|
|
|
std::condition_variable m_poll_cond;
|
|
|
|
|
|
|
|
|
|
std::atomic_bool m_terminating;
|
|
|
|
|
|
|
|
|
|
std::function<void()> m_on_start;
|
|
|
|
|
std::function<void()> m_on_exit;
|
2015-08-13 13:12:15 -07:00
|
|
|
|
|
|
|
|
ATOMIC_STATIC_DECL(RpcServer)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace nt
|
|
|
|
|
|
|
|
|
|
#endif // NT_RPCSERVER_H_
|