redesign
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="sidebar-visible no-js light">
|
||||
<html lang="en" class="sidebar-visible no-js">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<body class="light">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script type="text/javascript">
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||||
var default_theme = "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
@@ -60,11 +60,8 @@
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('no-js')
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
html.classList.add('js');
|
||||
document.body.className = theme;
|
||||
document.querySelector('html').className = theme + ' js';
|
||||
</script>
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
@@ -80,8 +77,8 @@
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div id="sidebar-scrollbox" class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="expanded "><a href="0_0_introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="expanded "><a href="0_1_background_information.html"><strong aria-hidden="true">2.</strong> Some background information</a></li><li class="expanded "><a href="0_2_naive_implementation.html" class="active"><strong aria-hidden="true">3.</strong> Naive example</a></li><li class="expanded "><a href="0_3_proper_waker.html"><strong aria-hidden="true">4.</strong> Proper Waker</a></li><li class="expanded "><a href="0_4_proper_future.html"><strong aria-hidden="true">5.</strong> Proper Future</a></li><li class="expanded "><a href="0_5_async_wait.html"><strong aria-hidden="true">6.</strong> Supporting async/await</a></li><li class="expanded "><a href="0_6_concurrent_futures.html"><strong aria-hidden="true">7.</strong> Bonus: concurrent futures</a></li></ol>
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li><a href="0_0_introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li><a href="0_1_background_information.html"><strong aria-hidden="true">2.</strong> Some background information</a></li><li><ol class="section"><li><a href="0_1_1_trait_objects.html"><strong aria-hidden="true">2.1.</strong> Trait objects and fat pointers</a></li><li><a href="0_1_2_generators_pin.html"><strong aria-hidden="true">2.2.</strong> Generators and Pin</a></li></ol></li><li><a href="0_2_naive_implementation.html" class="active"><strong aria-hidden="true">3.</strong> Naive example</a></li><li><a href="0_3_proper_waker.html"><strong aria-hidden="true">4.</strong> Proper Waker</a></li><li><a href="0_4_proper_future.html"><strong aria-hidden="true">5.</strong> Proper Future</a></li><li><a href="0_5_async_wait.html"><strong aria-hidden="true">6.</strong> Supporting async/await</a></li><li><a href="0_6_concurrent_futures.html"><strong aria-hidden="true">7.</strong> Bonus: concurrent futures</a></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||||
</nav>
|
||||
@@ -297,125 +294,125 @@ fn main() {
|
||||
|
||||
executor_run(reactor, readylist);
|
||||
}
|
||||
<span class="boring">// ====== EXECUTOR ======
|
||||
</span><span class="boring">fn executor_run(mut reactor: Reactor, rl: Arc<Mutex<Vec<usize>>>) {
|
||||
</span><span class="boring"> let start = Instant::now();
|
||||
</span><span class="boring"> loop {
|
||||
</span><span class="boring"> let mut rl_locked = rl.lock().unwrap();
|
||||
</span><span class="boring"> while let Some(event) = rl_locked.pop() {
|
||||
</span><span class="boring"> let dur = (Instant::now() - start).as_secs_f32();
|
||||
</span><span class="boring"> println!("Event {} just happened at time: {:.2}.", event, dur);
|
||||
</span><span class="boring"> reactor.outstanding.fetch_sub(1, Ordering::Relaxed);
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> drop(rl_locked);
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> if reactor.outstanding.load(Ordering::Relaxed) == 0 {
|
||||
</span><span class="boring"> reactor.close();
|
||||
</span><span class="boring"> break;
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> thread::park();
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">// ====== "FUTURE" IMPL ======
|
||||
</span><span class="boring">#[derive(Debug)]
|
||||
</span><span class="boring">struct MyWaker {
|
||||
</span><span class="boring"> id: usize,
|
||||
</span><span class="boring"> thread: thread::Thread,
|
||||
</span><span class="boring"> readylist: Arc<Mutex<Vec<usize>>>,
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">impl MyWaker {
|
||||
</span><span class="boring"> fn new(id: usize, thread: thread::Thread, readylist: Arc<Mutex<Vec<usize>>>) -> Self {
|
||||
</span><span class="boring"> MyWaker {
|
||||
</span><span class="boring"> id,
|
||||
</span><span class="boring"> thread,
|
||||
</span><span class="boring"> readylist,
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> fn wake(&self) {
|
||||
</span><span class="boring"> self.readylist.lock().map(|mut rl| rl.push(self.id)).unwrap();
|
||||
</span><span class="boring"> self.thread.unpark();
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">#[derive(Debug, Clone)]
|
||||
</span><span class="boring">pub struct Task {
|
||||
</span><span class="boring"> id: usize,
|
||||
</span><span class="boring"> pending: bool,
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">// ===== REACTOR =====
|
||||
</span><span class="boring">struct Reactor {
|
||||
</span><span class="boring"> dispatcher: Sender<Event>,
|
||||
</span><span class="boring"> handle: Option<JoinHandle<()>>,
|
||||
</span><span class="boring"> outstanding: AtomicUsize,
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">#[derive(Debug)]
|
||||
</span><span class="boring">enum Event {
|
||||
</span><span class="boring"> Close,
|
||||
</span><span class="boring"> Simple(MyWaker, u64),
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">impl Reactor {
|
||||
</span><span class="boring"> fn new() -> Self {
|
||||
</span><span class="boring"> let (tx, rx) = channel::<Event>();
|
||||
</span><span class="boring"> let mut handles = vec![];
|
||||
</span><span class="boring"> let handle = thread::spawn(move || {
|
||||
</span><span class="boring"> // This simulates some I/O resource
|
||||
</span><span class="boring"> for event in rx {
|
||||
</span><span class="boring"> match event {
|
||||
</span><span class="boring"> Event::Close => break,
|
||||
</span><span class="boring"> Event::Simple(mywaker, duration) => {
|
||||
</span><span class="boring"> let event_handle = thread::spawn(move || {
|
||||
</span><span class="boring"> thread::sleep(Duration::from_secs(duration));
|
||||
</span><span class="boring"> mywaker.wake();
|
||||
</span><span class="boring"> });
|
||||
</span><span class="boring"> handles.push(event_handle);
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> for handle in handles {
|
||||
</span><span class="boring"> handle.join().unwrap();
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> });
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> Reactor {
|
||||
</span><span class="boring"> dispatcher: tx,
|
||||
</span><span class="boring"> handle: Some(handle),
|
||||
</span><span class="boring"> outstanding: AtomicUsize::new(0),
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> fn register(&mut self, duration: u64, mywaker: MyWaker) {
|
||||
</span><span class="boring"> self.dispatcher
|
||||
</span><span class="boring"> .send(Event::Simple(mywaker, duration))
|
||||
</span><span class="boring"> .unwrap();
|
||||
</span><span class="boring"> self.outstanding.fetch_add(1, Ordering::Relaxed);
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">
|
||||
</span><span class="boring"> fn close(&mut self) {
|
||||
</span><span class="boring"> self.dispatcher.send(Event::Close).unwrap();
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">}
|
||||
</span><span class="boring">
|
||||
</span><span class="boring">impl Drop for Reactor {
|
||||
</span><span class="boring"> fn drop(&mut self) {
|
||||
</span><span class="boring"> self.handle.take().map(|h| h.join().unwrap()).unwrap();
|
||||
</span><span class="boring"> }
|
||||
</span><span class="boring">}
|
||||
</span></code></pre></pre>
|
||||
# // ====== EXECUTOR ======
|
||||
# fn executor_run(mut reactor: Reactor, rl: Arc<Mutex<Vec<usize>>>) {
|
||||
# let start = Instant::now();
|
||||
# loop {
|
||||
# let mut rl_locked = rl.lock().unwrap();
|
||||
# while let Some(event) = rl_locked.pop() {
|
||||
# let dur = (Instant::now() - start).as_secs_f32();
|
||||
# println!("Event {} just happened at time: {:.2}.", event, dur);
|
||||
# reactor.outstanding.fetch_sub(1, Ordering::Relaxed);
|
||||
# }
|
||||
# drop(rl_locked);
|
||||
#
|
||||
# if reactor.outstanding.load(Ordering::Relaxed) == 0 {
|
||||
# reactor.close();
|
||||
# break;
|
||||
# }
|
||||
#
|
||||
# thread::park();
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# // ====== "FUTURE" IMPL ======
|
||||
# #[derive(Debug)]
|
||||
# struct MyWaker {
|
||||
# id: usize,
|
||||
# thread: thread::Thread,
|
||||
# readylist: Arc<Mutex<Vec<usize>>>,
|
||||
# }
|
||||
#
|
||||
# impl MyWaker {
|
||||
# fn new(id: usize, thread: thread::Thread, readylist: Arc<Mutex<Vec<usize>>>) -> Self {
|
||||
# MyWaker {
|
||||
# id,
|
||||
# thread,
|
||||
# readylist,
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# fn wake(&self) {
|
||||
# self.readylist.lock().map(|mut rl| rl.push(self.id)).unwrap();
|
||||
# self.thread.unpark();
|
||||
# }
|
||||
# }
|
||||
#
|
||||
#
|
||||
# #[derive(Debug, Clone)]
|
||||
# pub struct Task {
|
||||
# id: usize,
|
||||
# pending: bool,
|
||||
# }
|
||||
#
|
||||
# // ===== REACTOR =====
|
||||
# struct Reactor {
|
||||
# dispatcher: Sender<Event>,
|
||||
# handle: Option<JoinHandle<()>>,
|
||||
# outstanding: AtomicUsize,
|
||||
# }
|
||||
# #[derive(Debug)]
|
||||
# enum Event {
|
||||
# Close,
|
||||
# Simple(MyWaker, u64),
|
||||
# }
|
||||
#
|
||||
# impl Reactor {
|
||||
# fn new() -> Self {
|
||||
# let (tx, rx) = channel::<Event>();
|
||||
# let mut handles = vec![];
|
||||
# let handle = thread::spawn(move || {
|
||||
# // This simulates some I/O resource
|
||||
# for event in rx {
|
||||
# match event {
|
||||
# Event::Close => break,
|
||||
# Event::Simple(mywaker, duration) => {
|
||||
# let event_handle = thread::spawn(move || {
|
||||
# thread::sleep(Duration::from_secs(duration));
|
||||
# mywaker.wake();
|
||||
# });
|
||||
# handles.push(event_handle);
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# for handle in handles {
|
||||
# handle.join().unwrap();
|
||||
# }
|
||||
# });
|
||||
#
|
||||
# Reactor {
|
||||
# dispatcher: tx,
|
||||
# handle: Some(handle),
|
||||
# outstanding: AtomicUsize::new(0),
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# fn register(&mut self, duration: u64, mywaker: MyWaker) {
|
||||
# self.dispatcher
|
||||
# .send(Event::Simple(mywaker, duration))
|
||||
# .unwrap();
|
||||
# self.outstanding.fetch_add(1, Ordering::Relaxed);
|
||||
# }
|
||||
#
|
||||
# fn close(&mut self) {
|
||||
# self.dispatcher.send(Event::Close).unwrap();
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# impl Drop for Reactor {
|
||||
# fn drop(&mut self) {
|
||||
# self.handle.take().map(|h| h.join().unwrap()).unwrap();
|
||||
# }
|
||||
# }
|
||||
</code></pre></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="prev" href="0_1_background_information.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a rel="prev" href="0_1_2_generators_pin.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
@@ -433,7 +430,7 @@ fn main() {
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a href="0_1_background_information.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<a href="0_1_2_generators_pin.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
@@ -448,30 +445,7 @@ fn main() {
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Livereload script (if served using the cli tool) -->
|
||||
<script type="text/javascript">
|
||||
var socket = new WebSocket("ws://localhost:3001");
|
||||
socket.onmessage = function (event) {
|
||||
if (event.data === "reload") {
|
||||
socket.close();
|
||||
location.reload(true); // force reload from server (not from cache)
|
||||
}
|
||||
};
|
||||
|
||||
window.onbeforeunload = function() {
|
||||
socket.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
window.playpen_copyable = true;
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user