memgraph/io/network/tcp_server.hpp

95 lines
1.8 KiB
C++
Raw Normal View History

2015-10-29 05:55:57 +08:00
#pragma once
#include <list>
#include <thread>
2015-10-29 05:55:57 +08:00
#include <atomic>
#include "debug/log.hpp"
#include "tcp_listener.hpp"
2015-10-29 05:55:57 +08:00
namespace io
{
template <class T>
class TcpServer : TcpListener<TcpServer<T>, 64, -1>
2015-10-29 05:55:57 +08:00
{
public:
TcpServer(const char* addr, const char* port)
: stream(std::move(Socket::bind(addr, port))) {}
2015-10-29 05:55:57 +08:00
~TcpServer()
{
stop();
2015-10-29 05:55:57 +08:00
for(auto& worker : workers)
worker.join();
2015-10-29 05:55:57 +08:00
}
template <class F>
void listen(size_t n, size_t backlog, F&& f)
2015-10-29 05:55:57 +08:00
{
for(size_t i = 0; i < n; ++i)
2015-10-29 05:55:57 +08:00
{
workers.emplace_back();
auto& w = workers.back();
threads[i] = std::thread([this, &w]() {
while(alive)
{
LOG_DEBUG("Worker " << hash(std::this_thread::get_id())
<< " waiting... ");
w.wait_and_process_events();
}
});
2015-10-29 05:55:57 +08:00
}
stream.socket.listen(backlog);
2015-10-29 05:55:57 +08:00
}
void stop()
{
alive.store(false, std::memory_order_release);
}
private:
std::list<std::thread> threads;
std::list<T> workers;
2015-10-29 05:55:57 +08:00
std::atomic<bool> alive { true };
TcpStream stream;
size_t idx = 0;
2015-10-29 05:55:57 +08:00
void on_close(TcpStream& stream)
{
LOG_DEBUG("server on_close!!!!");
2015-10-29 05:55:57 +08:00
}
void on_error(TcpStream& stream)
2015-10-29 05:55:57 +08:00
{
LOG_DEBUG("server on_error!!!!");
2015-10-29 05:55:57 +08:00
}
void on_data(TcpStream&)
2015-10-29 05:55:57 +08:00
{
while (true)
2015-10-29 05:55:57 +08:00
{
LOG_DEBUG("Trying to accept... ");
if(!workers[idx].accept(socket))
{
LOG_DEBUG("Did not accept!");
break;
}
idx = (idx + 1) % workers.size();
LOG_DEBUG("Accepted a new connection!");
2015-10-29 05:55:57 +08:00
}
}
2015-10-29 05:55:57 +08:00
void on_wait_timeout()
{
2015-10-29 05:55:57 +08:00
}
};
}