Squashed 'third_party/ntcore_2016/' content from commit d8de5e4
Change-Id: Id4839f41b6a620d8bae58dcf1710016671cc4992
git-subtree-dir: third_party/ntcore_2016
git-subtree-split: d8de5e4f19e612e7102172c0dbf152ce82d3d63a
diff --git a/src/RpcServer.h b/src/RpcServer.h
new file mode 100644
index 0000000..726034d
--- /dev/null
+++ b/src/RpcServer.h
@@ -0,0 +1,91 @@
+/*----------------------------------------------------------------------------*/
+/* 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 <thread>
+#include <utility>
+#include <vector>
+
+#include "llvm/DenseMap.h"
+#include "atomic_static.h"
+#include "Message.h"
+#include "ntcore_cpp.h"
+
+namespace nt {
+
+class RpcServer {
+ friend class RpcServerTest;
+ public:
+ static RpcServer& GetInstance() {
+ ATOMIC_STATIC(RpcServer, instance);
+ return instance;
+ }
+ ~RpcServer();
+
+ typedef std::function<void(std::shared_ptr<Message>)> SendMsgFunc;
+
+ void Start();
+ void Stop();
+
+ bool active() const { return m_active; }
+
+ void ProcessRpc(StringRef name, std::shared_ptr<Message> msg,
+ RpcCallback func, unsigned int conn_id,
+ SendMsgFunc send_response);
+
+ bool PollRpc(bool blocking, RpcCallInfo* call_info);
+ void PostRpcResponse(unsigned int rpc_id, unsigned int call_uid,
+ llvm::StringRef result);
+
+ private:
+ RpcServer();
+
+ void ThreadMain();
+
+ std::atomic_bool m_active;
+ std::atomic_bool m_terminating;
+
+ std::mutex m_mutex;
+ std::condition_variable m_call_cond, m_poll_cond;
+
+ struct RpcCall {
+ RpcCall(StringRef name_, std::shared_ptr<Message> msg_, RpcCallback func_,
+ unsigned int conn_id_, SendMsgFunc send_response_)
+ : name(name_),
+ msg(msg_),
+ func(func_),
+ conn_id(conn_id_),
+ send_response(send_response_) {}
+
+ std::string name;
+ std::shared_ptr<Message> msg;
+ RpcCallback func;
+ unsigned int conn_id;
+ SendMsgFunc send_response;
+ };
+ std::queue<RpcCall> m_call_queue, m_poll_queue;
+
+ llvm::DenseMap<std::pair<unsigned int, unsigned int>, SendMsgFunc>
+ m_response_map;
+
+ std::thread m_thread;
+ std::mutex m_shutdown_mutex;
+ std::condition_variable m_shutdown_cv;
+ bool m_shutdown = false;
+
+ ATOMIC_STATIC_DECL(RpcServer)
+};
+
+} // namespace nt
+
+#endif // NT_RPCSERVER_H_