#include "perfetto/base/build_config.h"
#include <errno.h>
#include <stdint.h>
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <synchapi.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/eventfd.h>
#include <unistd.h>
#else
#include <unistd.h>
#endif
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/event_fd.h"
#include "perfetto/ext/base/pipe.h"
#include "perfetto/ext/base/utils.h"
namespace perfetto {
namespace base {
EventFd::~EventFd() = default;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd::EventFd() {
event_handle_.reset(
CreateEventA(nullptr, true,
false, nullptr));
}
void EventFd::Notify() {
if (!SetEvent(event_handle_.get()))
PERFETTO_DFATAL("EventFd::Notify()");
}
void EventFd::Clear() {
if (!ResetEvent(event_handle_.get()))
PERFETTO_DFATAL("EventFd::Clear()");
}
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
EventFd::EventFd() { … }
void EventFd::Notify() { … }
void EventFd::Clear() { … }
#else
EventFd::EventFd() {
Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
write_fd_ = std::move(pipe.wr);
}
void EventFd::Notify() {
const uint64_t value = 1;
ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
if (ret <= 0 && errno != EAGAIN)
PERFETTO_DFATAL("EventFd::Notify()");
}
void EventFd::Clear() {
char buffer[16];
ssize_t ret =
PERFETTO_EINTR(read(event_handle_.get(), &buffer[0], sizeof(buffer)));
if (ret <= 0 && errno != EAGAIN)
PERFETTO_DFATAL("EventFd::Clear()");
}
#endif
}
}