2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2018-07-17 01:06:24 -07:00
|
|
|
|
|
|
|
|
#include "wpi/uv/Poll.h"
|
|
|
|
|
|
|
|
|
|
#include "wpi/uv/Loop.h"
|
|
|
|
|
|
|
|
|
|
namespace wpi {
|
|
|
|
|
namespace uv {
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Poll> Poll::Create(Loop& loop, int fd) {
|
|
|
|
|
auto h = std::make_shared<Poll>(private_init{});
|
|
|
|
|
int err = uv_poll_init(loop.GetRaw(), h->GetRaw(), fd);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
loop.ReportError(err);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
h->Keep();
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Poll> Poll::CreateSocket(Loop& loop, uv_os_sock_t sock) {
|
|
|
|
|
auto h = std::make_shared<Poll>(private_init{});
|
|
|
|
|
int err = uv_poll_init_socket(loop.GetRaw(), h->GetRaw(), sock);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
loop.ReportError(err);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
h->Keep();
|
|
|
|
|
return h;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-05 23:04:33 -07:00
|
|
|
void Poll::Reuse(int fd, std::function<void()> callback) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (IsClosing()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!m_reuseData) {
|
|
|
|
|
m_reuseData = std::make_unique<ReuseData>();
|
|
|
|
|
}
|
2018-09-05 23:04:33 -07:00
|
|
|
m_reuseData->callback = callback;
|
|
|
|
|
m_reuseData->isSocket = false;
|
|
|
|
|
m_reuseData->fd = fd;
|
|
|
|
|
uv_close(GetRawHandle(), [](uv_handle_t* handle) {
|
|
|
|
|
Poll& h = *static_cast<Poll*>(handle->data);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (!h.m_reuseData || h.m_reuseData->isSocket) {
|
|
|
|
|
return; // just in case
|
|
|
|
|
}
|
2018-09-05 23:04:33 -07:00
|
|
|
auto data = std::move(h.m_reuseData);
|
|
|
|
|
int err = uv_poll_init(h.GetLoopRef().GetRaw(), h.GetRaw(), data->fd);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
h.ReportError(err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
data->callback();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Poll::ReuseSocket(uv_os_sock_t sock, std::function<void()> callback) {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (IsClosing()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!m_reuseData) {
|
|
|
|
|
m_reuseData = std::make_unique<ReuseData>();
|
|
|
|
|
}
|
2018-09-05 23:04:33 -07:00
|
|
|
m_reuseData->callback = callback;
|
|
|
|
|
m_reuseData->isSocket = true;
|
|
|
|
|
m_reuseData->sock = sock;
|
|
|
|
|
uv_close(GetRawHandle(), [](uv_handle_t* handle) {
|
|
|
|
|
Poll& h = *static_cast<Poll*>(handle->data);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (!h.m_reuseData || !h.m_reuseData->isSocket) {
|
|
|
|
|
return; // just in case
|
|
|
|
|
}
|
2018-09-05 23:04:33 -07:00
|
|
|
auto data = std::move(h.m_reuseData);
|
|
|
|
|
int err = uv_poll_init(h.GetLoopRef().GetRaw(), h.GetRaw(), data->sock);
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
h.ReportError(err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
data->callback();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-17 01:06:24 -07:00
|
|
|
void Poll::Start(int events) {
|
|
|
|
|
Invoke(&uv_poll_start, GetRaw(), events,
|
|
|
|
|
[](uv_poll_t* handle, int status, int events) {
|
|
|
|
|
Poll& h = *static_cast<Poll*>(handle->data);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (status < 0) {
|
2018-07-17 01:06:24 -07:00
|
|
|
h.ReportError(status);
|
2020-12-28 12:58:06 -08:00
|
|
|
} else {
|
2018-07-17 01:06:24 -07:00
|
|
|
h.pollEvent(events);
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
2018-07-17 01:06:24 -07:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace uv
|
|
|
|
|
} // namespace wpi
|