Make FDWatcher support Read, Write and Except events, instead of just Read
This commit is contained in:
parent
99a3388e41
commit
7defdd3039
|
@ -114,7 +114,8 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll)
|
||||||
ValueId fifo_watcher_id = s_fifo_watcher_id;
|
ValueId fifo_watcher_id = s_fifo_watcher_id;
|
||||||
|
|
||||||
std::unique_ptr<FDWatcher, decltype(watcher_deleter)> watcher(
|
std::unique_ptr<FDWatcher, decltype(watcher_deleter)> watcher(
|
||||||
new FDWatcher(fd, [buffer, scroll, fifo_watcher_id](FDWatcher& watcher, EventMode mode) {
|
new FDWatcher(fd, FdEvents::Read,
|
||||||
|
[buffer, scroll, fifo_watcher_id](FDWatcher& watcher, FdEvents, EventMode mode) {
|
||||||
if (mode != EventMode::Normal)
|
if (mode != EventMode::Normal)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
FDWatcher::FDWatcher(int fd, Callback callback)
|
FDWatcher::FDWatcher(int fd, FdEvents events, Callback callback)
|
||||||
: m_fd{fd}, m_callback{std::move(callback)}
|
: m_fd{fd}, m_events{events}, m_callback{std::move(callback)}
|
||||||
{
|
{
|
||||||
EventManager::instance().m_fd_watchers.push_back(this);
|
EventManager::instance().m_fd_watchers.push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ FDWatcher::~FDWatcher()
|
||||||
unordered_erase(EventManager::instance().m_fd_watchers, this);
|
unordered_erase(EventManager::instance().m_fd_watchers, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FDWatcher::run(EventMode mode)
|
void FDWatcher::run(FdEvents events, EventMode mode)
|
||||||
{
|
{
|
||||||
m_callback(*this, mode);
|
m_callback(*this, events, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FDWatcher::close_fd()
|
void FDWatcher::close_fd()
|
||||||
|
@ -71,15 +71,21 @@ EventManager::~EventManager()
|
||||||
void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask)
|
void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask)
|
||||||
{
|
{
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
fd_set rfds;
|
fd_set rfds, wfds, efds;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
||||||
for (auto& watcher : m_fd_watchers)
|
for (auto& watcher : m_fd_watchers)
|
||||||
{
|
{
|
||||||
const int fd = watcher->fd();
|
const int fd = watcher->fd();
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
max_fd = std::max(fd, max_fd);
|
max_fd = std::max(fd, max_fd);
|
||||||
FD_SET(fd, &rfds);
|
auto events = watcher->events();
|
||||||
|
if (events & FdEvents::Read)
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
if (events & FdEvents::Write)
|
||||||
|
FD_SET(fd, &wfds);
|
||||||
|
if (events & FdEvents::Except)
|
||||||
|
FD_SET(fd, &efds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +107,7 @@ void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask)
|
||||||
ts = timespec{ (time_t)secs.count(), (long)(nsecs - secs).count() };
|
ts = timespec{ (time_t)secs.count(), (long)(nsecs - secs).count() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int res = pselect(max_fd + 1, &rfds, nullptr, nullptr,
|
int res = pselect(max_fd + 1, &rfds, &wfds, &efds,
|
||||||
with_timeout ? &ts : nullptr, sigmask);
|
with_timeout ? &ts : nullptr, sigmask);
|
||||||
|
|
||||||
// copy forced fds *after* select, so that signal handlers can write to
|
// copy forced fds *after* select, so that signal handlers can write to
|
||||||
|
@ -111,12 +117,18 @@ void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask)
|
||||||
|
|
||||||
for (int fd = 0; fd < max_fd + 1; ++fd)
|
for (int fd = 0; fd < max_fd + 1; ++fd)
|
||||||
{
|
{
|
||||||
if ((res > 0 and FD_ISSET(fd, &rfds)) or FD_ISSET(fd, &forced))
|
auto events = FD_ISSET(fd, &forced) ? FdEvents::Read : FdEvents::None;
|
||||||
|
if (res > 0)
|
||||||
|
events |= (FD_ISSET(fd, &rfds) ? FdEvents::Read : FdEvents::None) |
|
||||||
|
(FD_ISSET(fd, &wfds) ? FdEvents::Write : FdEvents::None) |
|
||||||
|
(FD_ISSET(fd, &efds) ? FdEvents::Except : FdEvents::None);
|
||||||
|
|
||||||
|
if (events != FdEvents::None)
|
||||||
{
|
{
|
||||||
auto it = find_if(m_fd_watchers,
|
auto it = find_if(m_fd_watchers,
|
||||||
[fd](const FDWatcher* w){return w->fd() == fd; });
|
[fd](const FDWatcher* w){return w->fd() == fd; });
|
||||||
if (it != m_fd_watchers.end())
|
if (it != m_fd_watchers.end())
|
||||||
(*it)->run(mode);
|
(*it)->run(events, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,24 +20,38 @@ enum class EventMode
|
||||||
Urgent,
|
Urgent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FdEvents
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Read = 1 << 0,
|
||||||
|
Write = 1 << 1,
|
||||||
|
Except = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct WithBitOps<FdEvents> : std::true_type {};
|
||||||
|
|
||||||
class FDWatcher
|
class FDWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Callback = std::function<void (FDWatcher& watcher, EventMode mode)>;
|
using Callback = std::function<void (FDWatcher& watcher, FdEvents events, EventMode mode)>;
|
||||||
FDWatcher(int fd, Callback callback);
|
FDWatcher(int fd, FdEvents events, Callback callback);
|
||||||
FDWatcher(const FDWatcher&) = delete;
|
FDWatcher(const FDWatcher&) = delete;
|
||||||
FDWatcher& operator=(const FDWatcher&) = delete;
|
FDWatcher& operator=(const FDWatcher&) = delete;
|
||||||
~FDWatcher();
|
~FDWatcher();
|
||||||
|
|
||||||
int fd() const { return m_fd; }
|
int fd() const { return m_fd; }
|
||||||
void run(EventMode mode);
|
FdEvents events() const { return m_events; }
|
||||||
|
FdEvents& events() { return m_events; }
|
||||||
|
|
||||||
|
void run(FdEvents events, EventMode mode);
|
||||||
|
|
||||||
void close_fd();
|
void close_fd();
|
||||||
void disable() { m_fd = -1; }
|
void disable() { m_fd = -1; }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int m_fd;
|
int m_fd;
|
||||||
Callback m_callback;
|
FdEvents m_events;
|
||||||
|
Callback m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Timer
|
class Timer
|
||||||
|
|
|
@ -164,7 +164,8 @@ void rpc_call(StringView method, Args&&... args)
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonUI::JsonUI()
|
JsonUI::JsonUI()
|
||||||
: m_stdin_watcher{0, [this](FDWatcher&, EventMode mode) {
|
: m_stdin_watcher{0, FdEvents::Read,
|
||||||
|
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||||
parse_requests(mode);
|
parse_requests(mode);
|
||||||
}}, m_dimensions{24, 80}
|
}}, m_dimensions{24, 80}
|
||||||
{
|
{
|
||||||
|
|
|
@ -219,7 +219,8 @@ void on_term_resize(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
NCursesUI::NCursesUI()
|
NCursesUI::NCursesUI()
|
||||||
: m_stdin_watcher{0, [this](FDWatcher&, EventMode mode) {
|
: m_stdin_watcher{0, FdEvents::Read,
|
||||||
|
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||||
if (not m_on_key)
|
if (not m_on_key)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,8 @@ private:
|
||||||
|
|
||||||
|
|
||||||
RemoteUI::RemoteUI(int socket, DisplayCoord dimensions)
|
RemoteUI::RemoteUI(int socket, DisplayCoord dimensions)
|
||||||
: m_socket_watcher(socket, [this](FDWatcher& watcher, EventMode mode) {
|
: m_socket_watcher(socket, FdEvents::Read,
|
||||||
|
[this](FDWatcher& watcher, FdEvents, EventMode mode) {
|
||||||
const int sock = watcher.fd();
|
const int sock = watcher.fd();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -506,7 +507,8 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
|
||||||
});
|
});
|
||||||
|
|
||||||
MsgReader reader;
|
MsgReader reader;
|
||||||
m_socket_watcher.reset(new FDWatcher{sock, [this, reader](FDWatcher& watcher, EventMode) mutable {
|
m_socket_watcher.reset(new FDWatcher{sock, FdEvents::Read,
|
||||||
|
[this, reader](FDWatcher& watcher, FdEvents, EventMode) mutable {
|
||||||
const int sock = watcher.fd();
|
const int sock = watcher.fd();
|
||||||
while (fd_readable(sock) and not reader.ready())
|
while (fd_readable(sock) and not reader.ready())
|
||||||
reader.read_available(sock);
|
reader.read_available(sock);
|
||||||
|
@ -593,8 +595,8 @@ class Server::Accepter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Accepter(int socket)
|
Accepter(int socket)
|
||||||
: m_socket_watcher(socket,
|
: m_socket_watcher(socket, FdEvents::Read,
|
||||||
[this](FDWatcher&, EventMode mode) {
|
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||||
if (mode == EventMode::Normal)
|
if (mode == EventMode::Normal)
|
||||||
handle_available_input();
|
handle_available_input();
|
||||||
})
|
})
|
||||||
|
@ -681,7 +683,7 @@ Server::Server(String session_name)
|
||||||
if (listen(listen_sock, 4) == -1)
|
if (listen(listen_sock, 4) == -1)
|
||||||
throw runtime_error(format("unable to listen on socket '{}'", addr.sun_path));
|
throw runtime_error(format("unable to listen on socket '{}'", addr.sun_path));
|
||||||
|
|
||||||
auto accepter = [this](FDWatcher& watcher, EventMode mode) {
|
auto accepter = [this](FDWatcher& watcher, FdEvents, EventMode mode) {
|
||||||
sockaddr_un client_addr;
|
sockaddr_un client_addr;
|
||||||
socklen_t client_addr_len = sizeof(sockaddr_un);
|
socklen_t client_addr_len = sizeof(sockaddr_un);
|
||||||
int sock = accept(watcher.fd(), (sockaddr*) &client_addr,
|
int sock = accept(watcher.fd(), (sockaddr*) &client_addr,
|
||||||
|
@ -692,7 +694,7 @@ Server::Server(String session_name)
|
||||||
|
|
||||||
m_accepters.emplace_back(new Accepter{sock});
|
m_accepters.emplace_back(new Accepter{sock});
|
||||||
};
|
};
|
||||||
m_listener.reset(new FDWatcher{listen_sock, accepter});
|
m_listener.reset(new FDWatcher{listen_sock, FdEvents::Read, accepter});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::rename_session(StringView name)
|
bool Server::rename_session(StringView name)
|
||||||
|
|
|
@ -158,8 +158,8 @@ std::pair<String, int> ShellManager::eval(
|
||||||
struct PipeReader : FDWatcher
|
struct PipeReader : FDWatcher
|
||||||
{
|
{
|
||||||
PipeReader(Pipe& pipe, String& contents)
|
PipeReader(Pipe& pipe, String& contents)
|
||||||
: FDWatcher(pipe.read_fd(),
|
: FDWatcher(pipe.read_fd(), FdEvents::Read,
|
||||||
[&contents, &pipe](FDWatcher& watcher, EventMode) {
|
[&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t size = ::read(pipe.read_fd(), buffer, 1024);
|
size_t size = ::read(pipe.read_fd(), buffer, 1024);
|
||||||
if (size <= 0)
|
if (size <= 0)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user