Separate Connection, ConnectionHandler, Server
This commit is contained in:
83
src/connection.hpp
Normal file
83
src/connection.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include "arena_allocator.hpp"
|
||||
#include "connection_handler.hpp"
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern std::atomic<int> activeConnections;
|
||||
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Represents a single client connection with efficient memory management.
|
||||
*
|
||||
* Connection ownership model:
|
||||
* - Created by accept thread, transferred to epoll via raw pointer
|
||||
* - Network threads claim ownership by wrapping raw pointer in unique_ptr
|
||||
* - Network thread optionally passes ownership to a thread pipeline
|
||||
* - Owner eventually transfers back to epoll by releasing unique_ptr to raw
|
||||
* pointer
|
||||
* - RAII cleanup happens if network thread doesn't transfer back
|
||||
*
|
||||
* Only the handler interface methods are public - all networking details are
|
||||
* private.
|
||||
*/
|
||||
// Forward declaration
|
||||
class Server;
|
||||
|
||||
struct Connection {
|
||||
Connection(struct sockaddr_storage addr, int fd, int64_t id,
|
||||
ConnectionHandler *handler, std::weak_ptr<Server> server);
|
||||
~Connection();
|
||||
|
||||
// Handler interface - public methods that handlers can use
|
||||
void appendMessage(std::string_view s);
|
||||
void closeAfterSend() { closeConnection_ = true; }
|
||||
ArenaAllocator &getArena() { return arena_; }
|
||||
int64_t getId() const { return id_; }
|
||||
|
||||
// Note: To release connection back to server, use
|
||||
// Server::releaseBackToServer(std::move(connection_ptr))
|
||||
|
||||
private:
|
||||
// Server is a friend and can access all networking internals
|
||||
friend class Server;
|
||||
|
||||
// Networking interface - only accessible by Server
|
||||
std::string_view readBytes(size_t max_request_size, size_t buffer_size);
|
||||
bool writeBytes();
|
||||
void tsan_acquire();
|
||||
void tsan_release();
|
||||
|
||||
// Direct access methods for Server
|
||||
int getFd() const { return fd_; }
|
||||
bool hasMessages() const { return !messages_.empty(); }
|
||||
bool shouldClose() const { return closeConnection_; }
|
||||
const int fd_;
|
||||
const int64_t id_;
|
||||
struct sockaddr_storage addr_; // sockaddr_storage handles IPv4/IPv6
|
||||
ArenaAllocator arena_;
|
||||
ConnectionHandler *handler_;
|
||||
std::weak_ptr<Server> server_; // Weak reference to server for safe cleanup
|
||||
|
||||
std::deque<std::string_view, ArenaStlAllocator<std::string_view>> messages_{
|
||||
ArenaStlAllocator<std::string_view>{&arena_}};
|
||||
|
||||
// Whether or not to close the connection after completing writing the
|
||||
// response
|
||||
bool closeConnection_{false};
|
||||
|
||||
// TSAN support for epoll synchronization
|
||||
#if __has_feature(thread_sanitizer)
|
||||
std::atomic<int> tsan_sync_;
|
||||
#endif
|
||||
};
|
||||
Reference in New Issue
Block a user