Commit b51f8cd7 authored by Akshay Vaidya's avatar Akshay Vaidya Committed by Dave Watson

Adding a release function for ThreadLocalPtr.

Summary:
ThreadLocalPtr manages the lifecycle of the object that is
stored with it. We have a use case where we sometimes want to transfer ownership
of the stored object to another thread by wrapping them with
unique_ptrs. Adding a release function, similar to to the
unique_ptr::release is the cleanest way for us to transfer ownership.

Test Plan:
I can do some on off testing using a command line tool, but I
was wondering about how to add some unit tests. Not sure when the folly
unit tests were.

Reviewed By: njormrod@fb.com

FB internal diff: D1321588
parent 870912b8
......@@ -165,6 +165,13 @@ class ThreadLocalPtr {
return *get();
}
T* release() {
threadlocal_detail::ElementWrapper& w =
threadlocal_detail::StaticMeta<Tag>::get(id_);
return static_cast<T*>(w.release());
}
void reset(T* newPtr = nullptr) {
threadlocal_detail::ElementWrapper& w =
threadlocal_detail::StaticMeta<Tag>::get(id_);
......
......@@ -77,13 +77,19 @@ struct ElementWrapper {
if (ptr != nullptr) {
DCHECK(deleter != nullptr);
deleter->dispose(ptr, mode);
if (ownsDeleter) {
delete deleter;
}
ptr = nullptr;
deleter = nullptr;
ownsDeleter = false;
cleanup();
}
}
void* release() {
auto retPtr = ptr;
if (ptr != nullptr) {
cleanup();
}
return retPtr;
}
template <class Ptr>
......@@ -114,6 +120,15 @@ struct ElementWrapper {
}
}
void cleanup() {
if (ownsDeleter) {
delete deleter;
}
ptr = nullptr;
deleter = nullptr;
ownsDeleter = false;
}
void* ptr;
DeleterBase* deleter;
bool ownsDeleter;
......
......@@ -86,6 +86,21 @@ TEST(ThreadLocalPtr, resetNull) {
EXPECT_FALSE(tl);
}
TEST(ThreadLocalPtr, TestRelease) {
Widget::totalVal_ = 0;
ThreadLocalPtr<Widget> w;
std::unique_ptr<Widget> wPtr;
std::thread([&w, &wPtr]() {
w.reset(new Widget());
w.get()->val_ += 10;
wPtr.reset(w.release());
}).join();
EXPECT_EQ(0, Widget::totalVal_);
wPtr.reset();
EXPECT_EQ(10, Widget::totalVal_);
}
// Test deleting the ThreadLocalPtr object
TEST(ThreadLocalPtr, CustomDeleter2) {
Widget::totalVal_ = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment