Page 22 of the slide

auto data_guard = data.lock()
auto data_ptr = &data_guard 
// getting ptr between acquire and release of data
// criticial section: between acquire and release
// using ptr outside the critical section can cause problem

*data_ptr = 666 // unsafe

lifetime of ptr should end at the point where the data releases!!

  • Type: set of values: e.g. ${\text{True}, \text{False}}$
  • value $\in$ Type: e.g. $\text{True} \in {\text{True}, \text{False}}$
  • (Strong) type system: preventing undefined behavior

Rust safe api for concurrency

Intro to rust

  • Shared mutable state is forbidden!
let bar1 = &mut foo.bar1;
let bar2 = &mut foo.bar1; // ERROR! two mutable borrows! 

shared mutable states are source of errors

for(auto it = v.begin(); it != v.end(); ++it) {
  if ((*it) == 5) {
    v.push_back(-1); 
    // this code might reallocate the vector and invalidates it (iterator invalidation)
    // or even a function call like f(it) can invalidate the iterator!
  }
} 

State (Data structures) and Invariant (relationship) : How to resolve shared mutable state?

  • invariant guarantees conditions that systems obeys
    • immutability: frozen vector (no changing in the vector)
    • no sharing of the data: only single variable points to a vector
    • etc.

Type-checking memory safety in c

  • void foo(int *p) : what if p == nullptr?
  • void foo(int &p) : what if p references object already freed?
  • voif foo(unique_ptr<int> p) : pitfall! we can demistify this one by type casting

References in Rust

fn foo(p: Box<i32>)
//p owns the object of type `i32`: unique reference (always safe)

fn foo(p: &i32) // immutable borrow (always safe)
// allows read, no write (mutation)
fn foo(p: &mut i32) // mutable borrow 
// allows write, not sharable
  • Box and mutable reference cannot exist at the same time