1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-05 12:21:48 +02:00

Merge pull request #11618 from NixOS/ignoreException-interrupt

Split ignoreException for destructors vs interrupt-safe
This commit is contained in:
Eelco Dolstra 2024-10-01 17:10:39 +02:00 committed by GitHub
commit 3e7b42dd89
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 164 additions and 125 deletions

View file

@ -45,7 +45,7 @@ unsigned int getMaxCPU()
auto period = cpuMaxParts[1];
if (quota != "max")
return std::ceil(std::stoi(quota) / std::stof(period));
} catch (Error &) { ignoreException(lvlDebug); }
} catch (Error &) { ignoreExceptionInDestructor(lvlDebug); }
#endif
return 0;

View file

@ -2,6 +2,7 @@
#include "signals.hh"
#include "finally.hh"
#include "serialise.hh"
#include "util.hh"
#include <fcntl.h>
#include <unistd.h>
@ -65,7 +66,7 @@ AutoCloseFD::~AutoCloseFD()
try {
close();
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}

View file

@ -5,6 +5,7 @@
#include "signals.hh"
#include "finally.hh"
#include "serialise.hh"
#include "util.hh"
#include <atomic>
#include <cerrno>
@ -517,7 +518,7 @@ AutoDelete::~AutoDelete()
}
}
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}

View file

@ -346,7 +346,7 @@ Activity::~Activity()
try {
logger.stopActivity(id);
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}

View file

@ -1,5 +1,6 @@
#include "serialise.hh"
#include "signals.hh"
#include "util.hh"
#include <cstring>
#include <cerrno>
@ -52,7 +53,7 @@ void BufferedSink::flush()
FdSink::~FdSink()
{
try { flush(); } catch (...) { ignoreException(); }
try { flush(); } catch (...) { ignoreExceptionInDestructor(); }
}

View file

@ -503,7 +503,7 @@ struct FramedSource : Source
}
}
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}
@ -550,7 +550,7 @@ struct FramedSink : nix::BufferedSink
to << 0;
to.flush();
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}

View file

@ -111,9 +111,8 @@ void ThreadPool::doWork(bool mainThread)
try {
std::rethrow_exception(exc);
} catch (std::exception & e) {
if (!dynamic_cast<Interrupted*>(&e) &&
!dynamic_cast<ThreadPoolShutDown*>(&e))
ignoreException();
if (!dynamic_cast<ThreadPoolShutDown*>(&e))
ignoreExceptionExceptInterrupt();
} catch (...) {
}
}

View file

@ -91,7 +91,7 @@ void unix::triggerInterrupt()
try {
callback();
} catch (...) {
ignoreException();
ignoreExceptionInDestructor();
}
}
}

View file

@ -1,6 +1,7 @@
#include "util.hh"
#include "fmt.hh"
#include "file-path.hh"
#include "signals.hh"
#include <array>
#include <cctype>
@ -182,7 +183,7 @@ std::string shellEscape(const std::string_view s)
}
void ignoreException(Verbosity lvl)
void ignoreExceptionInDestructor(Verbosity lvl)
{
/* Make sure no exceptions leave this function.
printError() also throws when remote is closed. */
@ -195,6 +196,17 @@ void ignoreException(Verbosity lvl)
} catch (...) { }
}
void ignoreExceptionExceptInterrupt(Verbosity lvl)
{
try {
throw;
} catch (const Interrupted & e) {
throw;
} catch (std::exception & e) {
printMsg(lvl, "error (ignored): %1%", e.what());
}
}
constexpr char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

View file

@ -156,9 +156,26 @@ std::string toLower(std::string s);
std::string shellEscape(const std::string_view s);
/* Exception handling in destructors: print an error message, then
ignore the exception. */
void ignoreException(Verbosity lvl = lvlError);
/**
* Exception handling in destructors: print an error message, then
* ignore the exception.
*
* If you're not in a destructor, you usually want to use `ignoreExceptionExceptInterrupt()`.
*
* This function might also be used in callbacks whose caller may not handle exceptions,
* but ideally we propagate the exception using an exception_ptr in such cases.
* See e.g. `PackBuilderContext`
*/
void ignoreExceptionInDestructor(Verbosity lvl = lvlError);
/**
* Not destructor-safe.
* Print an error message, then ignore the exception.
* If the exception is an `Interrupted` exception, rethrow it.
*
* This may be used in a few places where Interrupt can't happen, but that's ok.
*/
void ignoreExceptionExceptInterrupt(Verbosity lvl = lvlError);