Skip to content
Merged
2 changes: 1 addition & 1 deletion doc/win-dev.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function ThrowOnNativeFailure {

$VsVersion = 2019
$MsvcVersion = '14.2'
$BoostVersion = @(1, 86, 0)
$BoostVersion = @(1, 87, 0)
$OpensslVersion = '3_0_15'

switch ($Env:BITS) {
Expand Down
41 changes: 27 additions & 14 deletions lib/base/io-engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@
#include <utility>
#include <vector>
#include <stdexcept>
#include <boost/context/fixedsize_stack.hpp>
Comment thread
yhabteab marked this conversation as resolved.
#include <boost/exception/all.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/spawn.hpp>

#if BOOST_VERSION >= 108700
# include <boost/asio/detached.hpp>
#endif // BOOST_VERSION >= 108700

namespace icinga
{

Expand Down Expand Up @@ -100,24 +105,32 @@ class IoEngine

template <typename Handler, typename Function>
static void SpawnCoroutine(Handler& h, Function f) {

boost::asio::spawn(h,
[f](boost::asio::yield_context yc) {

auto wrapper = [f = std::move(f)](boost::asio::yield_context yc) {
try {
f(yc);
} catch (const std::exception& ex) {
Log(LogCritical, "IoEngine") << "Exception in coroutine: " << DiagnosticInformation(ex);
} catch (...) {
try {
f(yc);
} catch (const boost::coroutines::detail::forced_unwind &) {
// Required for proper stack unwinding when coroutines are destroyed.
// https://github.com/boostorg/coroutine/issues/39
throw;
Comment thread
yhabteab marked this conversation as resolved.
} catch (const std::exception& ex) {
Log(LogCritical, "IoEngine") << "Exception in coroutine: " << DiagnosticInformation(ex);
} catch (...) {
Log(LogCritical, "IoEngine", "Exception in coroutine!");
} catch (...) {
}
},
boost::coroutines::attributes(GetCoroutineStackSize()) // Set a pre-defined stack size.

// Required for proper stack unwinding when coroutines are destroyed.
// https://github.com/boostorg/coroutine/issues/39
throw;
}
};

#if BOOST_VERSION >= 108700
boost::asio::spawn(h,
std::allocator_arg, boost::context::fixedsize_stack(GetCoroutineStackSize()),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::allocator_arg, boost::context::fixedsize_stack(GetCoroutineStackSize()),
std::allocator_arg,
boost::context::fixedsize_stack(GetCoroutineStackSize()),

std::move(wrapper),
boost::asio::detached
);
#else // BOOST_VERSION >= 108700
boost::asio::spawn(h, std::move(wrapper), boost::coroutines::attributes(GetCoroutineStackSize()));
#endif // BOOST_VERSION >= 108700
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, this affects only Windows, currently. (Remember! WE control what we ship there.)

}

static inline
Expand Down
6 changes: 2 additions & 4 deletions lib/base/tcpsocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ void Connect(Socket& socket, const String& node, const String& service)
using boost::asio::ip::tcp;

tcp::resolver resolver (IoEngine::Get().GetIoContext());
tcp::resolver::query query (node, service);
auto result (resolver.resolve(query));
auto result (resolver.resolve(node.GetData(), service.GetData()));
auto current (result.begin());

for (;;) {
Expand Down Expand Up @@ -72,8 +71,7 @@ void Connect(Socket& socket, const String& node, const String& service, boost::a
using boost::asio::ip::tcp;

tcp::resolver resolver (IoEngine::Get().GetIoContext());
tcp::resolver::query query (node, service);
auto result (resolver.async_resolve(query, yc));
auto result (resolver.async_resolve(node.GetData(), service.GetData(), yc));
auto current (result.begin());

for (;;) {
Expand Down
41 changes: 4 additions & 37 deletions lib/icingadb/redisconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,6 @@ void RedisConnection::Connect(asio::yield_context& yc)
}

break;
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (const std::exception& ex) {
Log(LogCritical, "IcingaDB")
<< "Cannot connect to " << m_Host << ":" << m_Port << ": " << ex.what();
Expand Down Expand Up @@ -408,17 +406,10 @@ void RedisConnection::ReadLoop(asio::yield_context& yc)
for (auto i (item.Amount); i; --i) {
ReadOne(yc);
}
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (const std::exception& ex) {
Log(LogCritical, "IcingaDB")
<< "Error during receiving the response to a query which has been fired and forgotten: " << ex.what();

continue;
} catch (...) {
Log(LogCritical, "IcingaDB")
<< "Error during receiving the response to a query which has been fired and forgotten";

continue;
}

Expand All @@ -432,9 +423,7 @@ void RedisConnection::ReadLoop(asio::yield_context& yc)

try {
reply = ReadOne(yc);
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
promise.set_exception(std::current_exception());

continue;
Expand All @@ -455,9 +444,7 @@ void RedisConnection::ReadLoop(asio::yield_context& yc)
for (auto i (item.Amount); i; --i) {
try {
replies.emplace_back(ReadOne(yc));
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
promise.set_exception(std::current_exception());
break;
}
Expand Down Expand Up @@ -551,19 +538,11 @@ void RedisConnection::WriteItem(boost::asio::yield_context& yc, RedisConnection:

try {
WriteOne(item, yc);
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (const std::exception& ex) {
Log msg (LogCritical, "IcingaDB", "Error during sending query");
LogQuery(item, msg);
msg << " which has been fired and forgotten: " << ex.what();

return;
} catch (...) {
Log msg (LogCritical, "IcingaDB", "Error during sending query");
LogQuery(item, msg);
msg << " which has been fired and forgotten";

return;
}

Expand All @@ -587,19 +566,11 @@ void RedisConnection::WriteItem(boost::asio::yield_context& yc, RedisConnection:
WriteOne(query, yc);
++i;
}
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (const std::exception& ex) {
Log msg (LogCritical, "IcingaDB", "Error during sending query");
LogQuery(item[i], msg);
msg << " which has been fired and forgotten: " << ex.what();

return;
} catch (...) {
Log msg (LogCritical, "IcingaDB", "Error during sending query");
LogQuery(item[i], msg);
msg << " which has been fired and forgotten";

return;
}

Expand All @@ -618,9 +589,7 @@ void RedisConnection::WriteItem(boost::asio::yield_context& yc, RedisConnection:

try {
WriteOne(item.first, yc);
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
item.second.set_exception(std::current_exception());

return;
Expand All @@ -645,9 +614,7 @@ void RedisConnection::WriteItem(boost::asio::yield_context& yc, RedisConnection:
for (auto& query : item.first) {
WriteOne(query, yc);
}
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
item.second.set_exception(std::current_exception());

return;
Expand Down
8 changes: 2 additions & 6 deletions lib/icingadb/redisconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,7 @@ RedisConnection::Reply RedisConnection::ReadOne(StreamPtr& stream, boost::asio::

try {
return ReadRESP(*strm, yc);
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
if (m_Connecting.exchange(false)) {
m_Connected.store(false);
stream = nullptr;
Expand Down Expand Up @@ -427,9 +425,7 @@ void RedisConnection::WriteOne(StreamPtr& stream, RedisConnection::Query& query,
try {
WriteRESP(*strm, query, yc);
strm->async_flush(yc);
} catch (const boost::coroutines::detail::forced_unwind&) {
throw;
} catch (...) {
} catch (const std::exception&) {
if (m_Connecting.exchange(false)) {
m_Connected.store(false);
stream = nullptr;
Expand Down
4 changes: 1 addition & 3 deletions lib/remote/apilistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,7 @@ bool ApiListener::AddListener(const String& node, const String& service)

try {
tcp::resolver resolver (io);
tcp::resolver::query query (node, service, tcp::resolver::query::passive);

auto result (resolver.resolve(query));
auto result (resolver.resolve(node.GetData(), service.GetData(), tcp::resolver::passive));
auto current (result.begin());

for (;;) {
Expand Down
4 changes: 2 additions & 2 deletions lib/remote/jsonrpcconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void JsonRpcConnection::SendMessage(const Dictionary::Ptr& message)

Ptr keepAlive (this);

m_IoStrand.post([this, keepAlive, message]() { SendMessageInternal(message); });
boost::asio::post(m_IoStrand, [this, keepAlive, message] { SendMessageInternal(message); });
}

void JsonRpcConnection::SendRawMessage(const String& message)
Expand All @@ -223,7 +223,7 @@ void JsonRpcConnection::SendRawMessage(const String& message)

Ptr keepAlive (this);

m_IoStrand.post([this, keepAlive, message]() {
boost::asio::post(m_IoStrand, [this, keepAlive, message] {
if (m_ShuttingDown) {
return;
}
Expand Down
10 changes: 5 additions & 5 deletions test/base-io-engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ BOOST_AUTO_TEST_CASE(timeout_run)
boost::asio::io_context::strand strand (io);
int called = 0;

boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
IoEngine::SpawnCoroutine(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io);

Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
Expand All @@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(timeout_cancelled)
boost::asio::io_context::strand strand (io);
int called = 0;

boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
IoEngine::SpawnCoroutine(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io);
Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });

Expand All @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(timeout_scope)
boost::asio::io_context::strand strand (io);
int called = 0;

boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
IoEngine::SpawnCoroutine(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io);

{
Expand Down Expand Up @@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(timeout_due_cancelled)
boost::asio::io_context::strand strand (io);
int called = 0;

boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
IoEngine::SpawnCoroutine(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io);
Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });

Expand Down Expand Up @@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(timeout_due_scope)
boost::asio::io_context::strand strand (io);
int called = 0;

boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
IoEngine::SpawnCoroutine(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io);

{
Expand Down
4 changes: 2 additions & 2 deletions tools/win32/configure-dev.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ if (-not (Test-Path env:OPENSSL_ROOT_DIR)) {
$env:OPENSSL_ROOT_DIR = 'c:\local\OpenSSL-Win64'
}
if (-not (Test-Path env:BOOST_ROOT)) {
$env:BOOST_ROOT = 'c:\local\boost_1_86_0'
$env:BOOST_ROOT = 'c:\local\boost_1_87_0'
}
if (-not (Test-Path env:BOOST_LIBRARYDIR)) {
$env:BOOST_LIBRARYDIR = 'c:\local\boost_1_86_0\lib64-msvc-14.2'
$env:BOOST_LIBRARYDIR = 'c:\local\boost_1_87_0\lib64-msvc-14.2'
}
if (-not (Test-Path env:FLEX_BINARY)) {
$env:FLEX_BINARY = 'C:\ProgramData\chocolatey\bin\win_flex.exe'
Expand Down
4 changes: 2 additions & 2 deletions tools/win32/configure.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ if (-not (Test-Path env:OPENSSL_ROOT_DIR)) {
$env:OPENSSL_ROOT_DIR = "c:\local\OpenSSL_3_0_15-Win${env:BITS}"
}
if (-not (Test-Path env:BOOST_ROOT)) {
$env:BOOST_ROOT = "c:\local\boost_1_86_0-Win${env:BITS}"
$env:BOOST_ROOT = "c:\local\boost_1_87_0-Win${env:BITS}"
}
if (-not (Test-Path env:BOOST_LIBRARYDIR)) {
$env:BOOST_LIBRARYDIR = "c:\local\boost_1_86_0-Win${env:BITS}\lib${env:BITS}-msvc-14.2"
$env:BOOST_LIBRARYDIR = "c:\local\boost_1_87_0-Win${env:BITS}\lib${env:BITS}-msvc-14.2"
}
if (-not (Test-Path env:FLEX_BINARY)) {
$env:FLEX_BINARY = 'C:\ProgramData\chocolatey\bin\win_flex.exe'
Expand Down
Loading