Last active
November 15, 2016 03:58
-
-
Save jorendorff/17b68de490d4ee5b47cd07a2826a8ce2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Some generic code for launching a service. | |
use std::sync::mpsc::{Sender, channel}; | |
use std::thread::{spawn, JoinHandle}; | |
/// Wrapper around a JoinHandle that automatically joins when dropped. | |
struct AutoJoinHandle(Option<JoinHandle<()>>); | |
impl Drop for AutoJoinHandle { | |
fn drop(&mut self) { | |
if let Some(thread) = self.0.take() { | |
thread.join().unwrap(); | |
} | |
} | |
} | |
/// A running Service. | |
/// | |
/// Note: Currently you can send a `Service<R>` value to another thread, | |
/// but you can't share it across many threads at once, a dumb restriction. | |
pub struct Service<Request> | |
{ | |
sender: Sender<Request>, | |
#[allow(dead_code)] // this is here for its behavior on drop | |
thread: AutoJoinHandle | |
} | |
impl<Request> Service<Request> | |
where Request: Send + 'static | |
{ | |
/// Launch a service. | |
/// | |
/// To stop the service, just drop the value. | |
/// | |
pub fn new<F>(mut f: F) -> Service<Request> | |
// Rules about what `f` must be. It must be a closure ... that takes a | |
// single `Request` argument ... that can be sent to another thread. | |
where F: FnMut(Request) + Send + 'static | |
{ | |
let (sender, receiver) = channel(); | |
let thread = spawn(move || { | |
for request in receiver { | |
f(request); | |
} | |
}); | |
Service { | |
thread: AutoJoinHandle(Some(thread)), | |
sender: sender | |
} | |
} | |
/// Send a request to the service. | |
pub fn cast(&self, request: Request) { | |
self.sender.send(request).unwrap(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Some generic code for launching a service. | |
use std::sync::Mutex; | |
use std::sync::mpsc::{Sender, channel}; | |
use std::thread::{spawn, JoinHandle}; | |
/// Wrapper around a JoinHandle that automatically joins when dropped. | |
struct AutoJoinHandle(Option<JoinHandle<()>>); | |
impl Drop for AutoJoinHandle { | |
fn drop(&mut self) { | |
if let Some(thread) = self.0.take() { | |
thread.join().unwrap(); | |
} | |
} | |
} | |
/// A running Service. | |
pub struct Service<Request> | |
{ | |
sender: Mutex<Sender<Request>>, | |
#[allow(dead_code)] // this is here for its behavior on drop | |
thread: AutoJoinHandle | |
} | |
impl<Request> Service<Request> | |
where Request: Send + 'static | |
{ | |
/// Launch a service. | |
/// | |
/// To stop the service, just drop the value. | |
/// | |
pub fn new<F>(mut f: F) -> Service<Request> | |
// Rules about what `f` must be. It must be a closure ... that takes a | |
// single `Request` argument ... that can be sent to another thread. | |
where F: FnMut(Request) + Send + 'static | |
{ | |
let (sender, receiver) = channel(); | |
let thread = spawn(move || { | |
for request in receiver { | |
f(request); | |
} | |
}); | |
Service { | |
sender: Mutex::new(sender), | |
thread: AutoJoinHandle(Some(thread)) | |
} | |
} | |
/// Send a request to the service. | |
pub fn cast(&self, request: Request) { | |
let sender = self.sender.lock().unwrap(); | |
sender.send(request).unwrap(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment