[core] Make sure ThreadLocal will not own the pointer it is managing
ThreadLocal should not own the pointer it is managing because the use case in Mapbox GL is to keep a pointer to a stack allocated object, like: ``` MyObject foo; threadLocal.set(&foo); ``` To keep consistency, it is required that we clear the managed object before ThreadLocal gets destroyed by setting it to `nullptr`.
This commit is contained in:
@@ -71,30 +71,38 @@ TEST(ThreadLocalStorage, NotSetReturnsNull) {
|
||||
|
||||
namespace {
|
||||
|
||||
class TestThreadReclaim {
|
||||
class TestThreadDataOwnership {
|
||||
public:
|
||||
TestThreadReclaim(mbgl::ActorRef<TestThreadReclaim>, int* data_) {
|
||||
TestThreadDataOwnership(mbgl::ActorRef<TestThreadDataOwnership>, int* data_) {
|
||||
data.set(data_);
|
||||
}
|
||||
|
||||
~TestThreadDataOwnership() {
|
||||
data.set(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
ThreadLocal<int> data;
|
||||
static ThreadLocal<int> data;
|
||||
};
|
||||
|
||||
ThreadLocal<int> TestThreadDataOwnership::data;
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(ThreadLocalStorage, AutoReclaim) {
|
||||
TEST(ThreadLocalStorage, ShouldNotTakeOwnership) {
|
||||
RunLoop loop;
|
||||
|
||||
auto data1 = new int;
|
||||
auto data2 = new int;
|
||||
auto data1 = std::make_unique<int>(10);
|
||||
auto data2 = std::make_unique<int>(20);
|
||||
|
||||
auto thread1 = std::make_unique<Thread<TestThreadReclaim>>("Test", data1);
|
||||
auto thread2 = std::make_unique<Thread<TestThreadReclaim>>("Test", data2);
|
||||
auto thread1 = std::make_unique<Thread<TestThreadDataOwnership>>("Test", data1.get());
|
||||
auto thread2 = std::make_unique<Thread<TestThreadDataOwnership>>("Test", data2.get());
|
||||
|
||||
thread1.reset();
|
||||
thread2.reset();
|
||||
|
||||
// Should not leak, valgrind will
|
||||
// let us know.
|
||||
// Will crash if ThreadLocal destroys
|
||||
// the pointer it is managing.
|
||||
ASSERT_EQ(*data1, 10);
|
||||
ASSERT_EQ(*data2, 20);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user