webserv/webserv/socket/TimerSocket.cpp
2025-11-06 15:42:39 +01:00

66 lines
1.8 KiB
C++

#include <webserv/socket/TimerSocket.hpp>
#include <webserv/log/Log.hpp> // for LOCATION, Log
#include <webserv/socket/ASocket.hpp> // for ASocket
#include <stdexcept> // for runtime_error
#include <system_error> // for generic_category, system_error
#include <errno.h> // for errno
#include <sys/time.h> // for CLOCK_MONOTONIC
#include <sys/timerfd.h> // for timerfd_create, timerfd_settime
#include <time.h> // for itimerspec, timespec
#include <unistd.h> // for read, write
TimerSocket::TimerSocket(std::chrono::milliseconds timeout)
: ASocket(timerfd_create(CLOCK_MONOTONIC, 0), ASocket::IoState::NONE), timeout_(timeout)
{
}
void TimerSocket::activate()
{
Log::trace(LOCATION);
struct itimerspec timerSpec;
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(timeout_);
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout_ - seconds);
timerSpec.it_value.tv_sec = seconds.count();
timerSpec.it_value.tv_nsec = nanoseconds.count();
timerSpec.it_interval.tv_sec = 0;
timerSpec.it_interval.tv_nsec = 0;
if (timerfd_settime(getFd(), 0, &timerSpec, nullptr) == -1)
{
throw std::runtime_error("Failed to set timerfd time");
}
active_ = true;
setIOState(IoState::READ);
}
ASocket::Type TimerSocket::getType() const noexcept
{
return ASocket::Type::TIMER_SOCKET;
}
bool TimerSocket::isActive() const noexcept
{
return active_;
}
ssize_t TimerSocket::read(void *buf, size_t len) const
{
Log::trace(LOCATION);
ssize_t bytesRead = ::read(getFd(), buf, len);
return bytesRead;
}
ssize_t TimerSocket::write(const void *buf, size_t len) const
{
Log::trace(LOCATION);
ssize_t bytesSent = ::write(getFd(), buf, len);
return bytesSent;
}