From 560e3631ec57d34c679e6b0faec1e0efdd18d915 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 10 Aug 2024 11:26:26 +1000 Subject: Move debug utils to debug.hh/debug.cc Lots of code includes buffer_utils.hh just for write_to_debug_buffer which pulls many unnecessary dependencies. Reorganise to reduce compile times. --- src/shell_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/shell_manager.cc') diff --git a/src/shell_manager.cc b/src/shell_manager.cc index 47432df5..d08c4dbd 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -1,6 +1,6 @@ #include "shell_manager.hh" -#include "buffer_utils.hh" +#include "debug.hh" #include "client.hh" #include "clock.hh" #include "context.hh" -- cgit v1.2.3 From 01cb818c2077f5059bfa84834298bb813aa9baca Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 14 Aug 2024 22:04:35 +1000 Subject: Reduce number of included headers --- src/shell_manager.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/shell_manager.cc') diff --git a/src/shell_manager.cc b/src/shell_manager.cc index d08c4dbd..7346f2c1 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -10,7 +10,6 @@ #include "face_registry.hh" #include "file.hh" #include "flags.hh" -#include "option.hh" #include "option_types.hh" #include "regex.hh" @@ -118,7 +117,7 @@ Shell spawn_shell(const char* shell, StringView cmdline, if (pid_t pid = vfork()) return {pid, std::move(stdin_pipe[1]), std::move(stdout_pipe[0]), std::move(stderr_pipe[0])}; - auto renamefd = [](int oldfd, int newfd) { + constexpr auto renamefd = [](int oldfd, int newfd) { if (oldfd == newfd) return; dup2(oldfd, newfd); -- cgit v1.2.3 From 9275d965a6952d44035fd0502ee0d3991352c460 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 26 Aug 2024 21:00:08 +1000 Subject: Do not gather full input data in a single string when piping Refactor ShellManager and pipe to feed lines from the buffer directly, this should reduce memory use when piping big chunks of buffers. The pipe output is still provided as a single big buffer. --- src/shell_manager.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/shell_manager.cc') diff --git a/src/shell_manager.cc b/src/shell_manager.cc index 7346f2c1..6b656191 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -197,18 +197,22 @@ FDWatcher make_reader(int fd, String& contents, OnClose&& on_close) }}; } -FDWatcher make_pipe_writer(UniqueFd& fd, StringView contents) +FDWatcher make_pipe_writer(UniqueFd& fd, const FunctionRef& generator) { int flags = fcntl((int)fd, F_GETFL, 0); fcntl((int)fd, F_SETFL, flags | O_NONBLOCK); return {(int)fd, FdEvents::Write, EventMode::Urgent, - [contents, &fd](FDWatcher& watcher, FdEvents, EventMode) mutable { + [&generator, &fd, contents=generator()](FDWatcher& watcher, FdEvents, EventMode) mutable { while (fd_writable((int)fd)) { ssize_t size = ::write((int)fd, contents.begin(), (size_t)contents.length()); if (size > 0) + { contents = contents.substr(ByteCount{(int)size}); + if (contents.empty()) + contents = generator(); + } if (size == -1 and (errno == EAGAIN or errno == EWOULDBLOCK)) return; if (size < 0 or contents.empty()) @@ -263,7 +267,7 @@ struct CommandFifos } std::pair ShellManager::eval( - StringView cmdline, const Context& context, StringView input, + StringView cmdline, const Context& context, FunctionRef input_generator, Flags flags, const ShellContext& shell_context) { const DebugFlags debug_flags = context.options()["debug"].get(); @@ -290,13 +294,13 @@ std::pair ShellManager::eval( }); auto spawn_time = profile ? Clock::now() : Clock::time_point{}; - auto shell = spawn_shell(m_shell.c_str(), cmdline, shell_context.params, kak_env, not input.empty()); + auto shell = spawn_shell(m_shell.c_str(), cmdline, shell_context.params, kak_env, true); auto wait_time = Clock::now(); String stdout_contents, stderr_contents; auto stdout_reader = make_reader((int)shell.out, stdout_contents, [&](bool){ shell.out.close(); }); auto stderr_reader = make_reader((int)shell.err, stderr_contents, [&](bool){ shell.err.close(); }); - auto stdin_writer = make_pipe_writer(shell.in, input); + auto stdin_writer = make_pipe_writer(shell.in, input_generator); // block SIGCHLD to make sure we wont receive it before // our call to pselect, that will end up blocking indefinitly. -- cgit v1.2.3 From 7105584538f84d1c244809601fd3e573e8d6080c Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 24 Nov 2024 10:19:32 +0100 Subject: Print elapsed time when blocked on opening file for writing Extract the logic for "waiting for shell to finish" and reuse it for potentially blocking calls to open() that use the O_WRONLY flags. --- src/shell_manager.cc | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) (limited to 'src/shell_manager.cc') diff --git a/src/shell_manager.cc b/src/shell_manager.cc index 6b656191..0baf77c8 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -14,6 +14,7 @@ #include "regex.hh" #include +#include #include #include #include @@ -316,24 +317,11 @@ std::pair ShellManager::eval( bool failed = false; using namespace std::chrono; - static constexpr seconds wait_timeout{1}; - Optional previous_status; - Timer wait_timer{wait_time + wait_timeout, [&](Timer& timer) { - if (not context.has_client()) - return; - - const auto now = Clock::now(); - timer.set_next_date(now + wait_timeout); - auto& client = context.client(); - if (not previous_status) - previous_status = client.current_status(); - - client.print_status({format("waiting for shell command to finish{} ({}s)", - terminated ? " (shell terminated)" : "", - duration_cast(now - wait_time).count()), - context.faces()[failed ? "Error" : "Information"]}); - client.redraw_ifn(); - }, EventMode::Urgent}; + BusyIndicator busy_indicator{context, [&](seconds elapsed) { + return DisplayLine{format("waiting for shell command to finish{} ({}s)", + terminated ? " (shell terminated)" : "", elapsed.count()), + context.faces()[failed ? "Error" : "Information"]}; + }}; bool cancelling = false; while (not terminated or shell.in or @@ -373,12 +361,6 @@ std::pair ShellManager::eval( if (cancelling) throw cancel{}; - if (previous_status) // restore the status line - { - context.print_status(std::move(*previous_status)); - context.client().redraw_ifn(); - } - return { std::move(stdout_contents), WIFEXITED(status) ? WEXITSTATUS(status) : -1 }; } -- cgit v1.2.3