Files
allwpilib/src/Dispatcher.h

111 lines
3.2 KiB
C
Raw Normal View History

2015-07-16 22:55:50 -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_DISPATCHER_H_
#define NT_DISPATCHER_H_
#include <atomic>
2015-07-17 22:39:36 -07:00
#include <chrono>
#include <condition_variable>
#include <functional>
2015-07-16 22:55:50 -07:00
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "llvm/StringRef.h"
#include "atomic_static.h"
2015-07-16 22:55:50 -07:00
#include "NetworkConnection.h"
#include "Storage.h"
2015-07-16 22:55:50 -07:00
2015-07-17 22:39:36 -07:00
class TCPAcceptor;
namespace nt {
2015-07-16 22:55:50 -07:00
class Dispatcher {
public:
static Dispatcher& GetInstance() {
ATOMIC_STATIC(Dispatcher, instance);
return instance;
2015-07-16 22:55:50 -07:00
}
~Dispatcher();
void StartServer(const char* listen_address, unsigned int port);
void StartClient(const char* server_name, unsigned int port);
void Stop();
void SetUpdateRate(double interval);
void SetIdentity(llvm::StringRef name);
2015-07-17 22:39:36 -07:00
void Flush();
bool active() const { return m_active; }
2015-07-16 22:55:50 -07:00
Dispatcher(const Dispatcher&) = delete;
Dispatcher& operator=(const Dispatcher&) = delete;
private:
Dispatcher();
void DispatchThreadMain();
void ServerThreadMain(const char* listen_address, unsigned int port);
void ClientThreadMain(const char* server_name, unsigned int port);
2015-07-31 20:32:52 -07:00
bool ClientHandshake(
NetworkConnection& conn,
std::function<std::shared_ptr<Message>()> get_msg,
std::function<void(llvm::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
bool ServerHandshake(
NetworkConnection& conn,
std::function<std::shared_ptr<Message>()> get_msg,
std::function<void(llvm::ArrayRef<std::shared_ptr<Message>>)> send_msgs);
2015-07-31 20:32:52 -07:00
void ClientReconnect(unsigned int proto_rev = 0x0300);
2015-07-17 22:39:36 -07:00
void QueueOutgoing(std::shared_ptr<Message> msg, NetworkConnection* only,
NetworkConnection* except);
2015-07-17 22:39:36 -07:00
bool m_server;
2015-07-16 22:55:50 -07:00
std::thread m_dispatch_thread;
std::thread m_clientserver_thread;
2015-07-17 22:39:36 -07:00
std::thread m_notifier_thread;
2015-07-16 22:55:50 -07:00
2015-07-17 22:39:36 -07:00
std::shared_ptr<TCPAcceptor> m_server_acceptor;
// Mutex for user-accessible items
std::mutex m_user_mutex;
struct Connection {
Connection() = default;
explicit Connection(std::unique_ptr<NetworkConnection> net_)
: net(std::move(net_)) {}
std::unique_ptr<NetworkConnection> net;
NetworkConnection::Outgoing outgoing;
};
std::vector<Connection> m_connections;
2015-07-16 22:55:50 -07:00
std::string m_identity;
2015-07-17 22:39:36 -07:00
std::atomic_bool m_active; // set to false to terminate threads
std::atomic_uint m_update_rate; // periodic dispatch update rate, in ms
// Condition variable for forced dispatch wakeup (flush)
std::mutex m_flush_mutex;
std::condition_variable m_flush_cv;
std::chrono::steady_clock::time_point m_last_flush;
bool m_do_flush;
// Condition variable for client reconnect
std::mutex m_reconnect_mutex;
std::condition_variable m_reconnect_cv;
2015-07-31 20:32:52 -07:00
unsigned int m_reconnect_proto_rev;
2015-07-17 22:39:36 -07:00
bool m_do_reconnect;
2015-07-16 22:55:50 -07:00
ATOMIC_STATIC_DECL(Dispatcher)
2015-07-16 22:55:50 -07:00
};
} // namespace nt
2015-07-16 22:55:50 -07:00
#endif // NT_DISPATCHER_H_