diff --git a/exercices/06_coroutines/correction/Cargo.lock b/exercices/06_coroutines/correction/Cargo.lock
new file mode 100644
index 0000000000000000000000000000000000000000..76e0abc1a4a2e90a4658586216bcbf48cbc48e4b
--- /dev/null
+++ b/exercices/06_coroutines/correction/Cargo.lock
@@ -0,0 +1,113 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "coroutines"
+version = "0.1.0"
+dependencies = [
+ "mio",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+
+[[package]]
+name = "log"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
+
+[[package]]
+name = "mio"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/exercices/06_coroutines/correction/Cargo.toml b/exercices/06_coroutines/correction/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..36d20d352000db623ef0e5f8fcc0c9029d1eef39
--- /dev/null
+++ b/exercices/06_coroutines/correction/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "coroutines"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+mio = { version = "1.0.3", features = ["net", "os-poll"] }
diff --git a/exercices/06_coroutines/correction/src/future.rs b/exercices/06_coroutines/correction/src/future.rs
new file mode 100644
index 0000000000000000000000000000000000000000..92f98f344ee50014f22c54a5fbcdcd56c426dbf4
--- /dev/null
+++ b/exercices/06_coroutines/correction/src/future.rs
@@ -0,0 +1,60 @@
+pub trait Future {
+    type Output;
+
+    fn poll(&mut self) -> PollState<Self::Output>;
+}
+
+pub enum PollState<T> {
+    Ready(T),
+    NotReady,
+}
+
+pub struct JoinThree<F: Future> {
+    future1: (bool, F),
+    future2: (bool, F),
+    future3: (bool, F),
+}
+
+impl<F: Future> Future for JoinThree<F> {
+    type Output = ();
+    fn poll(&mut self) -> PollState<Self::Output> {
+        if !self.future1.0 {
+            match self.future1.1.poll() {
+                PollState::Ready(_) => {
+                    self.future1.0 = true;
+                }
+                PollState::NotReady => {}
+            }
+        }
+        if !self.future2.0 {
+            match self.future2.1.poll() {
+                PollState::Ready(_) => {
+                    self.future2.0 = true;
+                }
+                PollState::NotReady => {}
+            }
+        }
+
+        if !self.future3.0 {
+            match self.future3.1.poll() {
+                PollState::Ready(_) => {
+                    self.future3.0 = true;
+                }
+                PollState::NotReady => {}
+            }
+        }
+        if self.future1.0 && self.future2.0 && self.future3.0 {
+            PollState::Ready(())
+        } else {
+            PollState::NotReady
+        }
+    }
+}
+
+pub fn join_three<F: Future>(future1: F, future2: F, future3: F) -> JoinThree<F> {
+    JoinThree {
+        future1: (false, future1),
+        future2: (false, future2),
+        future3: (false, future3),
+    }
+}
diff --git a/exercices/06_coroutines/correction/src/http.rs b/exercices/06_coroutines/correction/src/http.rs
new file mode 100644
index 0000000000000000000000000000000000000000..575153b9cc0e86ef81868c1dcd0193dc6d61a7b3
--- /dev/null
+++ b/exercices/06_coroutines/correction/src/http.rs
@@ -0,0 +1,73 @@
+use crate::future::{Future, PollState};
+use std::io::{ErrorKind, Read, Write};
+
+fn get_req(path: &str) -> String {
+    format!(
+        "GET {path} HTTP/1.1\r\n\
+        Host: localhost\r\n\
+        Connection: close\r\n\
+        \r\n"
+    )
+}
+
+pub struct Http;
+
+impl Http {
+    pub fn get(path: &str) -> impl Future<Output = String> {
+        HttpGetFuture::new(path)
+    }
+}
+
+struct HttpGetFuture {
+    stream: Option<mio::net::TcpStream>,
+    buffer: Vec<u8>,
+    path: String,
+}
+
+impl HttpGetFuture {
+    fn new(path: &str) -> Self {
+        Self {
+            stream: None,
+            buffer: vec![],
+            path: String::from(path),
+        }
+    }
+    fn write_request(&mut self) {
+        let stream = std::net::TcpStream::connect("localhost:8080").unwrap();
+        stream.set_nonblocking(true).unwrap();
+        let mut stream = mio::net::TcpStream::from_std(stream);
+        stream.write_all(get_req(&self.path).as_bytes()).unwrap();
+        self.stream = Some(stream);
+    }
+}
+
+impl Future for HttpGetFuture {
+    type Output = String;
+    fn poll(&mut self) -> PollState<Self::Output> {
+        if self.stream.is_none() {
+            println!("First poll - start operation");
+            self.write_request();
+            return PollState::NotReady;
+        }
+        let mut buf = vec![0u8; 4096];
+        loop {
+            match self.stream.as_mut().unwrap().read(&mut buf) {
+                Ok(0) => {
+                    let s = String::from_utf8_lossy(&self.buffer);
+                    break PollState::Ready(String::from(s));
+                }
+                Ok(n) => {
+                    self.buffer.extend(&buf[0..n]);
+                    continue;
+                }
+                Err(e) if e.kind() == ErrorKind::WouldBlock => {
+                    break PollState::NotReady;
+                }
+                Err(e) if e.kind() == ErrorKind::Interrupted => {
+                    continue;
+                }
+                Err(e) => panic!("{e:?}"),
+            }
+        }
+    }
+}
diff --git a/exercices/06_coroutines/correction/src/lib.rs b/exercices/06_coroutines/correction/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5dfe1656cdcbf8b2b4bc1b31b8625d4879416947
--- /dev/null
+++ b/exercices/06_coroutines/correction/src/lib.rs
@@ -0,0 +1,2 @@
+pub mod future;
+pub mod http;
diff --git a/exercices/06_coroutines/correction/src/main.rs b/exercices/06_coroutines/correction/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0268320b5d858a7edc97f6bd3cb2a70403001014
--- /dev/null
+++ b/exercices/06_coroutines/correction/src/main.rs
@@ -0,0 +1,62 @@
+use std::time::Instant;
+
+use coroutines::future::{join_three, Future, PollState};
+use coroutines::http::Http;
+
+struct Coroutine {
+    state: CoroutineState,
+}
+
+impl Coroutine {
+    fn new(i: usize) -> Self {
+        Self {
+            state: CoroutineState::Start(i),
+        }
+    }
+}
+
+impl Future for Coroutine {
+    type Output = (); // We return nothing from the Coroutine Future
+
+    fn poll(&mut self) -> PollState<Self::Output> {
+        loop {
+            match self.state {
+                CoroutineState::Start(i) => {
+                    println!("Program starting");
+                    let path = format!("/{}/HelloWorld{i}", i * 1000);
+                    self.state = CoroutineState::Wait(Box::new(Http::get(&path)));
+                }
+                CoroutineState::Wait(ref mut future) => match future.poll() {
+                    PollState::Ready(txt) => {
+                        println!("{txt}");
+                        self.state = CoroutineState::Resolved;
+                        break PollState::Ready(());
+                    }
+                    PollState::NotReady => break PollState::NotReady,
+                },
+                CoroutineState::Resolved => panic!("Polled a resolved Future which is illegal!"),
+            }
+        }
+    }
+}
+
+enum CoroutineState {
+    Start(usize),
+    Wait(Box<dyn Future<Output = String>>),
+    Resolved,
+}
+
+fn async_main() -> impl Future<Output = ()> {
+    let future1 = Coroutine::new(1);
+    let future2 = Coroutine::new(2);
+    let future3 = Coroutine::new(3);
+
+    join_three(future1, future2, future3)
+}
+
+fn main() {
+    let start = Instant::now();
+    let mut future = async_main();
+    while let PollState::NotReady = future.poll() {}
+    println!("Elapsed time: {}", start.elapsed().as_millis());
+}