73 lines
2.3 KiB
C++
73 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <sys/mman.h>
|
|
#include <sys/resource.h>
|
|
|
|
struct Connection;
|
|
|
|
/**
|
|
* mmap-based Connection Registry for tracking active connections.
|
|
*
|
|
* This registry provides a lock-free mechanism for tracking all connections
|
|
* owned by the server, indexed by file descriptor. The design uses mmap to
|
|
* allocate a large virtual address space efficiently, with physical memory
|
|
* allocated on-demand as connections are created.
|
|
*
|
|
*/
|
|
struct ConnectionRegistry {
|
|
public:
|
|
/**
|
|
* Initialize the connection registry.
|
|
* Allocates virtual address space based on RLIMIT_NOFILE.
|
|
*
|
|
* Aborts the process if mmap fails or RLIMIT_NOFILE cannot be read
|
|
*/
|
|
ConnectionRegistry();
|
|
|
|
/**
|
|
* Destructor ensures proper cleanup of mmap'd memory.
|
|
*/
|
|
~ConnectionRegistry();
|
|
|
|
/**
|
|
* Store a connection in the registry, indexed by its file descriptor.
|
|
* Takes ownership of the connection via unique_ptr.
|
|
*
|
|
* @param fd File descriptor (must be valid and < max_fds_)
|
|
* @param connection unique_ptr to the connection (ownership transferred)
|
|
*/
|
|
void store(int fd, std::unique_ptr<Connection> connection);
|
|
|
|
/**
|
|
* Remove a connection from the registry and transfer ownership to caller.
|
|
* This transfers ownership via unique_ptr move semantics.
|
|
*
|
|
* @param fd File descriptor
|
|
* @return unique_ptr to the connection, or nullptr if not found
|
|
*/
|
|
std::unique_ptr<Connection> remove(int fd);
|
|
|
|
/**
|
|
* Get the maximum number of file descriptors supported.
|
|
*
|
|
* @return Maximum file descriptor limit
|
|
*/
|
|
size_t max_fds() const { return max_fds_; }
|
|
|
|
// Non-copyable and non-movable
|
|
ConnectionRegistry(const ConnectionRegistry &) = delete;
|
|
ConnectionRegistry &operator=(const ConnectionRegistry &) = delete;
|
|
ConnectionRegistry(ConnectionRegistry &&) = delete;
|
|
ConnectionRegistry &operator=(ConnectionRegistry &&) = delete;
|
|
|
|
private:
|
|
std::atomic<Connection *>
|
|
*connections_; ///< mmap'd array of raw connection pointers. It's
|
|
///< thread-safe without since epoll_ctl happens before
|
|
///< epoll_wait, but this makes tsan happy /shrug.
|
|
size_t max_fds_; ///< Maximum file descriptor limit
|
|
size_t aligned_size_; ///< Page-aligned size for munmap
|
|
};
|