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
|
||||
{
|
||||
FifoWatcher(int fd, Buffer& buffer, bool scroll)
|
||||
: FDWatcher(fd, FdEvents::Read,
|
||||
: FDWatcher(fd, FdEvents::Read, EventMode::Normal,
|
||||
[](FDWatcher& watcher, FdEvents, EventMode mode) {
|
||||
if (mode == EventMode::Normal)
|
||||
static_cast<FifoWatcher&>(watcher).read_fifo();
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
namespace Kakoune
|
||||
{
|
||||
|
||||
FDWatcher::FDWatcher(int fd, FdEvents events, Callback callback)
|
||||
: m_fd{fd}, m_events{events}, m_callback{std::move(callback)}
|
||||
FDWatcher::FDWatcher(int fd, FdEvents events, EventMode mode, Callback callback)
|
||||
: m_fd{fd}, m_events{events}, m_mode{mode}, m_callback{std::move(callback)}
|
||||
{
|
||||
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);
|
||||
for (auto& watcher : m_fd_watchers)
|
||||
{
|
||||
if (watcher->mode() == EventMode::Normal and mode == EventMode::Urgent)
|
||||
continue;
|
||||
|
||||
const int fd = watcher->fd();
|
||||
if (fd != -1)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ class FDWatcher
|
|||
{
|
||||
public:
|
||||
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& operator=(const FDWatcher&) = delete;
|
||||
~FDWatcher();
|
||||
|
@ -42,6 +42,7 @@ public:
|
|||
int fd() const { return m_fd; }
|
||||
FdEvents events() const { return m_events; }
|
||||
FdEvents& events() { return m_events; }
|
||||
EventMode mode() const { return m_mode; }
|
||||
|
||||
void run(FdEvents events, EventMode mode);
|
||||
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
private:
|
||||
int m_fd;
|
||||
FdEvents m_events;
|
||||
EventMode m_mode;
|
||||
Callback m_callback;
|
||||
};
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ void rpc_call(StringView method, Args&&... args)
|
|||
}
|
||||
|
||||
JsonUI::JsonUI()
|
||||
: m_stdin_watcher{0, FdEvents::Read,
|
||||
: m_stdin_watcher{0, FdEvents::Read, EventMode::Urgent,
|
||||
[this](FDWatcher&, FdEvents, EventMode mode) {
|
||||
parse_requests(mode);
|
||||
}}, m_dimensions{24, 80}
|
||||
|
|
|
@ -327,7 +327,7 @@ static void signal_handler(int)
|
|||
|
||||
NCursesUI::NCursesUI()
|
||||
: m_cursor{CursorMode::Buffer, {}},
|
||||
m_stdin_watcher{STDIN_FILENO, FdEvents::Read,
|
||||
m_stdin_watcher{STDIN_FILENO, FdEvents::Read, EventMode::Urgent,
|
||||
[this](FDWatcher&, FdEvents, EventMode) {
|
||||
if (not m_on_key)
|
||||
return;
|
||||
|
|
|
@ -461,7 +461,7 @@ static bool send_data(int fd, RemoteBuffer& buffer, Optional<int> ancillary_fd =
|
|||
}
|
||||
|
||||
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) {
|
||||
const int sock = watcher.fd();
|
||||
try
|
||||
|
@ -663,7 +663,7 @@ RemoteClient::RemoteClient(StringView session, StringView name, std::unique_ptr<
|
|||
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 {
|
||||
const int sock = watcher.fd();
|
||||
if (events & FdEvents::Write and send_data(sock, m_send_buffer))
|
||||
|
@ -777,7 +777,7 @@ class Server::Accepter
|
|||
{
|
||||
public:
|
||||
Accepter(int socket)
|
||||
: m_socket_watcher(socket, FdEvents::Read,
|
||||
: m_socket_watcher(socket, FdEvents::Read, EventMode::Urgent,
|
||||
[this](FDWatcher&, FdEvents, EventMode 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_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)
|
||||
|
|
|
@ -167,7 +167,7 @@ Vector<String> generate_env(StringView cmdline, const Context& context, const Sh
|
|||
|
||||
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) {
|
||||
char buffer[1024];
|
||||
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);
|
||||
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 {
|
||||
while (fd_writable(pipe.write_fd()))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user