Page 22 of the slide ```c++ 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!
```rust
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