mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Make Env::AppBundle constructor exception safe
When the Env::AppBundle constructor throws an exception it still needs to run ~AppBundle(), otherwise the JobQueue isn't properly shut down. Specifically the JobQueue can destruct without waiting on outstanding jobs in the queue. This change ensures that if Env::AppBundle constructor throws, Env::AppBundle::~AppBundle() runs. This fixes the unit test crash exposed by PR #3047.
This commit is contained in:
committed by
Manoj doshi
parent
41b2c80dde
commit
726dd69ab9
@@ -124,12 +124,13 @@ public:
|
||||
private:
|
||||
struct AppBundle
|
||||
{
|
||||
Application* app;
|
||||
Application* app = nullptr;
|
||||
std::unique_ptr<Application> owned;
|
||||
ManualTimeKeeper* timeKeeper;
|
||||
ManualTimeKeeper* timeKeeper = nullptr;
|
||||
std::thread thread;
|
||||
std::unique_ptr<AbstractClient> client;
|
||||
|
||||
AppBundle() = default;
|
||||
AppBundle (beast::unit_test::suite& suite,
|
||||
std::unique_ptr<Config> config,
|
||||
std::unique_ptr<Logs> logs);
|
||||
|
||||
@@ -749,6 +749,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void testExceptionalShutdown()
|
||||
{
|
||||
except(
|
||||
[this]
|
||||
{
|
||||
jtx::Env env {*this,
|
||||
jtx::envconfig([](std::unique_ptr<Config> cfg)
|
||||
{
|
||||
(*cfg).deprecatedClearSection("port_rpc");
|
||||
return cfg;
|
||||
})};
|
||||
}
|
||||
);
|
||||
pass();
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -771,6 +787,7 @@ public:
|
||||
testResignSigned();
|
||||
testSignAndSubmit();
|
||||
testFeatures();
|
||||
testExceptionalShutdown();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace jtx {
|
||||
Env::AppBundle::AppBundle(beast::unit_test::suite& suite,
|
||||
std::unique_ptr<Config> config,
|
||||
std::unique_ptr<Logs> logs)
|
||||
: AppBundle()
|
||||
{
|
||||
using namespace beast::severities;
|
||||
// Use kFatal threshold to reduce noise from STObject.
|
||||
@@ -89,9 +90,13 @@ Env::AppBundle::~AppBundle()
|
||||
client.reset();
|
||||
// Make sure all jobs finish, otherwise tests
|
||||
// might not get the coverage they expect.
|
||||
app->getJobQueue().rendezvous();
|
||||
app->signalStop();
|
||||
thread.join();
|
||||
if (app)
|
||||
{
|
||||
app->getJobQueue().rendezvous();
|
||||
app->signalStop();
|
||||
}
|
||||
if (thread.joinable())
|
||||
thread.join();
|
||||
|
||||
// Remove the debugLogSink before the suite goes out of scope.
|
||||
setDebugLogSink (nullptr);
|
||||
|
||||
Reference in New Issue
Block a user