Skip to content

Commit 30694b5

Browse files
committed
refactor: RAII logger suspension
1 parent 8804890 commit 30694b5

File tree

7 files changed

+46
-35
lines changed

7 files changed

+46
-35
lines changed

src/libcmd/repl.cc

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ struct NixRepl
102102
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
103103
{
104104
// Hide the progress bar during printing because it might interfere
105-
logger->pause();
106-
Finally resumeLoggerDefer([]() { logger->resume(); });
105+
auto suspension = logger->suspend();
107106
::nix::printValue(*state, str, v, PrintOptions {
108107
.ansiColors = true,
109108
.force = true,
@@ -180,18 +179,20 @@ ReplExitStatus NixRepl::mainLoop()
180179

181180
while (true) {
182181
// Hide the progress bar while waiting for user input, so that it won't interfere.
183-
logger->pause();
184-
// When continuing input from previous lines, don't print a prompt, just align to the same
185-
// number of chars as the prompt.
186-
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
187-
// Ctrl-D should exit the debugger.
188-
state->debugStop = false;
189-
logger->cout("");
190-
// TODO: Should Ctrl-D exit just the current debugger session or
191-
// the entire program?
192-
return ReplExitStatus::QuitAll;
182+
{
183+
auto suspension = logger->suspend();
184+
// When continuing input from previous lines, don't print a prompt, just align to the same
185+
// number of chars as the prompt.
186+
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
187+
// Ctrl-D should exit the debugger.
188+
state->debugStop = false;
189+
logger->cout("");
190+
// TODO: Should Ctrl-D exit just the current debugger session or
191+
// the entire program?
192+
return ReplExitStatus::QuitAll;
193+
}
194+
// `suspension` resumes the logger
193195
}
194-
logger->resume();
195196
try {
196197
switch (processLine(input)) {
197198
case ProcessLineResult::Quit:
@@ -694,10 +695,9 @@ ProcessLineResult NixRepl::processLine(std::string line)
694695
} else {
695696
Value v;
696697
evalString(line, v);
697-
logger->pause();
698+
auto suspension = logger->suspend();
698699
printValue(std::cout, v, 1);
699700
std::cout << std::endl;
700-
logger->resume();
701701
}
702702
}
703703

src/libfetchers/git.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,7 @@ struct GitInputScheme : InputScheme
351351

352352
if (commitMsg) {
353353
// Pause the logger to allow for user input (such as a gpg passphrase) in `git commit`
354-
logger->pause();
355-
Finally restoreLogger([]() { logger->resume(); });
354+
auto suspension = logger->suspend();
356355
runProgram("git", true,
357356
{ "-C", repoPath->string(), "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-F", "-" },
358357
*commitMsg);

src/libstore/ssh.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
117117
ProcessOptions options;
118118
options.dieWithParent = false;
119119

120+
std::unique_ptr<Logger::Suspension> loggerSuspension;
120121
if (!fakeSSH && !useMaster) {
121-
logger->pause();
122+
loggerSuspension = std::make_unique<Logger::Suspension>(logger->suspend());
122123
}
123-
Finally cleanup = [&]() { logger->resume(); };
124124

125125
conn->sshPid = startProcess([&]() {
126126
restoreProcessContext();
@@ -199,8 +199,7 @@ Path SSHMaster::startMaster()
199199
ProcessOptions options;
200200
options.dieWithParent = false;
201201

202-
logger->pause();
203-
Finally cleanup = [&]() { logger->resume(); };
202+
auto suspension = logger->suspend();
204203

205204
if (isMasterRunning())
206205
return state->socketPath;

src/libutil/logging.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ void Logger::writeToStdout(std::string_view s)
4343
writeFull(standard_out, "\n");
4444
}
4545

46+
Logger::Suspension Logger::suspend()
47+
{
48+
pause();
49+
return Suspension { ._finalize = {[this](){this->resume();}} };
50+
}
51+
52+
std::optional<Logger::Suspension> Logger::suspendIf(bool cond)
53+
{
54+
if (cond)
55+
return suspend();
56+
return {};
57+
}
58+
4659
class SimpleLogger : public Logger
4760
{
4861
public:

src/libutil/logging.hh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "error.hh"
55
#include "config.hh"
66
#include "file-descriptor.hh"
7+
#include "finally.hh"
78

89
#include <nlohmann/json_fwd.hpp>
910

@@ -75,6 +76,17 @@ public:
7576

7677
virtual void stop() { };
7778

79+
/**
80+
* Guard object to resume the logger when done.
81+
*/
82+
struct Suspension {
83+
Finally<std::function<void()>> _finalize;
84+
};
85+
86+
Suspension suspend();
87+
88+
std::optional<Suspension> suspendIf(bool cond);
89+
7890
virtual void pause() { };
7991
virtual void resume() { };
8092

src/libutil/unix/processes.cc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,7 @@ void runProgram2(const RunOptions & options)
306306
// case), so we can't use it if we alter the environment
307307
processOptions.allowVfork = !options.environment;
308308

309-
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
310-
if (options.isInteractive) {
311-
logger->pause();
312-
resumeLoggerDefer.emplace(
313-
[]() {
314-
logger->resume();
315-
}
316-
);
317-
}
309+
auto suspension = logger->suspendIf(options.isInteractive);
318310

319311
/* Fork. */
320312
Pid pid = startProcess([&] {

src/libutil/windows/processes.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,7 @@ void runProgram2(const RunOptions & options)
312312
// TODO: Implement shebang / program interpreter lookup on Windows
313313
auto interpreter = getProgramInterpreter(realProgram);
314314

315-
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
316-
if (options.isInteractive) {
317-
logger->pause();
318-
resumeLoggerDefer.emplace([]() { logger->resume(); });
319-
}
315+
auto suspension = logger->suspendIf(options.isInteractive);
320316

321317
Pid pid = spawnProcess(interpreter.has_value() ? *interpreter : realProgram, options, out, in);
322318

0 commit comments

Comments
 (0)