diff --git a/09_pinning.md b/09_pinning.md
index 1f00212ad80b591c687a1f5248adccb8e3993baa..fad4a2fd9bf0b056b51dc7d5fef669766ab05add 100644
--- a/09_pinning.md
+++ b/09_pinning.md
@@ -93,6 +93,20 @@ coroutine fn async_main() {
 
 ## Le compteur 1/
 
+```rust
+impl Coroutine {
+    fn new() -> Self {
+        Self {
+            stack: Stack { counter: None },
+            state: State::Start,
+        }
+    }
+}
+
+```
+
+## Le compteur 2/
+
 ```rust
 State::Start => {
     self.stack.counter = Some(0);
@@ -119,7 +133,7 @@ State::Wait2(ref mut f2) => {
 }
 ```
 
-## Compteur 2/
+## Compteur 3/
 
 * `Start`: on initialise le compteur
 * `Wait1`: 
@@ -132,3 +146,323 @@ State::Wait2(ref mut f2) => {
     * on affiche sa velur à l'écran
     * on "nettoie" la valeur (rien besoin de faire, car on a déjà `None` dans la pile)
 
+# Partie 2: Ajouter des références
+
+## Objectif: ajouter un buffer dans notre code `async`
+
+```rust
+coroutine fn async_main() {
+    let mut buffer = String::from("\nBUFFER:\n------\n");
+    let writer = &mut buffer;
+    let mut counter = 0;
+    println!("Program starting");
+    let txt = Http::get("/600/HelloAsyncWait").wait;
+    writeln!(writer, "{txt}").unwrap();
+    counter += 1;
+    let txt = Http::get("/400/HelloAsyncWait").wait;
+    writeln!(writer, "{txt}").unwrap();
+    writeln!(writer, "------").unwrap();
+    counter += 1;
+    println!("Received {} responses", counter);
+    println!("{buffer}");
+}
+```
+
+* `buffer` sera une `Option<String>`
+* `writer` est une `Option<*mut String>`
+* Interdit de `Option<&mut String>`, car `writer` pointe sur `buffer`
+* `writeln!()` permet d'écrire dans une autre cible que `println!()`
+
+## Le `buffer` 1/
+
+```rust 
+struct Coroutine {
+    stack: Stack,
+    state: State,
+}
+struct Stack {
+    counter: Option<usize>,
+    buffer: Option<String>,
+    writer: Option<*mut String>,
+}
+impl Coroutine {
+    fn new() -> Self {
+        Self {
+            stack: Stack { counter: None, buffer: None, writer: None },
+            state: State::Start,
+        }
+    }
+}
+```
+
+* On étend notre `Stack` avec le `buffer` et `writer`
+
+## Le `buffer` 2/
+
+### `Start`
+
+```rust
+State::Start => {
+    self.stack.counter = Some(0);
+    self.stack.buffer = Some(String::from("\nBUFFER:\n------\n"));
+    self.stack.writer = Some(self.stack.buffer.as_mut().unwrap());
+    println!("Program starting");
+    let fut1 = Box::new(Http::get("/600/HelloAsyncWait"));
+    self.state = State::Wait1(fut1);
+}
+```
+
+* On initialise `buffer/writer`
+* On écrit dans le buffer via `writer`
+* L'état est implicitement sauvé dans la struct `stack`
+* `buffer.as_mut()` coercé en `*mut String`
+
+### `Wait1`
+
+```rust
+State::Wait1(ref mut f1) => {
+    match f1.poll(waker) {
+        PollState::Ready(txt) => {
+            let mut counter = self.stack.counter.take().unwrap();
+            let writer = unsafe { &mut *self.stack.writer.take().unwrap() };
+            writeln!(writer, "{txt}").unwrap();
+            counter += 1;
+            let fut2 = Box::new(Http::get("/400/HelloAsyncWait"));
+            self.state = State::Wait2(fut2);
+            self.stack.counter = Some(counter);
+            self.stack.writer = Some(writer);
+        }
+        PollState::NotReady => break PollState::NotReady,
+    }
+}
+```
+
+* On prend l'ownership du `writer`, et on écrit dedans
+* On remet le `writer` dans la `stack`
+* On est obligé de faire du `unsafe`
+
+### `Wait2`
+
+```rust 
+State::Wait2(ref mut f2) => {
+    match f2.poll(waker) {
+        PollState::Ready(txt) => {
+            let mut counter = self.stack.counter.take().unwrap();
+            let buffer = self.stack.buffer.as_ref().take().unwrap();
+            let writer = unsafe { &mut *self.stack.writer.take().unwrap() };
+            writeln!(writer, "{txt}").unwrap();
+            writeln!(writer, "------").unwrap();
+            counter += 1;
+            println!("Received {counter} responses");
+            println!("{buffer}");
+            self.state = State::Resolved;
+            let _ = self.stack.buffer.take();
+            break PollState::Ready(String::new());
+        }
+        PollState::NotReady => break PollState::NotReady,
+    }
+}
+```
+
+* On prend une référence vers le `buffer`
+* On **peut pas** prendre l'ownership du `buffer` => le `writer` serait invalidé
+* On **prend l'ownership** de la référence vers le buffer
+* On écrit dans le `writer` et affiche le `buffer`
+* On `drop()` le bufffer à la fin pour libérer les ressources et éviter de garder les choses inutiles en mémoire
+
+# Apparté: optimisation
+
+## Optimisation
+
+* Pour éviter de `poll()` trop souvent, on pourrait optimiser un tout petit peu le code
+* On modifie `block_on()`
+
+    ```rust
+        pub fn block_on<F>(&mut self, future: F)
+        where
+            F: Future<Output = String> + 'static,
+        {
+            let waker = self.get_waker(usize::MAX);
+            let mut future = future;
+            match future.poll(&waker) {
+                PollState::NotReady => (),
+                PollState::Ready(_) => return,
+            }
+            spawn(future);
+            loop {
+                while let Some(id) = self.pop_ready() {
+                ...
+    ```
+* Si les `Future` parent est déjà `Ready` on a rien besoin de faire.
+
+## Le drame
+
+```console 
+Program starting
+First poll - start operation
+Data not ready
+Data not ready
+main:  1, pending tasks. Sleep until notified.
+First poll - start operation
+Data not ready
+main:  1, pending tasks. Sleep until notified.
+Received 2 responses
+/400/HelloAsyncW
+free(): double free detected in tcache 2
+```
+
+* Hum, hum, `free(): double free detected in tcache 2`
+
+## Ok.... Il s'est passé quoi?
+
+1. On a un `Future` en argument de `block_on()` et tout va bien
+2. On appelle `poll()` une première fois 
+    * le `Future` est sur la pile de `block_on()`
+    * on appelle `poll()` et on est dans l'état `Start`
+    * initialisation de la structure auto-référencée qui fait pointer le `writer` sur le `buffer` qui est sur la pile
+3. On retourne `NotReady` et le future est placé dans la  `HashMap<usize, Box<dyn Future>>` de `Executor`
+4. Le `Future` est désormais sur la pile
+5. A l'appel suivant de `poll()` on essaie de lire le `buffer` via `writer` qui contient encore l'ancienne adresse...
+
+# Partie 4: Le Pinning
+
+## Le Pinning
+
+* Trouver un moyen de **fixer** la mémoire pour avoir la **garantie** de pourvoir partager un état
+* Aucune garantie de l'OS que des données restent au même endroit
+* En Rust: un type `Pin<T>` et un trait `Unpin`
+* Un trait `Unpin` implémenté pour un type fait que `Pin<T>` n'a aucun effet
+* `Pin<T>` un type qui est pas `Unpin` darantit qu'il bouge pas en mémoire
+* `Pin<T>` est un *wrapper* autour des références et pointeurs intelligents
+* Épingler un type qui n'est pas `Unpin` garantit que la valeur va rester à la même place en mémoire
+
+## Un exemple de Pinning 1/
+
+```rust
+struct MaybeSelfRef {
+    data: usize,
+    self_ref: Option<*mut usize>,
+    _pin: PhantomPinned,
+}
+```
+
+* Des données, une auto-référence
+* Un `PhantomPinned` qui indique au compilateur que rien ne devra bouger
+
+## Un exemple de Pinning 2/
+
+```rust
+impl MaybeSelfRef {
+    fn new() -> Self {
+        Self {
+            data: 0,
+            self_ref: None,
+            _pin: PhantomPinned::default(),
+        }
+    }
+```
+
+* On crée une struct poar "défaut"
+* Pas encore auto-référencée
+
+## Un exemple de Pinning 3/
+
+```rust
+impl MaybeSelfRef {
+    fn init(self: Pin<&mut Self>) {
+        unsafe {
+            let Self { data, self_ref, .. } = self.get_unchecked_mut();
+            *self_ref = Some(data);
+        }
+    }
+}
+```
+
+* La structure devient auto-référencée que lorsqu'on appelle `init()`
+* Le type en argument est `Pin<&mut Self>`: **Pin projection**
+
+## Un exemple de Pinning 4/
+
+```rust
+impl MaybeSelfRef {
+    fn self_ref(self: Pin<&mut Self>) -> Option<&mut usize> {
+        unsafe { self.get_unchecked_mut().self_ref.map(|sr| &mut *sr) }
+    }
+}
+```
+
+* On cache le pointeur et le `unsafe` dans une fonction
+* Transformer un pointeur en référence est intrisèquement `unsafe` car on sait pas si le pointeur est valide
+
+## Le Pinning sur le tas
+
+```rust
+fn main() {
+    let mut x = Box::pin(MaybeSelfRef::new());
+    x.as_mut().init();
+    println!("Heap Pinning data {}", x.as_ref().data);
+    *x.as_mut().self_ref().unwrap() = 10;
+    println!("Heap Pinning modified {}", x.as_ref().data);
+}
+```
+
+* On crée un `Box::pin()` (pointeur de données sur le tas)
+* On initialise notre instance
+* On modifie l'instance avec la `self_ref()`
+* C'est "simple" d'épingler sur le tas (on peut mettre la valeur n'importe où)
+
+## Le Pinning sur la pile 1/
+
+```rust
+fn main() {
+    let mut x = MaybeSelfRef::new();
+    let mut x = unsafe { Pin::new_unchecked(&mut x) };
+    x.as_mut().init();
+    println!(" Pinning data {}", x.as_ref().data);
+    *x.as_mut().self_ref().unwrap() = 10;
+    println!("Heap Pinning modified {}", x.as_ref().data);
+}
+```
+
+* Presque pareil.... Sauf que c'est `unsafe` de créer l'instance épinglée `x`
+* C'est difficile de garantir la position de `x` dans la pile parce que c'est structuré (faut une "bonne place")
+* Si on fait cela à l'intérieur d'une fonction, on peut pas garantir que les données seront là (on drop tout à la sortie)
+* C'est `unsafe` car les garanties de Rust peuvent pas être satisfaites
+
+## Le Pinning sur la pile 2/
+
+```rust
+fn main() {
+    println!("Problem with Stack pinning");
+    let mut x = MaybeSelfRef::new();
+    let mut y = MaybeSelfRef::new();
+    {
+        unsafe {
+            let mut x = Pin::new_unchecked(&mut x);
+            x.as_mut().init();
+            *x.as_mut().self_ref().unwrap() = 10;
+        };
+    }
+    swap(&mut x, &mut y);
+}
+```
+
+* On cache l'épinglage de `x` dans un bloc séparé.
+* Quand on quitte `{}` on peut échanger les références en `safe`
+* Ici `y` contiendra l'adresse de `x.data` et non celle de `y.data`
+
+## Le Pinning sur la pile 3/
+
+```rust
+fn main() {
+    let mut x = pin!(MaybeSelfRef::new());
+    MaybeSelfRef::init(x.as_mut());
+    println!("{}", x.as_ref().data);
+    *x.as_mut().self_ref().unwrap() = 2;
+    println!("{}", x.as_ref().data);
+}
+```
+
+* La macro `pin!()` nous sauve
+* Si on essaie de refaire l'exemple précent, on a une erreur de compilation
+* Si on veut absolument faire un `Pin` sur la pile, utiliser `pin!()`