mirror of https://github.com/Icinga/icinga2.git
IoEngine#SpawnCoroutine(): always terminate coroutines cleanly
This commit is contained in:
parent
099cc5d8df
commit
b65aed1dd3
|
@ -3,7 +3,9 @@
|
||||||
#ifndef IO_ENGINE_H
|
#ifndef IO_ENGINE_H
|
||||||
#define IO_ENGINE_H
|
#define IO_ENGINE_H
|
||||||
|
|
||||||
|
#include "base/exception.hpp"
|
||||||
#include "base/lazy-init.hpp"
|
#include "base/lazy-init.hpp"
|
||||||
|
#include "base/logger.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -79,28 +81,6 @@ public:
|
||||||
|
|
||||||
boost::asio::io_context& GetIoContext();
|
boost::asio::io_context& GetIoContext();
|
||||||
|
|
||||||
/*
|
|
||||||
* Custom exceptions thrown in a Boost.Coroutine may cause stack corruption.
|
|
||||||
* Ensure that these are wrapped correctly.
|
|
||||||
*
|
|
||||||
* Inspired by https://github.com/niekbouman/commelec-api/blob/master/commelec-api/coroutine-exception.hpp
|
|
||||||
* Source: http://boost.2283326.n4.nabble.com/coroutine-only-std-exceptions-are-caught-from-coroutines-td4683671.html
|
|
||||||
*/
|
|
||||||
static inline boost::exception_ptr convertExceptionPtr(std::exception_ptr ex) {
|
|
||||||
try {
|
|
||||||
throw boost::enable_current_exception(ex);
|
|
||||||
} catch (...) {
|
|
||||||
return boost::current_exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rethrowBoostExceptionPointer() {
|
|
||||||
std::exception_ptr sep;
|
|
||||||
sep = std::current_exception();
|
|
||||||
boost::exception_ptr bep = convertExceptionPtr(sep);
|
|
||||||
boost::rethrow_exception(bep);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline size_t GetCoroutineStackSize() {
|
static inline size_t GetCoroutineStackSize() {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Increase the stack size for Windows coroutines to prevent exception corruption.
|
// Increase the stack size for Windows coroutines to prevent exception corruption.
|
||||||
|
@ -126,9 +106,11 @@ public:
|
||||||
// Required for proper stack unwinding when coroutines are destroyed.
|
// Required for proper stack unwinding when coroutines are destroyed.
|
||||||
// https://github.com/boostorg/coroutine/issues/39
|
// https://github.com/boostorg/coroutine/issues/39
|
||||||
throw;
|
throw;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
Log(LogCritical, "IoEngine", "Exception in coroutine!");
|
||||||
|
Log(LogDebug, "IoEngine") << "Exception in coroutine: " << DiagnosticInformation(ex);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// Handle uncaught exceptions outside of the coroutine.
|
Log(LogCritical, "IoEngine", "Exception in coroutine!");
|
||||||
rethrowBoostExceptionPointer();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
boost::coroutines::attributes(GetCoroutineStackSize()) // Set a pre-defined stack size.
|
boost::coroutines::attributes(GetCoroutineStackSize()) // Set a pre-defined stack size.
|
||||||
|
|
Loading…
Reference in New Issue