OBRM for aturon

pull/10/head
Alexis Beingessner 9 years ago committed by Manish Goregaokar
parent fe09c847aa
commit 35f68b4107

@ -27,7 +27,7 @@
* [Checked](checked-uninit.md) * [Checked](checked-uninit.md)
* [Drop Flags](drop-flags.md) * [Drop Flags](drop-flags.md)
* [Unchecked](unchecked-uninit.md) * [Unchecked](unchecked-uninit.md)
* [Ownership-Oriented Resource Management](raii.md) * [Ownership Based Resource Management](obrm.md)
* [Constructors](constructors.md) * [Constructors](constructors.md)
* [Destructors](destructors.md) * [Destructors](destructors.md)
* [Leaking](leaking.md) * [Leaking](leaking.md)

@ -45,8 +45,8 @@ impl<T> Drop for Box<T> {
``` ```
and this works fine because when Rust goes to drop the `ptr` field it just sees and this works fine because when Rust goes to drop the `ptr` field it just sees
a *mut that has no actual `Drop` implementation. Similarly nothing can use- a [Unique][] that has no actual `Drop` implementation. Similarly nothing can
after-free the `ptr` because the Box is immediately marked as uninitialized. use-after-free the `ptr` because when drop exits, it becomes inacessible.
However this wouldn't work: However this wouldn't work:
@ -174,3 +174,5 @@ arbitrarily invalid state in there.
On balance this is an ok choice. Certainly what you should reach for by default. On balance this is an ok choice. Certainly what you should reach for by default.
However, in the future we expect there to be a first-class way to announce that However, in the future we expect there to be a first-class way to announce that
a field shouldn't be automatically dropped. a field shouldn't be automatically dropped.
[Unique]: phantom-data.html

@ -8,14 +8,17 @@ is perfect and all of our problems are solved.
Everything is terrible and we have new and exotic problems to try to solve. Everything is terrible and we have new and exotic problems to try to solve.
Many people like to believe that Rust eliminates resource leaks, but this is Many people like to believe that Rust eliminates resource leaks. In practice,
absolutely not the case, no matter how you look at it. In the strictest sense, this is basically true. You would be surprised to see a Safe Rust program
"leaking" is so abstract as to be unpreventable. It's quite trivial to leak resources in an uncontrolled way.
initialize a collection at the start of a program, fill it with tons of objects
with destructors, and then enter an infinite event loop that never refers to it. However from a theoretical perspective this is absolutely not the case, no
The collection will sit around uselessly, holding on to its precious resources matter how you look at it. In the strictest sense, "leaking" is so abstract as
until the program terminates (at which point all those resources would have been to be unpreventable. It's quite trivial to initialize a collection at the start
reclaimed by the OS anyway). of a program, fill it with tons of objects with destructors, and then enter an
infinite event loop that never refers to it. The collection will sit around
uselessly, holding on to its precious resources until the program terminates (at
which point all those resources would have been reclaimed by the OS anyway).
We may consider a more restricted form of leak: failing to drop a value that is We may consider a more restricted form of leak: failing to drop a value that is
unreachable. Rust also doesn't prevent this. In fact Rust has a *function for unreachable. Rust also doesn't prevent this. In fact Rust has a *function for
@ -181,7 +184,26 @@ in memory.
## thread::scoped::JoinGuard ## thread::scoped::JoinGuard
The thread::scoped API intends to allow threads to be spawned that reference The thread::scoped API intends to allow threads to be spawned that reference
data on the stack without any synchronization over that data. Usage looked like: data on their parent's stack without any synchronization over that data by
ensuring the parent joins the thread before any of the shared data goes out
of scope.
```rust
pub fn scoped<'a, F>(f: F) -> JoinGuard<'a>
where F: FnOnce() + Send + 'a
```
Here `f` is some closure for the other thread to execute. Saying that
`F: Send +'a` is saying that it closes over data that lives for `'a`, and it
either owns that data or the data was Sync (implying `&data` is Send).
Because JoinGuard has a lifetime, it keeps all the data it closes over
borrowed in the parent thread. This means the JoinGuard can't outlive
the data that the other thread is working on. When the JoinGuard *does* get
dropped it blocks the parent thread, ensuring the child terminates before any
of the closed-over data goes out of scope in the parent.
Usage looked like:
```rust,ignore ```rust,ignore
let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

@ -0,0 +1,14 @@
% The Perils Of Ownership Based Resource Management (OBRM)
OBRM (AKA RAII: Resource Acquisition Is Initialization) is something you'll
interact with a lot in Rust. Especially if you use the standard library.
Roughly speaking the pattern is as follows: to acquire a resource, you create an
object that manages it. To release the resource, you simply destroy the object,
and it cleans up the resource for you. The most common "resource" this pattern
manages is simply *memory*. `Box`, `Rc`, and basically everything in
`std::collections` is a convenience to enable correctly managing memory. This is
particularly important in Rust because we have no pervasive GC to rely on for
memory management. Which is the point, really: Rust is about control. However we
are not limited to just memory. Pretty much every other system resource like a
thread, file, or socket is exposed through this kind of API.

@ -1,14 +0,0 @@
% The Perils Of RAII
Ownership Based Resource Management (AKA RAII: Resource Acquisition Is Initialization) is
something you'll interact with a lot in Rust. Especially if you use the standard library.
Roughly speaking the pattern is as follows: to acquire a resource, you create an object that
manages it. To release the resource, you simply destroy the object, and it cleans up the
resource for you. The most common "resource"
this pattern manages is simply *memory*. `Box`, `Rc`, and basically everything in
`std::collections` is a convenience to enable correctly managing memory. This is particularly
important in Rust because we have no pervasive GC to rely on for memory management. Which is the
point, really: Rust is about control. However we are not limited to just memory.
Pretty much every other system resource like a thread, file, or socket is exposed through
this kind of API.
Loading…
Cancel
Save