From 6ecb0a3c1bebeccc960e67a0e57142f8a8c5e47b Mon Sep 17 00:00:00 2001 From: Ben Striegel Date: Tue, 13 Nov 2012 21:38:18 -0500 Subject: [PATCH] Convert libstd to use the Drop trait --- src/libstd/arc.rs | 5 +- src/libstd/arena.rs | 5 +- src/libstd/c_vec.rs | 7 ++- src/libstd/future.rs | 8 ++- src/libstd/net_tcp.rs | 7 ++- src/libstd/sort.rs | 5 +- src/libstd/sync.rs | 117 +++++++++++++++++++++++++------------- src/libstd/thread_pool.rs | 5 +- 8 files changed, 107 insertions(+), 52 deletions(-) diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 0033a4eaccd07..503c15b46c2cd 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -217,7 +217,10 @@ fn check_poison(is_mutex: bool, failed: bool) { #[doc(hidden)] struct PoisonOnFail { failed: &mut bool, - drop { +} + +impl PoisonOnFail : Drop { + fn finalize() { /* assert !*self.failed; -- might be false in case of cond.wait() */ if task::failing() { *self.failed = true; } } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 9f40794b28a79..cf8bbc628f0c1 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -55,7 +55,10 @@ pub struct Arena { priv mut head: Chunk, priv mut pod_head: Chunk, priv mut chunks: @List, - drop { +} + +impl Arena : Drop { + fn finalize() { unsafe { destroy_chunk(&self.head); for list::each(self.chunks) |chunk| { diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 06d56ed1ae529..2e94f07d2d88d 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -39,12 +39,15 @@ pub enum CVec { struct DtorRes { dtor: Option, - drop { +} + +impl DtorRes : Drop { + fn finalize() { match self.dtor { option::None => (), option::Some(f) => f() } - } + } } fn DtorRes(dtor: Option) -> DtorRes { diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 503e915cf8783..17b487f16dee2 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -23,10 +23,12 @@ use cast::copy_lifetime; #[doc = "The future type"] pub struct Future { /*priv*/ mut state: FutureState, +} - // FIXME(#2829) -- futures should not be copyable, because they close - // over fn~'s that have pipes and so forth within! - drop {} +// FIXME(#2829) -- futures should not be copyable, because they close +// over fn~'s that have pipes and so forth within! +impl Future : Drop { + fn finalize() {} } priv enum FutureState { diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index d58ab844f117a..182ec2a233c97 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -27,11 +27,14 @@ extern mod rustrt { */ struct TcpSocket { socket_data: @TcpSocketData, - drop { +} + +impl TcpSocket : Drop { + fn finalize() { unsafe { tear_down_socket_data(self.socket_data) } - } + } } pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket { diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 40c81951b5e9c..4f06cc40c229c 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -1133,7 +1133,10 @@ mod big_tests { val: uint, key: fn(@uint), - drop { + } + + impl LVal : Drop { + fn finalize() { let x = unsafe { task::local_data::local_data_get(self.key) }; match x { Some(@y) => { diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 43d1c9664a51f..55f458c6f46c4 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -150,7 +150,12 @@ impl &Sem<~[mut Waitqueue]> { #[doc(hidden)] struct SemRelease { sem: &Sem<()>, - drop { self.sem.release(); } +} + +impl SemRelease : Drop { + fn finalize() { + self.sem.release(); + } } fn SemRelease(sem: &r/Sem<()>) -> SemRelease/&r { @@ -162,7 +167,12 @@ fn SemRelease(sem: &r/Sem<()>) -> SemRelease/&r { #[doc(hidden)] struct SemAndSignalRelease { sem: &Sem<~[mut Waitqueue]>, - drop { self.sem.release(); } +} + +impl SemAndSignalRelease : Drop { + fn finalize() { + self.sem.release(); + } } fn SemAndSignalRelease(sem: &r/Sem<~[mut Waitqueue]>) @@ -173,7 +183,9 @@ fn SemAndSignalRelease(sem: &r/Sem<~[mut Waitqueue]>) } /// A mechanism for atomic-unlock-and-deschedule blocking and signalling. -pub struct Condvar { priv sem: &Sem<~[mut Waitqueue]>, drop { } } +pub struct Condvar { priv sem: &Sem<~[mut Waitqueue]> } + +impl Condvar : Drop { fn finalize() {} } impl &Condvar { /** @@ -242,10 +254,15 @@ impl &Condvar { // bounded in when it gets released, this shouldn't hang forever. struct SemAndSignalReacquire { sem: &Sem<~[mut Waitqueue]>, - drop unsafe { - // Needs to succeed, instead of itself dying. - do task::unkillable { - self.sem.acquire(); + } + + impl SemAndSignalReacquire : Drop { + fn finalize() { + unsafe { + // Needs to succeed, instead of itself dying. + do task::unkillable { + self.sem.acquire(); + } } } } @@ -581,20 +598,25 @@ impl &RWlock { #[doc(hidden)] struct RWlockReleaseRead { lock: &RWlock, - drop unsafe { - do task::unkillable { - let mut last_reader = false; - do self.lock.state.with |state| { - assert state.read_mode; - assert state.read_count > 0; - state.read_count -= 1; - if state.read_count == 0 { - last_reader = true; - state.read_mode = false; +} + +impl RWlockReleaseRead : Drop { + fn finalize() { + unsafe { + do task::unkillable { + let mut last_reader = false; + do self.lock.state.with |state| { + assert state.read_mode; + assert state.read_count > 0; + state.read_count -= 1; + if state.read_count == 0 { + last_reader = true; + state.read_mode = false; + } + } + if last_reader { + (&self.lock.access_lock).release(); } - } - if last_reader { - (&self.lock.access_lock).release(); } } } @@ -610,27 +632,33 @@ fn RWlockReleaseRead(lock: &r/RWlock) -> RWlockReleaseRead/&r { #[doc(hidden)] struct RWlockReleaseDowngrade { lock: &RWlock, - drop unsafe { - do task::unkillable { - let mut writer_or_last_reader = false; - do self.lock.state.with |state| { - if state.read_mode { - assert state.read_count > 0; - state.read_count -= 1; - if state.read_count == 0 { - // Case 1: Writer downgraded & was the last reader - writer_or_last_reader = true; - state.read_mode = false; +} + +impl RWlockReleaseDowngrade : Drop { + fn finalize() { + unsafe { + do task::unkillable { + let mut writer_or_last_reader = false; + do self.lock.state.with |state| { + if state.read_mode { + assert state.read_count > 0; + state.read_count -= 1; + if state.read_count == 0 { + // Case 1: Writer downgraded & was the last reader + writer_or_last_reader = true; + state.read_mode = false; + } else { + // Case 2: Writer downgraded & was not the last + // reader + } } else { - // Case 2: Writer downgraded & was not the last reader + // Case 3: Writer did not downgrade + writer_or_last_reader = true; } - } else { - // Case 3: Writer did not downgrade - writer_or_last_reader = true; } - } - if writer_or_last_reader { - (&self.lock.access_lock).release(); + if writer_or_last_reader { + (&self.lock.access_lock).release(); + } } } } @@ -643,9 +671,11 @@ fn RWlockReleaseDowngrade(lock: &r/RWlock) -> RWlockReleaseDowngrade/&r { } /// The "write permission" token used for rwlock.write_downgrade(). -pub struct RWlockWriteMode { /* priv */ lock: &RWlock, drop { } } +pub struct RWlockWriteMode { /* priv */ lock: &RWlock } +impl RWlockWriteMode : Drop { fn finalize() {} } /// The "read permission" token used for rwlock.write_downgrade(). -pub struct RWlockReadMode { priv lock: &RWlock, drop { } } +pub struct RWlockReadMode { priv lock: &RWlock } +impl RWlockReadMode : Drop { fn finalize() {} } impl &RWlockWriteMode { /// Access the pre-downgrade rwlock in write mode. @@ -954,7 +984,12 @@ mod tests { } struct SendOnFailure { c: pipes::Chan<()>, - drop { self.c.send(()); } + } + + impl SendOnFailure : Drop { + fn finalize() { + self.c.send(()); + } } fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure { diff --git a/src/libstd/thread_pool.rs b/src/libstd/thread_pool.rs index 4bded2093d0fc..f5d1a6edbf13e 100644 --- a/src/libstd/thread_pool.rs +++ b/src/libstd/thread_pool.rs @@ -13,7 +13,10 @@ pub struct ThreadPool { channels: ~[Chan>], mut next_index: uint, - drop { +} + +impl ThreadPool { + fn finalize() { for self.channels.each |channel| { channel.send(Quit); }