Files
allwpilib/src/Dispatcher.h

106 lines
2.8 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>
2015-07-16 22:55:50 -07:00
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "llvm/StringRef.h"
#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() {
if (!m_instance) m_instance.reset(new Dispatcher);
return *m_instance;
}
~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-17 22:39:36 -07:00
void ClientReconnect();
NT_Type GetEntryType(unsigned int id) const;
2015-07-16 22:55:50 -07:00
struct Connection {
enum State {
};
State state;
2015-07-17 22:39:36 -07:00
std::string remote_id;
std::unique_ptr<NetworkConnection> net;
2015-07-16 22:55:50 -07:00
};
2015-07-17 22:39:36 -07:00
void AddConnection(Connection&& conn);
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;
2015-07-16 22:55:50 -07:00
std::vector<Connection> m_connections;
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;
bool m_do_reconnect;
2015-07-16 22:55:50 -07:00
// Map from integer id to storage entry. Id is 16-bit, so just use a vector.
mutable std::mutex m_idmap_mutex;
std::vector<std::shared_ptr<StorageEntry>> m_idmap;
// Global instance
2015-07-16 22:55:50 -07:00
static std::unique_ptr<Dispatcher> m_instance;
};
} // namespace nt
2015-07-16 22:55:50 -07:00
#endif // NT_DISPATCHER_H_