summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-11-30 13:59:08 +0000
committerMaxime Coste <mawww@kakoune.org>2016-12-01 19:44:07 +0000
commit7defdd30398826cca65b22810853a211b950c666 (patch)
tree7ba492354c307cec20979089a60e18809176c9d7 /src
parent99a3388e41a434a15a778f5e0e46202d3fa0e719 (diff)
Make FDWatcher support Read, Write and Except events, instead of just Read
Diffstat (limited to 'src')
-rw-r--r--src/buffer_utils.cc3
-rw-r--r--src/event_manager.cc32
-rw-r--r--src/event_manager.hh24
-rw-r--r--src/json_ui.cc3
-rw-r--r--src/ncurses_ui.cc3
-rw-r--r--src/remote.cc14
-rw-r--r--src/shell_manager.cc4
7 files changed, 57 insertions, 26 deletions
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index 735657e0..4ff1c1cf 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -114,7 +114,8 @@ Buffer* create_fifo_buffer(String name, int fd, bool scroll)
ValueId fifo_watcher_id = s_fifo_watcher_id;
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)
return;
diff --git a/src/event_manager.cc b/src/event_manager.cc
index d42f53c8..221a6d0d 100644
--- a/src/event_manager.cc
+++ b/src/event_manager.cc
@@ -7,8 +7,8 @@
namespace Kakoune
{
-FDWatcher::FDWatcher(int fd, Callback callback)
- : m_fd{fd}, m_callback{std::move(callback)}
+FDWatcher::FDWatcher(int fd, FdEvents events, Callback callback)
+ : m_fd{fd}, m_events{events}, m_callback{std::move(callback)}
{
EventManager::instance().m_fd_watchers.push_back(this);
}
@@ -18,9 +18,9 @@ FDWatcher::~FDWatcher()
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()
@@ -71,15 +71,21 @@ EventManager::~EventManager()
void EventManager::handle_next_events(EventMode mode, sigset_t* sigmask)
{
int max_fd = 0;
- fd_set rfds;
- FD_ZERO(&rfds);
+ fd_set rfds, wfds, efds;
+ FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
for (auto& watcher : m_fd_watchers)
{
const int fd = watcher->fd();
if (fd != -1)
{
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() };
}
}
- int res = pselect(max_fd + 1, &rfds, nullptr, nullptr,
+ int res = pselect(max_fd + 1, &rfds, &wfds, &efds,
with_timeout ? &ts : nullptr, sigmask);
// 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)
{
- 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,
[fd](const FDWatcher* w){return w->fd() == fd; });
if (it != m_fd_watchers.end())
- (*it)->run(mode);
+ (*it)->run(events, mode);
}
}
diff --git a/src/event_manager.hh b/src/event_manager.hh
index 5121b324..3d222f48 100644
--- a/src/event_manager.hh
+++ b/src/event_manager.hh
@@ -20,24 +20,38 @@ enum class EventMode
Urgent,
};
+enum class FdEvents
+{
+ None = 0,
+ Read = 1 << 0,
+ Write = 1 << 1,
+ Except = 1 << 2,
+};
+
+template<> struct WithBitOps<FdEvents> : std::true_type {};
+
class FDWatcher
{
public:
- using Callback = std::function<void (FDWatcher& watcher, EventMode mode)>;
- FDWatcher(int fd, Callback callback);
+ using Callback = std::function<void (FDWatcher& watcher, FdEvents events, EventMode mode)>;
+ FDWatcher(int fd, FdEvents events, Callback callback);
FDWatcher(const FDWatcher&) = delete;
FDWatcher& operator=(const FDWatcher&) = delete;
~FDWatcher();
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 disable() { m_fd = -1; }
private:
- int m_fd;
- Callback m_callback;
+ int m_fd;
+ FdEvents m_events;
+ Callback m_callback;
};
class Timer
diff --git a/src/json_ui.cc b/src/json_ui.cc
index 0a82e07e..95697d73 100644
--- a/src/json_ui.cc
+++ b/src/json_ui.cc
@@ -164,7 +164,8 @@ void rpc_call(StringView method, Args&&... args)
}
JsonUI::JsonUI()
- : m_stdin_watcher{0, [this](FDWatcher&, EventMode mode) {
+ : m_stdin_watcher{0, FdEvents::Read,
+ [this](FDWatcher&, FdEvents, EventMode mode) {
parse_requests(mode);
}}, m_dimensions{24, 80}
{
diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc
index 89aefcc0..64f9a82a 100644
--- a/src/ncurses_ui.cc
+++ b/src/ncurses_ui.cc
@@ -219,7 +219,8 @@ void on_term_resize(int)
}
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)
return;
diff --git a/src/remote.cc b/src/remote.cc
index 682971ef..7d44c2e5 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -345,7 +345,8 @@ private:
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();
try
{
@@ -506,7 +507,8 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
});
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();
while (fd_readable(sock) and not reader.ready())
reader.read_available(sock);
@@ -593,8 +595,8 @@ class Server::Accepter
{
public:
Accepter(int socket)
- : m_socket_watcher(socket,
- [this](FDWatcher&, EventMode mode) {
+ : m_socket_watcher(socket, FdEvents::Read,
+ [this](FDWatcher&, FdEvents, EventMode mode) {
if (mode == EventMode::Normal)
handle_available_input();
})
@@ -681,7 +683,7 @@ Server::Server(String session_name)
if (listen(listen_sock, 4) == -1)
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;
socklen_t client_addr_len = sizeof(sockaddr_un);
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_listener.reset(new FDWatcher{listen_sock, accepter});
+ m_listener.reset(new FDWatcher{listen_sock, FdEvents::Read, accepter});
}
bool Server::rename_session(StringView name)
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index 81df87ee..25cc2be6 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -158,8 +158,8 @@ std::pair<String, int> ShellManager::eval(
struct PipeReader : FDWatcher
{
PipeReader(Pipe& pipe, String& contents)
- : FDWatcher(pipe.read_fd(),
- [&contents, &pipe](FDWatcher& watcher, EventMode) {
+ : FDWatcher(pipe.read_fd(), FdEvents::Read,
+ [&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
char buffer[1024];
size_t size = ::read(pipe.read_fd(), buffer, 1024);
if (size <= 0)