forked from lix-project/lix
Merge changes I8456c47b,I48253f5f into main
* changes: repl: clear the interrupt before reading the next line libutil: remove the interrupt-blocking code
This commit is contained in:
commit
0903a99bad
8
doc/manual/rl-next/repl-interrupt.md
Normal file
8
doc/manual/rl-next/repl-interrupt.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
synopsis: Interrupting builds in the REPL works more than once
|
||||||
|
cls: 1097
|
||||||
|
---
|
||||||
|
|
||||||
|
Builds in the REPL can be interrupted by pressing Ctrl+C.
|
||||||
|
Previously, this only worked once per REPL session; further attempts would be ignored.
|
||||||
|
This issue is now fixed, so that builds can be canceled consistently.
|
|
@ -262,6 +262,8 @@ ReplExitStatus NixRepl::mainLoop()
|
||||||
std::string input;
|
std::string input;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
_isInterrupted = false;
|
||||||
|
|
||||||
// When continuing input from previous lines, don't print a prompt, just align to the same
|
// When continuing input from previous lines, don't print a prompt, just align to the same
|
||||||
// number of chars as the prompt.
|
// number of chars as the prompt.
|
||||||
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
|
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
|
||||||
|
@ -424,8 +426,6 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
||||||
if (line.empty())
|
if (line.empty())
|
||||||
return ProcessLineResult::PromptAgain;
|
return ProcessLineResult::PromptAgain;
|
||||||
|
|
||||||
_isInterrupted = false;
|
|
||||||
|
|
||||||
std::string command, arg;
|
std::string command, arg;
|
||||||
|
|
||||||
if (line[0] == ':') {
|
if (line[0] == ':') {
|
||||||
|
|
|
@ -319,17 +319,8 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
|
||||||
ErrorInfo::programName = baseNameOf(programName);
|
ErrorInfo::programName = baseNameOf(programName);
|
||||||
|
|
||||||
std::string error = ANSI_RED "error:" ANSI_NORMAL " ";
|
std::string error = ANSI_RED "error:" ANSI_NORMAL " ";
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
fun();
|
fun();
|
||||||
} catch (...) {
|
|
||||||
/* Subtle: we have to make sure that any `interrupted'
|
|
||||||
condition is discharged before we reach printMsg()
|
|
||||||
below, since otherwise it will throw an (uncaught)
|
|
||||||
exception. */
|
|
||||||
setInterruptThrown();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
} catch (Exit & e) {
|
} catch (Exit & e) {
|
||||||
return e.status;
|
return e.status;
|
||||||
} catch (UsageError & e) {
|
} catch (UsageError & e) {
|
||||||
|
|
|
@ -9,21 +9,14 @@ namespace nix {
|
||||||
|
|
||||||
std::atomic<bool> _isInterrupted = false;
|
std::atomic<bool> _isInterrupted = false;
|
||||||
|
|
||||||
static thread_local bool interruptThrown = false;
|
|
||||||
thread_local std::function<bool()> interruptCheck;
|
thread_local std::function<bool()> interruptCheck;
|
||||||
|
|
||||||
void setInterruptThrown()
|
|
||||||
{
|
|
||||||
interruptThrown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _interrupted()
|
void _interrupted()
|
||||||
{
|
{
|
||||||
/* Block user interrupts while an exception is being handled.
|
/* Block user interrupts while an exception is being handled.
|
||||||
Throwing an exception while another exception is being handled
|
Throwing an exception while another exception is being handled
|
||||||
kills the program! */
|
kills the program! */
|
||||||
if (!interruptThrown && !std::uncaught_exceptions()) {
|
if (!std::uncaught_exceptions()) {
|
||||||
interruptThrown = true;
|
|
||||||
throw Interrupted("interrupted by the user");
|
throw Interrupted("interrupted by the user");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ extern std::atomic<bool> _isInterrupted;
|
||||||
|
|
||||||
extern thread_local std::function<bool()> interruptCheck;
|
extern thread_local std::function<bool()> interruptCheck;
|
||||||
|
|
||||||
void setInterruptThrown();
|
|
||||||
|
|
||||||
void _interrupted();
|
void _interrupted();
|
||||||
|
|
||||||
void inline checkInterrupt()
|
void inline checkInterrupt()
|
||||||
|
|
Loading…
Reference in a new issue