Skip to content

Commit 7bf7bd6

Browse files
committed
work around portability issue on FreeBSD, in which the key returned from
pthread_key_create can be 0.
1 parent 95d1771 commit 7bf7bd6

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

src/libstd/sys/common/thread_local.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,23 @@ impl StaticKey {
185185
}
186186

187187
unsafe fn lazy_init(&self) -> uint {
188-
let key = imp::create(self.dtor);
188+
// POSIX allows the key created here to be 0, but the compare_and_swap
189+
// below relies on using 0 as a sentinel value to check who won the
190+
// race to set the shared TLS key. As far as I know, there is no
191+
// guaranteed value that cannot be returned as a posix_key_create key,
192+
// so there is no value we can initialize the inner key with to
193+
// prove that it has not yet been set. As such, we'll continue using a
194+
// value of 0, but with some gyrations to make sure we have a non-0
195+
// value returned from the creation routine.
196+
// TODO: this is clearly a hack, and should be cleaned up.
197+
let key1 = imp::create(self.dtor);
198+
let key = if key1 != 0 {
199+
key1
200+
} else {
201+
let key2 = imp::create(self.dtor);
202+
imp::destroy(key1);
203+
key2
204+
};
189205
assert!(key != 0);
190206
match self.inner.key.compare_and_swap(0, key as uint, atomic::SeqCst) {
191207
// The CAS succeeded, so we've created the actual key

0 commit comments

Comments
 (0)