Brian Silverman | f7bd1c2 | 2015-12-24 16:07:11 -0800 | [diff] [blame^] | 1 | /*----------------------------------------------------------------------------*/ |
| 2 | /* Copyright (c) FIRST 2015. All Rights Reserved. */ |
| 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */ |
| 4 | /* must be accompanied by the FIRST BSD license file in the root directory of */ |
| 5 | /* the project. */ |
| 6 | /*----------------------------------------------------------------------------*/ |
| 7 | |
| 8 | #ifndef NT_RPCSERVER_H_ |
| 9 | #define NT_RPCSERVER_H_ |
| 10 | |
| 11 | #include <atomic> |
| 12 | #include <condition_variable> |
| 13 | #include <mutex> |
| 14 | #include <queue> |
| 15 | #include <thread> |
| 16 | #include <utility> |
| 17 | #include <vector> |
| 18 | |
| 19 | #include "llvm/DenseMap.h" |
| 20 | #include "atomic_static.h" |
| 21 | #include "Message.h" |
| 22 | #include "ntcore_cpp.h" |
| 23 | |
| 24 | namespace nt { |
| 25 | |
| 26 | class RpcServer { |
| 27 | friend class RpcServerTest; |
| 28 | public: |
| 29 | static RpcServer& GetInstance() { |
| 30 | ATOMIC_STATIC(RpcServer, instance); |
| 31 | return instance; |
| 32 | } |
| 33 | ~RpcServer(); |
| 34 | |
| 35 | typedef std::function<void(std::shared_ptr<Message>)> SendMsgFunc; |
| 36 | |
| 37 | void Start(); |
| 38 | void Stop(); |
| 39 | |
| 40 | bool active() const { return m_active; } |
| 41 | |
| 42 | void ProcessRpc(StringRef name, std::shared_ptr<Message> msg, |
| 43 | RpcCallback func, unsigned int conn_id, |
| 44 | SendMsgFunc send_response); |
| 45 | |
| 46 | bool PollRpc(bool blocking, RpcCallInfo* call_info); |
| 47 | void PostRpcResponse(unsigned int rpc_id, unsigned int call_uid, |
| 48 | llvm::StringRef result); |
| 49 | |
| 50 | private: |
| 51 | RpcServer(); |
| 52 | |
| 53 | void ThreadMain(); |
| 54 | |
| 55 | std::atomic_bool m_active; |
| 56 | std::atomic_bool m_terminating; |
| 57 | |
| 58 | std::mutex m_mutex; |
| 59 | std::condition_variable m_call_cond, m_poll_cond; |
| 60 | |
| 61 | struct RpcCall { |
| 62 | RpcCall(StringRef name_, std::shared_ptr<Message> msg_, RpcCallback func_, |
| 63 | unsigned int conn_id_, SendMsgFunc send_response_) |
| 64 | : name(name_), |
| 65 | msg(msg_), |
| 66 | func(func_), |
| 67 | conn_id(conn_id_), |
| 68 | send_response(send_response_) {} |
| 69 | |
| 70 | std::string name; |
| 71 | std::shared_ptr<Message> msg; |
| 72 | RpcCallback func; |
| 73 | unsigned int conn_id; |
| 74 | SendMsgFunc send_response; |
| 75 | }; |
| 76 | std::queue<RpcCall> m_call_queue, m_poll_queue; |
| 77 | |
| 78 | llvm::DenseMap<std::pair<unsigned int, unsigned int>, SendMsgFunc> |
| 79 | m_response_map; |
| 80 | |
| 81 | std::thread m_thread; |
| 82 | std::mutex m_shutdown_mutex; |
| 83 | std::condition_variable m_shutdown_cv; |
| 84 | bool m_shutdown = false; |
| 85 | |
| 86 | ATOMIC_STATIC_DECL(RpcServer) |
| 87 | }; |
| 88 | |
| 89 | } // namespace nt |
| 90 | |
| 91 | #endif // NT_RPCSERVER_H_ |