Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert libstd to use the Drop trait #3962

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/libstd/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Expand Down
5 changes: 4 additions & 1 deletion src/libstd/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ pub struct Arena {
priv mut head: Chunk,
priv mut pod_head: Chunk,
priv mut chunks: @List<Chunk>,
drop {
}

impl Arena : Drop {
fn finalize() {
unsafe {
destroy_chunk(&self.head);
for list::each(self.chunks) |chunk| {
Expand Down
7 changes: 5 additions & 2 deletions src/libstd/c_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@ pub enum CVec<T> {

struct DtorRes {
dtor: Option<fn@()>,
drop {
}

impl DtorRes : Drop {
fn finalize() {
match self.dtor {
option::None => (),
option::Some(f) => f()
}
}
}
}

fn DtorRes(dtor: Option<fn@()>) -> DtorRes {
Expand Down
8 changes: 5 additions & 3 deletions src/libstd/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ use cast::copy_lifetime;
#[doc = "The future type"]
pub struct Future<A> {
/*priv*/ mut state: FutureState<A>,
}

// 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<A> Future<A> : Drop {
fn finalize() {}
}

priv enum FutureState<A> {
Expand Down
7 changes: 5 additions & 2 deletions src/libstd/net_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion src/libstd/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
117 changes: 76 additions & 41 deletions src/libstd/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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]>)
Expand All @@ -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 {
/**
Expand Down Expand Up @@ -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();
}
}
}
}
Expand Down Expand Up @@ -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();
}
}
}
Expand All @@ -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();
}
}
}
}
Expand All @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion src/libstd/thread_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ pub struct ThreadPool<T> {
channels: ~[Chan<Msg<T>>],
mut next_index: uint,

drop {
}

impl<T> ThreadPool<T> {
fn finalize() {
for self.channels.each |channel| {
channel.send(Quit);
}
Expand Down