Compare commits
	
		
			No commits in common. "da89562800ccb48bb1823784fcf0c6405ee08561" and "ebf0a894063fa68097a297d99e683237f33dcdef" have entirely different histories.
		
	
	
		
			da89562800
			...
			ebf0a89406
		
	
		
| @ -10,26 +10,24 @@ use std::thread; | |||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
|     let addr = "127.0.0.1:7878"; |     let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); | ||||||
|     let listener = TcpListener::bind(&addr).unwrap(); |  | ||||||
|     println!("Listening on http://{}", &addr); |  | ||||||
| 
 |  | ||||||
|     let counter = Arc::new(Mutex::new(0usize)); |     let counter = Arc::new(Mutex::new(0usize)); | ||||||
|  | 
 | ||||||
|     let tasks = ThreadPool::new(100); |     let tasks = ThreadPool::new(100); | ||||||
| 
 | 
 | ||||||
|     for stream in listener.incoming()/*.take(2)*/ { |     for stream in listener.incoming() { | ||||||
|         println!("accepted new connection"); |         let stream = stream.unwrap(); | ||||||
|  |         let counter = Arc::clone(&counter); | ||||||
| 
 | 
 | ||||||
|         if let Ok(stream) = stream { |         tasks.run(move || { | ||||||
|             let counter = Arc::clone(&counter); |             { | ||||||
| 
 |                 // in a subscope to release borrow automatically
 | ||||||
|             tasks.run(move || { |                 let mut count = counter.lock().unwrap(); | ||||||
|                 handle_connection(counter, stream); |                 *count += 1; | ||||||
|             }); |             } | ||||||
|         } |             handle_connection(counter, stream); | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     println!("Shutting down..."); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn handle_connection(counter: Arc<Mutex<usize>>, mut stream: TcpStream) { | fn handle_connection(counter: Arc<Mutex<usize>>, mut stream: TcpStream) { | ||||||
| @ -39,8 +37,7 @@ fn handle_connection(counter: Arc<Mutex<usize>>, mut stream: TcpStream) { | |||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
|         // in a subscope to unlock automatically
 |         // in a subscope to unlock automatically
 | ||||||
|         let mut count = counter.lock().unwrap(); |         let count = counter.lock().unwrap(); | ||||||
|         *count += 1; |  | ||||||
|         println!("Request: {}\n{}", count, String::from_utf8_lossy(&buffer[..])); |         println!("Request: {}\n{}", count, String::from_utf8_lossy(&buffer[..])); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										58
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -16,65 +16,29 @@ type Job = Box<dyn FnBox + Send + 'static>; | |||||||
| 
 | 
 | ||||||
| struct Worker { | struct Worker { | ||||||
|     id: usize, |     id: usize, | ||||||
|     thread: Option<thread::JoinHandle<()>>, |     thread: thread::JoinHandle<()>, | ||||||
| } |  | ||||||
| 
 |  | ||||||
| enum Message { |  | ||||||
|   NewJob(Job), |  | ||||||
|   Terminate, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Worker { | impl Worker { | ||||||
|     pub fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) -> Worker { |     pub fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { | ||||||
|         Worker { |         Worker { | ||||||
|             id, |             id, | ||||||
|             thread: Some(thread::spawn(move || { |             thread: thread::spawn(move || { | ||||||
|                 loop { |                 loop { | ||||||
|                     if let Ok(job) = receiver.lock().expect("unrecoverable poisened panicked thread state").recv() { |                     let job = receiver.lock().expect("unrecoverable poisened panicked thread state").recv().unwrap(); | ||||||
|                         match job { | 
 | ||||||
|                             Message::NewJob(job) => { |                     println!("such busy, so worker #{}!", id); | ||||||
|                                 println!("such busy, so worker #{}!", id); | 
 | ||||||
|                                 job.call_box(); |                     job.call_box(); | ||||||
|                             } |  | ||||||
|                             Message::Terminate => { |  | ||||||
|                                 println!("such sad, so dead #{}!", id); |  | ||||||
|                                 break; |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } else { |  | ||||||
|                         // TODO respawn? (unless in terminate mode)
 |  | ||||||
|                         // or why would the recv fail? already terminated?
 |  | ||||||
|                         // thread panic not handled?
 |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             })), |             }), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct ThreadPool { | pub struct ThreadPool { | ||||||
|     workers: Vec<Worker>, |     workers: Vec<Worker>, | ||||||
|     sender: mpsc::Sender<Message>, |     sender: mpsc::Sender<Job>, | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Drop for ThreadPool { |  | ||||||
|     fn drop(&mut self) { |  | ||||||
|         // Each worker will only receive Terminate once
 |  | ||||||
|         for _ in &mut self.workers { |  | ||||||
|             self.sender.send(Message::Terminate).unwrap(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // Each worker will join once complete
 |  | ||||||
|         for worker in &mut self.workers { |  | ||||||
|             println!("Shutting down worker {} ...", worker.id); |  | ||||||
| 
 |  | ||||||
|             if let Some(thread) = worker.thread.take() { |  | ||||||
|                 thread.join().unwrap(); |  | ||||||
|                 println!("Killed {}!", worker.id); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ThreadPool { | impl ThreadPool { | ||||||
| @ -100,6 +64,6 @@ impl ThreadPool { | |||||||
|     pub fn run<F: FnOnce() + Send + 'static>(&self, task: F) |     pub fn run<F: FnOnce() + Send + 'static>(&self, task: F) | ||||||
|     { |     { | ||||||
|         let task = Box::new(task); |         let task = Box::new(task); | ||||||
|         self.sender.send(Message::NewJob(task)).unwrap(); |         self.sender.send(task).unwrap(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user