mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Fix a bug with the scheduler and destructor order
The PausibleIdleCallback must have some handle into the event loop, and because struct destructors are run in order of top-to-bottom in order of fields, this meant that the event loop was getting destroyed before the idle callback was getting destroyed. I can't confirm that this fixes a problem in how we use libuv, but it does semantically fix a problem for usage with other event loops.
This commit is contained in:
parent
3f5b2219cc
commit
3b30377e14
@ -85,7 +85,17 @@ pub struct Scheduler {
|
|||||||
priv yield_check_count: uint,
|
priv yield_check_count: uint,
|
||||||
/// A flag to tell the scheduler loop it needs to do some stealing
|
/// A flag to tell the scheduler loop it needs to do some stealing
|
||||||
/// in order to introduce randomness as part of a yield
|
/// in order to introduce randomness as part of a yield
|
||||||
priv steal_for_yield: bool
|
priv steal_for_yield: bool,
|
||||||
|
|
||||||
|
// n.b. currently destructors of an object are run in top-to-bottom in order
|
||||||
|
// of field declaration. Due to its nature, the pausible idle callback
|
||||||
|
// must have some sort of handle to the event loop, so it needs to get
|
||||||
|
// destroyed before the event loop itself. For this reason, we destroy
|
||||||
|
// the event loop last to ensure that any unsafe references to it are
|
||||||
|
// destroyed before it's actually destroyed.
|
||||||
|
|
||||||
|
/// The event loop used to drive the scheduler and perform I/O
|
||||||
|
event_loop: ~EventLoopObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An indication of how hard to work on a given operation, the difference
|
/// An indication of how hard to work on a given operation, the difference
|
||||||
|
52
src/test/run-pass/field-destruction-order.rs
Normal file
52
src/test/run-pass/field-destruction-order.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// In theory, it doesn't matter what order destructors are run in for rust
|
||||||
|
// because we have explicit ownership of values meaning that there's no need to
|
||||||
|
// run one before another. With unsafe code, however, there may be a safe
|
||||||
|
// interface which relies on fields having their destructors run in a particular
|
||||||
|
// order. At the time of this writing, std::rt::sched::Scheduler is an example
|
||||||
|
// of a structure which contains unsafe handles to FFI-like types, and the
|
||||||
|
// destruction order of the fields matters in the sense that some handles need
|
||||||
|
// to get destroyed before others.
|
||||||
|
//
|
||||||
|
// In C++, destruction order happens bottom-to-top in order of field
|
||||||
|
// declarations, but we currently run them top-to-bottom. I don't think the
|
||||||
|
// order really matters that much as long as we define what it is.
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
struct B;
|
||||||
|
struct C {
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut hit: bool = false;
|
||||||
|
|
||||||
|
impl Drop for A {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
assert!(!hit);
|
||||||
|
hit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for B {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
assert!(hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let _c = C { a: A, b: B };
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user