migrate all manual closing to new UniqueFd

Makes things cleaner.
This commit is contained in:
Lily Tsuru 2024-02-03 19:19:10 -05:00
parent dcda1bfd1c
commit bc8ed5eb8a
7 changed files with 71 additions and 19 deletions

View File

@ -13,11 +13,7 @@ namespace nanosm {
} }
} }
EventLoop::~EventLoop() { EventLoop::~EventLoop() = default;
if(epollFd == -1) {
close(epollFd);
}
}
void EventLoop::Post(PostFn func) { void EventLoop::Post(PostFn func) {
if(!func) if(!func)

View File

@ -62,13 +62,14 @@ namespace nanosm {
void Stop(); void Stop();
private: private:
int epollFd {}; nanosm::UniqueFd epollFd {};
bool shouldStop { false }; bool shouldStop { false };
/// All tracked IO objects. /// All tracked IO objects.
std::set<std::shared_ptr<IoObject>> ioObjects {}; std::set<std::shared_ptr<IoObject>> ioObjects {};
/// FIFO queue of functions to run semi-asynchronously /// FIFO queue of functions to run semi-asynchronously
/// One function is ran every eventloop tick.
std::deque<PostFn> postCallbacks {}; std::deque<PostFn> postCallbacks {};
}; };

View File

@ -36,7 +36,7 @@ namespace nanosm {
void Process::Respawn() { void Process::Respawn() {
pid = Clone3({ pid = Clone3({
.flags = CLONE_PIDFD, .flags = CLONE_PIDFD,
.pidfd = std::bit_cast<u64>(&pidFd), .pidfd = std::bit_cast<u64>(pidFd.GetFDMutPtr()),
.exit_signal = SIGCHLD, .exit_signal = SIGCHLD,
}); });
@ -95,10 +95,8 @@ namespace nanosm {
} }
void Process::Reset() { void Process::Reset() {
if(pidFd != -1) { if(pidFd.Valid())
close(pidFd); pidFd.Reset();
pidFd = -1;
}
pid = -1; pid = -1;
siginfo = {}; siginfo = {};

View File

@ -4,6 +4,7 @@
#include <sys/wait.h> #include <sys/wait.h>
#include "EventLoop.hpp" #include "EventLoop.hpp"
#include "Types.hpp"
namespace nanosm { namespace nanosm {
@ -36,7 +37,7 @@ namespace nanosm {
private: private:
void Reset(); void Reset();
int pidFd { -1 }; nanosm::UniqueFd pidFd { -1 };
pid_t pid { -1 }; pid_t pid { -1 };
siginfo_t siginfo {}; siginfo_t siginfo {};
std::string commLine; std::string commLine;

View File

@ -12,13 +12,11 @@ namespace nanosm {
} }
} }
Timer::~Timer() { Timer::~Timer() = default;
Reset();
}
void Timer::Reset() { void Timer::Reset() {
if(timerFd != -1) if(timerFd.Valid())
close(timerFd); timerFd.Reset();
} }
int Timer::GetFD() const { int Timer::GetFD() const {

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "EventLoop.hpp" #include "EventLoop.hpp"
#include "Types.hpp"
namespace nanosm { namespace nanosm {
@ -23,7 +24,7 @@ namespace nanosm {
void Arm(u32 durationSeconds); void Arm(u32 durationSeconds);
private: private:
int timerFd { -1 }; nanosm::UniqueFd timerFd { -1 };
std::function<void()> cb; std::function<void()> cb;
}; };

View File

@ -46,4 +46,61 @@ namespace nanosm {
usize size {}; usize size {};
}; };
/// A "smart pointer" for file descriptors.
struct UniqueFd {
constexpr UniqueFd()
: UniqueFd(-1) {}
constexpr explicit UniqueFd(int fd)
: fd(fd) {
}
constexpr UniqueFd(UniqueFd&& from) {
fd = std::move(from.fd);
from.fd = -1;
}
constexpr ~UniqueFd() {
Reset();
}
/// Assigns a new file descriptor to this UniqueFd,
/// closing the old one.
constexpr UniqueFd& operator=(int fd) {
Reset(fd);
return *this;
}
constexpr int GetFD() const { return fd; }
/// Gets a mutable pointer to the file descriptor value.
///
/// You should only use this in clone3() or such system
/// calls that expect an address to a value to populate
/// with a known-valid/good file descriptor. Otherwise,
/// this function is very unsafe and a easy way to FD leak.
int* GetFDMutPtr() { return &fd; }
constexpr operator int() const {
return GetFD();
}
constexpr bool Valid() const {
return fd != -1;
}
constexpr void Reset(int newFd = -1) {
// If a previously valid file descriptor was assigned,
// then we have to close it to avoid leaking file
// descriptors. Do so here.
if(Valid())
close(fd);
fd = newFd;
}
private:
int fd { -1 };
};
} // namespace nanosm } // namespace nanosm