WPILibC++  unspecified
Dispatcher.h
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_DISPATCHER_H_
9 #define NT_DISPATCHER_H_
10 
11 #include <atomic>
12 #include <chrono>
13 #include <condition_variable>
14 #include <functional>
15 #include <memory>
16 #include <mutex>
17 #include <string>
18 #include <thread>
19 #include <vector>
20 
21 #include "llvm/StringRef.h"
22 
23 #include "IDispatcher.h"
24 #include "INetworkConnection.h"
25 
26 namespace wpi {
27 class Logger;
28 class NetworkAcceptor;
29 class NetworkStream;
30 }
31 
32 namespace nt {
33 
34 class IConnectionNotifier;
35 class IStorage;
36 class NetworkConnection;
37 
38 class DispatcherBase : public IDispatcher {
39  friend class DispatcherTest;
40 
41  public:
42  typedef std::function<std::unique_ptr<wpi::NetworkStream>()> Connector;
43 
44  DispatcherBase(IStorage& storage, IConnectionNotifier& notifier,
45  wpi::Logger& logger);
46  virtual ~DispatcherBase();
47 
48  unsigned int GetNetworkMode() const;
49  void StartServer(llvm::StringRef persist_filename,
50  std::unique_ptr<wpi::NetworkAcceptor> acceptor);
51  void StartClient();
52  void Stop();
53  void SetUpdateRate(double interval);
54  void SetIdentity(llvm::StringRef name);
55  void Flush();
56  std::vector<ConnectionInfo> GetConnections() const;
57  bool IsConnected() const;
58 
59  unsigned int AddListener(
60  std::function<void(const ConnectionNotification& event)> callback,
61  bool immediate_notify) const;
62  unsigned int AddPolledListener(unsigned int poller_uid,
63  bool immediate_notify) const;
64 
65  void SetConnector(Connector connector);
66  void SetConnectorOverride(Connector connector);
67  void ClearConnectorOverride();
68 
69  bool active() const { return m_active; }
70 
71  DispatcherBase(const DispatcherBase&) = delete;
72  DispatcherBase& operator=(const DispatcherBase&) = delete;
73 
74  private:
75  void DispatchThreadMain();
76  void ServerThreadMain();
77  void ClientThreadMain();
78 
79  bool ClientHandshake(
80  NetworkConnection& conn,
81  std::function<std::shared_ptr<Message>()> get_msg,
82  std::function<void(llvm::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
83  bool ServerHandshake(
84  NetworkConnection& conn,
85  std::function<std::shared_ptr<Message>()> get_msg,
86  std::function<void(llvm::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
87 
88  void ClientReconnect(unsigned int proto_rev = 0x0300);
89 
90  void QueueOutgoing(std::shared_ptr<Message> msg, INetworkConnection* only,
91  INetworkConnection* except) override;
92 
93  IStorage& m_storage;
94  IConnectionNotifier& m_notifier;
95  unsigned int m_networkMode = NT_NET_MODE_NONE;
96  std::string m_persist_filename;
97  std::thread m_dispatch_thread;
98  std::thread m_clientserver_thread;
99 
100  std::unique_ptr<wpi::NetworkAcceptor> m_server_acceptor;
101  Connector m_client_connector_override;
102  Connector m_client_connector;
103  uint8_t m_connections_uid = 0;
104 
105  // Mutex for user-accessible items
106  mutable std::mutex m_user_mutex;
107  std::vector<std::shared_ptr<INetworkConnection>> m_connections;
108  std::string m_identity;
109 
110  std::atomic_bool m_active; // set to false to terminate threads
111  std::atomic_uint m_update_rate; // periodic dispatch update rate, in ms
112 
113  // Condition variable for forced dispatch wakeup (flush)
114  std::mutex m_flush_mutex;
115  std::condition_variable m_flush_cv;
116  std::chrono::steady_clock::time_point m_last_flush;
117  bool m_do_flush = false;
118 
119  // Condition variable for client reconnect (uses user mutex)
120  std::condition_variable m_reconnect_cv;
121  unsigned int m_reconnect_proto_rev = 0x0300;
122  bool m_do_reconnect = true;
123 
124  protected:
125  wpi::Logger& m_logger;
126 };
127 
128 class Dispatcher : public DispatcherBase {
129  friend class DispatcherTest;
130 
131  public:
132  Dispatcher(IStorage& storage, IConnectionNotifier& notifier,
133  wpi::Logger& logger)
134  : DispatcherBase(storage, notifier, logger) {}
135 
136  void StartServer(StringRef persist_filename, const char* listen_address,
137  unsigned int port);
138 
139  void SetServer(const char* server_name, unsigned int port);
140  void SetServer(ArrayRef<std::pair<StringRef, unsigned int>> servers);
141  void SetServerTeam(unsigned int team, unsigned int port);
142 
143  void SetServerOverride(const char* server_name, unsigned int port);
144  void ClearServerOverride();
145 };
146 
147 } // namespace nt
148 
149 #endif // NT_DISPATCHER_H_
Definition: Dispatcher.h:38
std::vector< ConnectionInfo > GetConnections()
Get information on the currently established network connections.
Definition: ntcore_cpp.cpp:891
void SetUpdateRate(double interval)
Set the periodic update rate.
Definition: ntcore_cpp.cpp:871
void SetServer(const char *server_name, unsigned int port)
Sets server address and port for client (without restarting client).
Definition: ntcore_cpp.cpp:821
Definition: Dispatcher.h:128
void Flush()
Flush Entries.
Definition: ntcore_cpp.cpp:882
Definition: IConnectionNotifier.h:17
Definition: SocketError.cpp:18
Definition: IStorage.h:26
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:32
Definition: NetworkConnection.h:30
bool IsConnected(NT_Inst inst)
Return whether or not the instance is connected to another node.
Definition: ntcore_cpp.cpp:902
Definition: IEntryNotifier.h:15
NetworkTables Connection Notification.
Definition: ntcore_cpp.h:206
unsigned int GetNetworkMode()
Get the current network mode.
Definition: ntcore_cpp.cpp:732
void SetServerTeam(NT_Inst inst, unsigned int team, unsigned int port)
Sets server addresses and port for client (without restarting client).
Definition: ntcore_cpp.cpp:844
void StartServer(StringRef persist_filename, const char *listen_address, unsigned int port)
Starts a server using the specified filename, listening address, and port.
Definition: ntcore_cpp.cpp:743
Definition: IDispatcher.h:21
Definition: Logger.h:30
Definition: INetworkConnection.h:18
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:42
void StartClient()
Starts a client.
Definition: ntcore_cpp.cpp:766