Do not select on non-urgent fd when handling only urgent events
This avoids 100% CPU usage when we have pending fifo input while running a shell process, as we will not end-up busy looping in pselect but not reading the available data due to being only processing urgent events.
This commit is contained in:
parent
c12d1c16b7
commit
4a59018dcd
|
@ -133,7 +133,7 @@ Buffer* create_fifo_buffer(String name, int fd, Buffer::Flags flags, bool scroll
|
||||||
struct FifoWatcher : FDWatcher
|
struct FifoWatcher : FDWatcher
|
||||||
{
|
{
|
||||||
FifoWatcher(int fd, Buffer& buffer, bool scroll)
|
FifoWatcher(int fd, Buffer& buffer, bool scroll)
|
||||||
: FDWatcher(fd, FdEvents::Read,
|
: FDWatcher(fd, FdEvents::Read, EventMode::Normal,
|
||||||
[](FDWatcher& watcher, FdEvents, EventMode mode) {
|
[](FDWatcher& watcher, FdEvents, EventMode mode) {
|
||||||
if (mode == EventMode::Normal)
|
if (mode == EventMode::Normal)
|
||||||
static_cast<FifoWatcher&>(watcher).read_fifo();
|
static_cast<FifoWatcher&>(watcher).read_fifo();
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
FDWatcher::FDWatcher(int fd, FdEvents events, Callback callback)
|
FDWatcher::FDWatcher(int fd, FdEvents events, EventMode mode, Callback callback)
|
||||||
: m_fd{fd}, m_events{events}, m_callback{std::move(callback)}
|
: m_fd{fd}, m_events{events}, m_mode{mode}, m_callback{std::move(callback)}
|
||||||
{
|
{
|
||||||
EventManager::instance().m_fd_watchers.push_back(this);
|
EventManager::instance().m_fd_watchers.push_back(this);
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,9 @@ bool EventManager::handle_next_events(EventMode mode, sigset_t* sigmask, bool bl
|
||||||
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
|
||||||
for (auto& watcher : m_fd_watchers)
|
for (auto& watcher : m_fd_watchers)
|
||||||
{
|
{
|
||||||
|
if (watcher->mode() == EventMode::Normal and mode == EventMode::Urgent)
|
||||||
|
continue;
|
||||||
|
|
||||||
const int fd = watcher->fd();
|
const int fd = watcher->fd();
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,7 @@ class FDWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Callback = std::function<void (FDWatcher& watcher, FdEvents events, EventMode mode)>;
|
using Callback = std::function<void (FDWatcher& watcher, FdEvents events, EventMode mode)>;
|
||||||
FDWatcher(int fd, FdEvents events, Callback callback);
|
FDWatcher(int fd, FdEvents events, EventMode mode, Callback callback);
|
||||||
FDWatcher(const FDWatcher&) = delete;
|
FDWatcher(const FDWatcher&) = delete;
|
||||||
FDWatcher& operator=(const FDWatcher&) = delete;
|
FDWatcher& operator=(const FDWatcher&) = delete;
|
||||||
~FDWatcher();
|
~FDWatcher();
|
||||||
|
@ -42,6 +42,7 @@ public:
|
||||||
int fd() const { return m_fd; }
|
int fd() const { return m_fd; }
|
||||||
FdEvents events() const { return m_events; }
|
FdEvents events() const { return m_events; }
|
||||||
FdEvents& events() { return m_events; }
|
FdEvents& events() { return m_events; }
|
||||||
|
EventMode mode() const { return m_mode; }
|
||||||
|
|
||||||
void run(FdEvents events, EventMode mode);
|
void run(FdEvents events, EventMode mode);
|
||||||
|
|
||||||
|
@ -51,6 +52,7 @@ public:
|
||||||
private:
|
private:
|
||||||
int m_fd;
|
int m_fd;
|
||||||
FdEvents m_events;
|
FdEvents m_events;
|
||||||
|
EventMode m_mode;
|
||||||
Callback m_callback;
|
Callback m_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ void rpc_call(StringView method, Args&&... args)
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonUI::JsonUI()
|
JsonUI::JsonUI()
|
||||||
: m_stdin_watcher{0, FdEvents::Read,
|
: m_stdin_watcher{0, FdEvents::Read, EventMode::Urgent,
|
||||||
[this](FDWatcher&, FdEvents, EventMode mode) {
|
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||||
parse_requests(mode);
|
parse_requests(mode);
|
||||||
}}, m_dimensions{24, 80}
|
}}, m_dimensions{24, 80}
|
||||||
|
|
|
@ -327,7 +327,7 @@ static void signal_handler(int)
|
||||||
|
|
||||||
NCursesUI::NCursesUI()
|
NCursesUI::NCursesUI()
|
||||||
: m_cursor{CursorMode::Buffer, {}},
|
: m_cursor{CursorMode::Buffer, {}},
|
||||||
m_stdin_watcher{STDIN_FILENO, FdEvents::Read,
|
m_stdin_watcher{STDIN_FILENO, FdEvents::Read, EventMode::Urgent,
|
||||||
[this](FDWatcher&, FdEvents, EventMode) {
|
[this](FDWatcher&, FdEvents, EventMode) {
|
||||||
if (not m_on_key)
|
if (not m_on_key)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -461,7 +461,7 @@ static bool send_data(int fd, RemoteBuffer& buffer, Optional<int> ancillary_fd =
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteUI::RemoteUI(int socket, DisplayCoord dimensions)
|
RemoteUI::RemoteUI(int socket, DisplayCoord dimensions)
|
||||||
: m_socket_watcher(socket, FdEvents::Read | FdEvents::Write,
|
: m_socket_watcher(socket, FdEvents::Read | FdEvents::Write, EventMode::Urgent,
|
||||||
[this](FDWatcher& watcher, FdEvents events, EventMode) {
|
[this](FDWatcher& watcher, FdEvents events, EventMode) {
|
||||||
const int sock = watcher.fd();
|
const int sock = watcher.fd();
|
||||||
try
|
try
|
||||||
|
@ -663,7 +663,7 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
|
||||||
m_socket_watcher->events() |= FdEvents::Write;
|
m_socket_watcher->events() |= FdEvents::Write;
|
||||||
});
|
});
|
||||||
|
|
||||||
m_socket_watcher.reset(new FDWatcher{sock, FdEvents::Read | FdEvents::Write,
|
m_socket_watcher.reset(new FDWatcher{sock, FdEvents::Read | FdEvents::Write, EventMode::Urgent,
|
||||||
[this, reader = MsgReader{}](FDWatcher& watcher, FdEvents events, EventMode) mutable {
|
[this, reader = MsgReader{}](FDWatcher& watcher, FdEvents events, EventMode) mutable {
|
||||||
const int sock = watcher.fd();
|
const int sock = watcher.fd();
|
||||||
if (events & FdEvents::Write and send_data(sock, m_send_buffer))
|
if (events & FdEvents::Write and send_data(sock, m_send_buffer))
|
||||||
|
@ -777,7 +777,7 @@ class Server::Accepter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Accepter(int socket)
|
Accepter(int socket)
|
||||||
: m_socket_watcher(socket, FdEvents::Read,
|
: m_socket_watcher(socket, FdEvents::Read, EventMode::Urgent,
|
||||||
[this](FDWatcher&, FdEvents, EventMode mode) {
|
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||||
handle_available_input(mode);
|
handle_available_input(mode);
|
||||||
})
|
})
|
||||||
|
@ -888,7 +888,7 @@ Server::Server(String session_name, bool is_daemon)
|
||||||
|
|
||||||
m_accepters.emplace_back(new Accepter{sock});
|
m_accepters.emplace_back(new Accepter{sock});
|
||||||
};
|
};
|
||||||
m_listener.reset(new FDWatcher{listen_sock, FdEvents::Read, accepter});
|
m_listener.reset(new FDWatcher{listen_sock, FdEvents::Read, EventMode::Urgent, accepter});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Server::rename_session(StringView name)
|
bool Server::rename_session(StringView name)
|
||||||
|
|
|
@ -167,7 +167,7 @@ Vector<String> generate_env(StringView cmdline, const Context& context, const Sh
|
||||||
|
|
||||||
FDWatcher make_pipe_reader(Pipe& pipe, String& contents)
|
FDWatcher make_pipe_reader(Pipe& pipe, String& contents)
|
||||||
{
|
{
|
||||||
return {pipe.read_fd(), FdEvents::Read,
|
return {pipe.read_fd(), FdEvents::Read, EventMode::Urgent,
|
||||||
[&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
|
[&contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
while (fd_readable(pipe.read_fd()))
|
while (fd_readable(pipe.read_fd()))
|
||||||
|
@ -188,7 +188,7 @@ FDWatcher make_pipe_writer(Pipe& pipe, StringView contents)
|
||||||
{
|
{
|
||||||
int flags = fcntl(pipe.write_fd(), F_GETFL, 0);
|
int flags = fcntl(pipe.write_fd(), F_GETFL, 0);
|
||||||
fcntl(pipe.write_fd(), F_SETFL, flags | O_NONBLOCK);
|
fcntl(pipe.write_fd(), F_SETFL, flags | O_NONBLOCK);
|
||||||
return {pipe.write_fd(), FdEvents::Write,
|
return {pipe.write_fd(), FdEvents::Write, EventMode::Urgent,
|
||||||
[contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) mutable {
|
[contents, &pipe](FDWatcher& watcher, FdEvents, EventMode) mutable {
|
||||||
while (fd_writable(pipe.write_fd()))
|
while (fd_writable(pipe.write_fd()))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user