summary refs log tree commit diff
path: root/src/libstd/sys/windows/thread_local.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-19 11:29:39 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-12-30 14:33:59 -0800
commit9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7 (patch)
treeda18d5791e6841a1aa6a9469baca155d4ca9828d /src/libstd/sys/windows/thread_local.rs
parentd2368c3c11ddab9d812c4ddec2e44579326ad347 (diff)
downloadrust-9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7.tar.gz
rust-9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7.zip
std: Re-enable at_exit()
The new semantics of this function are that the callbacks are run when the *main
thread* exits, not when all threads have exited. This implies that other threads
may still be running when the `at_exit` callbacks are invoked and users need to
be prepared for this situation.

Users in the standard library have been audited in accordance to these new rules
as well.

Closes #20012
Diffstat (limited to 'src/libstd/sys/windows/thread_local.rs')
-rw-r--r--src/libstd/sys/windows/thread_local.rs11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index 60b0d584db3..4ac57e37117 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -137,9 +137,9 @@ unsafe fn init_dtors() {
     rt::at_exit(move|| {
         DTOR_LOCK.lock();
         let dtors = DTORS;
-        DTORS = 0 as *mut _;
+        DTORS = 1 as *mut _;
         mem::transmute::<_, Box<Vec<(Key, Dtor)>>>(dtors);
-        assert!(DTORS.is_null()); // can't re-init after destructing
+        assert!(DTORS as uint == 1); // can't re-init after destructing
         DTOR_LOCK.unlock();
     });
 }
@@ -147,6 +147,9 @@ unsafe fn init_dtors() {
 unsafe fn register_dtor(key: Key, dtor: Dtor) {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as uint != 0);
+    assert!(DTORS as uint != 1,
+            "cannot create new TLS keys after the main thread has exited");
     (*DTORS).push((key, dtor));
     DTOR_LOCK.unlock();
 }
@@ -154,6 +157,9 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
 unsafe fn unregister_dtor(key: Key) -> bool {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as uint != 0);
+    assert!(DTORS as uint != 1,
+            "cannot unregister destructors after the main thread has exited");
     let ret = {
         let dtors = &mut *DTORS;
         let before = dtors.len();
@@ -232,6 +238,7 @@ unsafe extern "system" fn on_tls_callback(h: LPVOID,
     }
 }
 
+#[allow(dead_code)] // not actually dead
 unsafe fn run_dtors() {
     let mut any_run = true;
     for _ in range(0, 5i) {