Fix rare corruption in StaticMeta::head_ list around fork
authorTudor Bosman <tudorb@fb.com>
Wed, 5 Feb 2014 00:23:43 +0000 (16:23 -0800)
committerSara Golemon <sgolemon@fb.com>
Thu, 6 Feb 2014 19:50:14 +0000 (11:50 -0800)
commit9afa70a24d098fd105d2929d74dd8342a5c4a1ca
treec2b79903cb61005af69da478770ad1725340b56c
parent79c25e6f4a7742342347b4dc23d4e237eac2aa37
Fix rare corruption in StaticMeta::head_ list around fork

Summary:
In a rare case, the current thread's would be inserted in the StaticMeta linked
list twice, causing the list to be corrupted, leading to code spinning forever.

After a fork, in the child, only the current thread survives, so all other threads
must be forcefully removed from StaticMeta. We do that by clearing the list
and re-adding the current thread, but we didn't check whether the current thread
was already there. It is possible for the current thread to not be in the list
if it never used any ThreadLocalPtr objects with the same tag.

Now, when the thread in the child tries to use a ThreadLocalPtr with the same
tag, it adds itself to the list (##if (prevCapacity == 0)
meta.push_back(threadEntry)##), but it had already been added by the post-fork
handler, boom.

Fix by adding the necessary check in onForkChild.

Test Plan: @durham's test case, also added new test for this

Reviewed By: delong.j@fb.com

FB internal diff: D1158672

@override-unit-failures
folly/detail/ThreadLocalDetail.h
folly/test/ThreadLocalTest.cpp