Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
51
tools/EVerest-main/lib/everest/io/src/event/event_fd.cpp
Normal file
51
tools/EVerest-main/lib/everest/io/src/event/event_fd.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/io/event/event_fd.hpp>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
namespace everest::lib::io::event {
|
||||
|
||||
event_fd_base::event_fd_base(unsigned int initval, int flags) : m_fd(::eventfd(initval, flags)) {
|
||||
if (m_fd == -1) {
|
||||
throw std::runtime_error("failed to create an eventfd");
|
||||
}
|
||||
}
|
||||
|
||||
event_fd_base::operator int() const {
|
||||
return get_raw_fd();
|
||||
}
|
||||
|
||||
int event_fd_base::get_raw_fd() const {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
bool event_fd_base::valid() const {
|
||||
return m_fd != unique_fd::NO_DESCRIPTOR_SENTINEL;
|
||||
}
|
||||
|
||||
std::optional<uint64_t> event_fd_base::read() {
|
||||
eventfd_t eventfd_buffer{0};
|
||||
if (eventfd_read(m_fd, &eventfd_buffer) == 0) {
|
||||
return eventfd_buffer;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool event_fd_base::write(std::uint64_t data) {
|
||||
return eventfd_write(m_fd, data) == 0;
|
||||
}
|
||||
|
||||
bool event_fd_base::notify() {
|
||||
return write(1);
|
||||
}
|
||||
|
||||
event_fd::event_fd() : event_fd_base(0, 0) {
|
||||
}
|
||||
|
||||
semaphore_fd::semaphore_fd() : event_fd_base(0, EFD_SEMAPHORE) {
|
||||
}
|
||||
|
||||
} // namespace everest::lib::io::event
|
||||
164
tools/EVerest-main/lib/everest/io/src/event/fd_event_client.cpp
Normal file
164
tools/EVerest-main/lib/everest/io/src/event/fd_event_client.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/io/event/fd_event_client.hpp>
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
|
||||
namespace everest::lib::io::event {
|
||||
|
||||
generic_fd_event_client_impl::generic_fd_event_client_impl(action const& send_one, action const& receive_one,
|
||||
action const& reset_client, error_status const& get_error) :
|
||||
m_send_one(send_one), m_receive_one(receive_one), m_reset_client(reset_client), m_get_error(get_error) {
|
||||
m_event_handler = std::make_unique<event::fd_event_handler>();
|
||||
}
|
||||
|
||||
generic_fd_event_client_impl::~generic_fd_event_client_impl() = default;
|
||||
|
||||
int generic_fd_event_client_impl::get_poll_fd() {
|
||||
return m_event_handler->get_poll_fd();
|
||||
}
|
||||
|
||||
sync_status generic_fd_event_client_impl::sync() {
|
||||
return sync_impl(-1);
|
||||
}
|
||||
|
||||
sync_status generic_fd_event_client_impl::sync_impl(int timeout_ms) {
|
||||
auto result = m_event_handler->poll(std::chrono::milliseconds(timeout_ms));
|
||||
m_event_handler->run_actions();
|
||||
|
||||
// The error handler must be called after all event handlers have run.
|
||||
// Removing handlers during error processing is likely to result in
|
||||
// inconsistent state and and segmentations fault.
|
||||
return result ? sync_status::ok : sync_status::timeout;
|
||||
}
|
||||
|
||||
bool generic_fd_event_client_impl::setup_error_event_handler() {
|
||||
return m_event_handler->register_event_handler(&m_error_status_event_fd, [this](auto) {
|
||||
if (on_error()) {
|
||||
error_handler();
|
||||
call_error_handler(m_error);
|
||||
return sync_status::error;
|
||||
} else if (clear_error_pending()) {
|
||||
clear_error_handler(m_error);
|
||||
}
|
||||
return sync_status::ok;
|
||||
});
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::setup_io_event_handler(int fd) {
|
||||
using namespace everest::lib::io::event;
|
||||
m_event_handler->register_event_handler(
|
||||
fd,
|
||||
[this, fd](auto events) {
|
||||
auto success = true;
|
||||
if (events.count(poll_events::error)) {
|
||||
auto error = m_get_error();
|
||||
if (error) {
|
||||
set_error_status_and_notify(error);
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
if (events.count(poll_events::hungup)) {
|
||||
success = false;
|
||||
}
|
||||
if (success && events.count(poll_events::read)) {
|
||||
success = rx_handler();
|
||||
}
|
||||
if (success && events.count(poll_events::write)) {
|
||||
success = tx_handler(fd);
|
||||
}
|
||||
},
|
||||
poll_events::read);
|
||||
m_event_handler->register_event_handler(&m_io_event_fd, [this, fd](auto) {
|
||||
m_event_handler->modify_event_handler(fd, poll_events::write, event_modification::add);
|
||||
});
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::set_error_handler(cb_error const& handler) {
|
||||
add_action([this, handler]() { m_error = handler; });
|
||||
}
|
||||
|
||||
bool generic_fd_event_client_impl::unregister_source(int fd) {
|
||||
return m_event_handler->remove_event_handler(fd);
|
||||
}
|
||||
|
||||
bool generic_fd_event_client_impl::set_error_status_and_notify(int error_code) {
|
||||
auto result = set_error_status(error_code);
|
||||
m_error_status_event_fd.notify();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool generic_fd_event_client_impl::rx_handler() {
|
||||
auto status = m_receive_one();
|
||||
auto error_code = status == action_status::success ? 0 : m_get_error();
|
||||
auto result = set_error_status_and_notify(error_code);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool generic_fd_event_client_impl::tx_handler(int fd) {
|
||||
// We send one message only, even if more data is queued.
|
||||
// This prevents the kernel buffer from filling up
|
||||
auto status = m_send_one();
|
||||
switch (status) {
|
||||
case action_status::empty: {
|
||||
// if there are no more message we no longer listen to writeable events
|
||||
// otherwise we wait for the socket to become writeable again.
|
||||
m_event_handler->modify_event_handler(fd, event::poll_events::write, event::event_modification::remove);
|
||||
return true;
|
||||
}
|
||||
case action_status::fail: {
|
||||
auto error_code = m_get_error();
|
||||
set_error_status_and_notify(error_code);
|
||||
return false;
|
||||
}
|
||||
case action_status::success: {
|
||||
set_error_status_and_notify(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::error_handler() {
|
||||
add_action([this]() { m_reset_client(); });
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::prepare_io_event_handler() {
|
||||
m_event_handler->register_event_handler(&m_connected_event_fd, [this](auto) {
|
||||
auto client_status = m_client_status.handle();
|
||||
if (client_status->ok) {
|
||||
auto error_code = m_get_error();
|
||||
set_error_status_and_notify(error_code);
|
||||
setup_io_event_handler(client_status->fd);
|
||||
if (m_on_ready_action) {
|
||||
m_event_handler->add_action(m_on_ready_action);
|
||||
}
|
||||
} else {
|
||||
auto error_code = m_get_error();
|
||||
set_error_status_and_notify(error_code);
|
||||
}
|
||||
|
||||
return sync_status::ok;
|
||||
});
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::on_client_ready(bool ok, int fd) {
|
||||
auto client_status = m_client_status.handle();
|
||||
client_status->ok = ok;
|
||||
client_status->fd = fd;
|
||||
m_connected_event_fd.notify();
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::add_action(fd_event_handler::task&& item) {
|
||||
m_event_handler->add_action(std::forward<fd_event_handler::task>(item));
|
||||
}
|
||||
|
||||
void generic_fd_event_client_impl::set_on_ready_action(ready_action&& item) {
|
||||
m_on_ready_action = std::move(item);
|
||||
auto client_status = m_client_status.handle();
|
||||
if (client_status->ok) {
|
||||
m_event_handler->add_action(m_on_ready_action);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace everest::lib::io::event
|
||||
379
tools/EVerest-main/lib/everest/io/src/event/fd_event_handler.cpp
Normal file
379
tools/EVerest-main/lib/everest/io/src/event/fd_event_handler.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include "everest/io/event/fd_event_sync_interface.hpp"
|
||||
#include <everest/io/event/event_fd.hpp>
|
||||
#include <everest/io/event/fd_event_client.hpp>
|
||||
#include <everest/io/event/fd_event_handler.hpp>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <everest/io/event/unique_fd.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
namespace everest::lib::io::event {
|
||||
|
||||
namespace {
|
||||
uint32_t poll_event_to_bitmask(poll_events e) {
|
||||
switch (e) {
|
||||
case poll_events::read:
|
||||
return EPOLLIN;
|
||||
case poll_events::priority:
|
||||
return EPOLLPRI;
|
||||
case poll_events::write:
|
||||
return EPOLLOUT;
|
||||
case poll_events::error:
|
||||
return EPOLLERR;
|
||||
case poll_events::hungup:
|
||||
return EPOLLHUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<poll_events> bitmask_to_poll_events(uint32_t bitmask) {
|
||||
std::set<poll_events> result;
|
||||
if (bitmask & EPOLLIN) {
|
||||
result.insert(poll_events::read);
|
||||
}
|
||||
if (bitmask & EPOLLPRI) {
|
||||
result.insert(poll_events::priority);
|
||||
}
|
||||
if (bitmask & EPOLLOUT) {
|
||||
result.insert(poll_events::write);
|
||||
}
|
||||
if (bitmask & EPOLLERR) {
|
||||
result.insert(poll_events::error);
|
||||
}
|
||||
if (bitmask & EPOLLHUP) {
|
||||
result.insert(poll_events::hungup);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t sum_events(std::set<poll_events> const& events) {
|
||||
uint32_t result = 0;
|
||||
for (auto e : events) {
|
||||
result = result | poll_event_to_bitmask(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::set<poll_events> operator|(poll_events lhs, poll_events rhs) {
|
||||
return {lhs, rhs};
|
||||
}
|
||||
|
||||
std::set<poll_events>& operator|(std::set<poll_events>& lhs, poll_events rhs) {
|
||||
lhs.insert(rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
bool operator&(std::set<poll_events> const& lhs, poll_events rhs) {
|
||||
return lhs.count(rhs) == 1;
|
||||
}
|
||||
|
||||
class EventHandlerMap {
|
||||
public:
|
||||
EventHandlerMap() : m_epoll_fd(epoll_create1(0)) {
|
||||
if (not m_epoll_fd.is_fd()) {
|
||||
::perror("epoll_create");
|
||||
}
|
||||
}
|
||||
|
||||
bool add(int fd, fd_event_handler::event_handler_type handler, fd_event_handler::event_list const& events) {
|
||||
epoll_event event;
|
||||
event.events = sum_events(events);
|
||||
event.data.fd = fd;
|
||||
auto result = epoll_ctl(m_epoll_fd, EPOLL_CTL_ADD, fd, &event) == 0;
|
||||
if (result) {
|
||||
m_event_map[fd] = {std::move(handler), event};
|
||||
m_pollfds.resize(m_pollfds.size() + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool remove(int fd) {
|
||||
auto epoll_result = epoll_ctl(m_epoll_fd, EPOLL_CTL_DEL, fd, nullptr);
|
||||
auto handler_result = m_event_map.count(fd);
|
||||
if (handler_result) {
|
||||
m_event_map.erase(fd);
|
||||
m_pollfds.resize(m_pollfds.size() - 1);
|
||||
}
|
||||
return epoll_result or handler_result;
|
||||
}
|
||||
bool modify_remove(int fd, fd_event_handler::event_list const& events) {
|
||||
auto action = [](uint32_t current, fd_event_handler::event_list const& change) {
|
||||
auto raw_change = sum_events(change);
|
||||
auto result = current & (~raw_change);
|
||||
return result;
|
||||
};
|
||||
return modify(fd, events, action);
|
||||
}
|
||||
|
||||
bool modify_add(int fd, fd_event_handler::event_list const& events) {
|
||||
auto action = [](uint32_t current, fd_event_handler::event_list const& change) {
|
||||
auto raw_change = sum_events(change);
|
||||
auto result = current | raw_change;
|
||||
return result;
|
||||
};
|
||||
return modify(fd, events, action);
|
||||
}
|
||||
|
||||
bool modify_replace(int fd, fd_event_handler::event_list const& events) {
|
||||
auto action = [](uint32_t, fd_event_handler::event_list const& change) {
|
||||
auto raw_change = sum_events(change);
|
||||
auto result = raw_change;
|
||||
return result;
|
||||
};
|
||||
return modify(fd, events, action);
|
||||
}
|
||||
|
||||
const auto& get(int fd) const {
|
||||
return std::get<fd_event_handler::event_handler_type>(m_event_map.at(fd));
|
||||
}
|
||||
|
||||
bool exists(int fd) const {
|
||||
return m_event_map.count(fd);
|
||||
}
|
||||
|
||||
auto& get_pollfds() {
|
||||
return m_pollfds;
|
||||
}
|
||||
|
||||
int get_epoll_fd() {
|
||||
return static_cast<int>(m_epoll_fd);
|
||||
}
|
||||
|
||||
private:
|
||||
using event_state = std::tuple<fd_event_handler::event_handler_type, epoll_event>;
|
||||
bool modify(int fd, fd_event_handler::event_list const& events,
|
||||
std::function<uint32_t(uint32_t, fd_event_handler::event_list const&)> const& event_action) {
|
||||
auto result = false;
|
||||
if (m_event_map.count(fd)) {
|
||||
auto& event = std::get<epoll_event>(m_event_map.at(fd));
|
||||
auto backup = event.events;
|
||||
event.events = event_action(backup, events);
|
||||
result = epoll_ctl(m_epoll_fd, EPOLL_CTL_MOD, fd, &event) == 0;
|
||||
if (not result) {
|
||||
event.events = backup;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<epoll_event> m_pollfds;
|
||||
std::map<int, event_state> m_event_map;
|
||||
unique_fd m_epoll_fd;
|
||||
};
|
||||
|
||||
fd_event_handler::~fd_event_handler() = default;
|
||||
|
||||
fd_event_handler::fd_event_handler() {
|
||||
m_handlers = std::make_unique<EventHandlerMap>();
|
||||
register_event_handler(&m_action_event, [](auto&&) {});
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(int fd, event_handler_type const& handler, event_list const& events) {
|
||||
if (fd == -1 or not handler or m_handlers->exists(fd)) {
|
||||
return false;
|
||||
}
|
||||
m_handlers->add(fd, handler, events);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(int fd, event_handler_type const& handler, poll_events event) {
|
||||
return register_event_handler(fd, handler, event_list{event});
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(event_fd* fd, event_handler_type const& handler) {
|
||||
if (not fd) {
|
||||
return false;
|
||||
}
|
||||
auto raw = fd->get_raw_fd();
|
||||
return register_event_handler(
|
||||
raw,
|
||||
[handler, fd](event_list const& e) {
|
||||
fd->read();
|
||||
handler(e);
|
||||
},
|
||||
poll_events::read);
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(event_fd* fd, event_handler_simple_type const& handler) {
|
||||
return register_event_handler(fd, [handler](event_list const&) { handler(); });
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(timer_fd* fd, event_handler_type const& handler) {
|
||||
if (not fd) {
|
||||
return false;
|
||||
}
|
||||
auto raw = fd->get_raw_fd();
|
||||
return register_event_handler(
|
||||
raw,
|
||||
[handler, fd](event_list const& e) {
|
||||
fd->read();
|
||||
handler(e);
|
||||
},
|
||||
poll_events::read);
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(timer_fd* fd, event_handler_simple_type const& handler) {
|
||||
return register_event_handler(fd, [handler](event_list const&) { handler(); });
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(fd_event_sync_interface* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
auto raw = obj->get_poll_fd();
|
||||
return register_event_handler(
|
||||
raw, [obj](event_list const&) { obj->sync(); }, poll_events::read);
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(fd_event_register_interface* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
return obj->register_events(*this);
|
||||
}
|
||||
|
||||
bool fd_event_handler::register_event_handler(fd_event_handler* obj) {
|
||||
if (not obj or obj == this) {
|
||||
return false;
|
||||
}
|
||||
auto raw = obj->get_poll_fd();
|
||||
return register_event_handler(
|
||||
raw,
|
||||
[obj](event_list const&) {
|
||||
obj->poll();
|
||||
obj->run_actions();
|
||||
},
|
||||
poll_events::read);
|
||||
}
|
||||
|
||||
bool fd_event_handler::unregister_event_handler(fd_event_register_interface* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
return obj->unregister_events(*this);
|
||||
}
|
||||
|
||||
bool fd_event_handler::unregister_event_handler(fd_event_sync_interface* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
return remove_event_handler(obj->get_poll_fd());
|
||||
}
|
||||
|
||||
bool fd_event_handler::unregister_event_handler(timer_fd* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
return remove_event_handler(obj->get_raw_fd());
|
||||
}
|
||||
|
||||
bool fd_event_handler::unregister_event_handler(event_fd* obj) {
|
||||
if (not obj) {
|
||||
return false;
|
||||
}
|
||||
return remove_event_handler(obj->get_raw_fd());
|
||||
}
|
||||
|
||||
bool fd_event_handler::unregister_event_handler(int fd) {
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
return remove_event_handler(fd);
|
||||
}
|
||||
|
||||
bool fd_event_handler::modify_event_handler(int fd, event_list const& events, event_modification change) {
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
switch (change) {
|
||||
case event_modification::add:
|
||||
return m_handlers->modify_add(fd, events);
|
||||
case event_modification::remove:
|
||||
return m_handlers->modify_remove(fd, events);
|
||||
case event_modification::replace:
|
||||
return m_handlers->modify_replace(fd, events);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool fd_event_handler::modify_event_handler(int fd, poll_events event, event_modification change) {
|
||||
return modify_event_handler(fd, event_list{event}, change);
|
||||
}
|
||||
|
||||
bool fd_event_handler::remove_event_handler(int fd) {
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
return m_handlers->remove(fd);
|
||||
}
|
||||
|
||||
void fd_event_handler::poll() {
|
||||
poll_impl(-1);
|
||||
}
|
||||
|
||||
bool fd_event_handler::poll_impl(int timeout_ms) {
|
||||
auto& pollfds = m_handlers->get_pollfds();
|
||||
auto status = ::epoll_wait(m_handlers->get_epoll_fd(), pollfds.data(), pollfds.size(), timeout_ms);
|
||||
|
||||
if (status > 0) {
|
||||
for (int i = 0; i < status; ++i) {
|
||||
auto& item = pollfds[i];
|
||||
m_handlers->get(item.data.fd)(bitmask_to_poll_events(item.events));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd_event_handler::get_poll_fd() {
|
||||
return m_handlers->get_epoll_fd();
|
||||
}
|
||||
|
||||
void fd_event_handler::add_action(task&& item) {
|
||||
task_pool.push(std::forward<task>(item));
|
||||
m_action_event.notify();
|
||||
}
|
||||
|
||||
void fd_event_handler::add_action(task const& item) {
|
||||
task_pool.push(std::move(item));
|
||||
m_action_event.notify();
|
||||
}
|
||||
|
||||
void fd_event_handler::run_actions() {
|
||||
while (true) {
|
||||
auto item = task_pool.try_pop();
|
||||
if (item.has_value()) {
|
||||
try {
|
||||
item.value()();
|
||||
} catch (...) {
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fd_event_handler::run_once() {
|
||||
poll();
|
||||
run_actions();
|
||||
}
|
||||
|
||||
void fd_event_handler::run(std::atomic_bool& online) {
|
||||
while (online.load()) {
|
||||
poll();
|
||||
run_actions();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace everest::lib::io::event
|
||||
75
tools/EVerest-main/lib/everest/io/src/event/timer_fd.cpp
Normal file
75
tools/EVerest-main/lib/everest/io/src/event/timer_fd.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <ctime>
|
||||
#include <everest/io/event/timer_fd.hpp>
|
||||
#include <stdexcept>
|
||||
#include <sys/timerfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace everest::lib::io::event {
|
||||
|
||||
timer_fd::timer_fd() : m_fd(::timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)) {
|
||||
if (m_fd == -1) {
|
||||
throw std::runtime_error("failed to create an timerfd");
|
||||
}
|
||||
}
|
||||
|
||||
timer_fd::operator int() const {
|
||||
return get_raw_fd();
|
||||
}
|
||||
|
||||
int timer_fd::get_raw_fd() const {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
bool timer_fd::valid() const {
|
||||
return m_fd != unique_fd::NO_DESCRIPTOR_SENTINEL;
|
||||
}
|
||||
|
||||
int timer_fd::read() {
|
||||
uint64_t buffer;
|
||||
return ::read(m_fd, &buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
bool timer_fd::reset() {
|
||||
return set_timeout_ns(m_to_ns);
|
||||
}
|
||||
|
||||
void timer_fd::set_single_shot(bool on) {
|
||||
m_single_shot = on;
|
||||
}
|
||||
|
||||
bool timer_fd::disarm() {
|
||||
struct itimerspec timer {};
|
||||
return ::timerfd_settime(m_fd, 0, &timer, nullptr) == 0;
|
||||
}
|
||||
|
||||
bool timer_fd::set_timeout_ms(long long to) {
|
||||
return set_timeout_ns(1000 * 1000 * to);
|
||||
}
|
||||
|
||||
bool timer_fd::set_timeout_us(long long to) {
|
||||
return set_timeout_ns(1000 * to);
|
||||
}
|
||||
|
||||
bool timer_fd::set_timeout_ns(long long to) {
|
||||
m_to_ns = to;
|
||||
struct itimerspec timer {};
|
||||
auto const sec = to / 1000000000LL;
|
||||
auto const nano = to % 1000000000LL;
|
||||
|
||||
timer.it_value.tv_sec = sec;
|
||||
timer.it_value.tv_nsec = nano;
|
||||
if (m_single_shot) {
|
||||
timer.it_interval.tv_sec = 0;
|
||||
timer.it_interval.tv_nsec = 0;
|
||||
} else {
|
||||
timer.it_interval.tv_sec = sec;
|
||||
timer.it_interval.tv_nsec = nano;
|
||||
}
|
||||
|
||||
return ::timerfd_settime(m_fd, 0, &timer, nullptr) == 0;
|
||||
}
|
||||
|
||||
} // namespace everest::lib::io::event
|
||||
53
tools/EVerest-main/lib/everest/io/src/event/unique_fd.cpp
Normal file
53
tools/EVerest-main/lib/everest/io/src/event/unique_fd.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/io/event/unique_fd.hpp>
|
||||
#include <unistd.h>
|
||||
#include <utility>
|
||||
|
||||
namespace everest::lib::io::event {
|
||||
|
||||
namespace {
|
||||
void close_descriptor_if_valid(int fd) {
|
||||
if (fd != unique_fd::NO_DESCRIPTOR_SENTINEL) {
|
||||
// NOTE (aw): according to the close(2) man page, close might return an error but it should not be retried
|
||||
::close(fd);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
unique_fd::unique_fd(int fd) : m_fd(fd){};
|
||||
|
||||
unique_fd::operator int() const {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
bool unique_fd::is_fd() const {
|
||||
return m_fd != NO_DESCRIPTOR_SENTINEL;
|
||||
}
|
||||
|
||||
int unique_fd::release() {
|
||||
return std::exchange(m_fd, NO_DESCRIPTOR_SENTINEL);
|
||||
}
|
||||
|
||||
void unique_fd::close() {
|
||||
close_descriptor_if_valid(m_fd);
|
||||
std::exchange(m_fd, NO_DESCRIPTOR_SENTINEL);
|
||||
}
|
||||
|
||||
unique_fd::unique_fd(unique_fd&& other) : m_fd(std::exchange(other.m_fd, NO_DESCRIPTOR_SENTINEL)) {
|
||||
}
|
||||
|
||||
unique_fd& unique_fd::operator=(unique_fd&& other) {
|
||||
if (this != &other) {
|
||||
close_descriptor_if_valid(m_fd);
|
||||
m_fd = std::exchange(other.m_fd, NO_DESCRIPTOR_SENTINEL);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
unique_fd::~unique_fd() {
|
||||
close_descriptor_if_valid(m_fd);
|
||||
}
|
||||
} // namespace everest::lib::io::event
|
||||
Reference in New Issue
Block a user