libstore: make Pool::get fully cancel-safe
cancelling a get() promise could leave the pool with allegedly in use resource handles that do not actually exist. this would cause asserts in ~Pool to fire (and crash the entire program due to bad accounting) probably fixes #1041 Change-Id: Ic61ab9b658f02f71e8be7577b8a1115600846f86
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "lix/libutil/pool.hh"
|
||||
#include "lix/libutil/result.hh"
|
||||
#include <exception>
|
||||
#include <gtest/gtest.h>
|
||||
#include <kj/async.h>
|
||||
|
||||
@@ -132,4 +133,35 @@ namespace nix {
|
||||
ASSERT_NE(h->num, counter);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PoolTest, factoryCancel)
|
||||
{
|
||||
// resource factories failing must not crash if a promise is cancelled.
|
||||
// c.f. https://git.lix.systems/lix-project/lix/issues/1041
|
||||
|
||||
{
|
||||
Pool<TestResource> pool(1);
|
||||
(void) pool.get();
|
||||
}
|
||||
|
||||
{
|
||||
auto createResource = []() -> kj::Promise<Result<ref<TestResource>>> {
|
||||
return {result::failure(std::make_exception_ptr(Error("failure")))};
|
||||
};
|
||||
|
||||
Pool<TestResource> pool(1, createResource);
|
||||
(void) pool.get();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PoolTest, factoryFailureNormal)
|
||||
{
|
||||
auto createResource = []() -> kj::Promise<Result<ref<TestResource>>> {
|
||||
return {result::failure(std::make_exception_ptr(Error("failure")))};
|
||||
};
|
||||
|
||||
Pool<TestResource> pool(1, createResource);
|
||||
|
||||
ASSERT_THROW(pool.get().wait(ws).value(), Error);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user