You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lib.rs 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. use std::thread;
  2. use std::sync::{mpsc, Mutex, Arc};
  3. enum Message {
  4. NewJob(Job),
  5. Terminate
  6. }
  7. pub struct ThreadPool{
  8. workers: Vec<Worker>,
  9. sender: mpsc::Sender<Message>,
  10. }
  11. type Job = Box<dyn FnOnce() + Send + 'static>;
  12. impl ThreadPool {
  13. pub fn new(size: usize) -> ThreadPool {
  14. assert!(size > 0);
  15. let (sender, receiver) = mpsc::channel();
  16. let receiver = Arc::new(Mutex::new(receiver));
  17. let mut workers = Vec::with_capacity(size);
  18. for id in 0..size {
  19. workers.push(Worker::new(id, Arc::clone(&receiver)));
  20. }
  21. ThreadPool {
  22. workers,
  23. sender,
  24. }
  25. }
  26. pub fn execute<F>(&self, f: F)
  27. where
  28. F: FnOnce() + Send + 'static
  29. {
  30. let job = Box::new(f);
  31. self.sender.send(Message::NewJob(job)).unwrap();
  32. }
  33. // pub fn spawn<F, T>(f: F) -> JoinHandle<T>
  34. // where
  35. // F: FnOnce() -> T + Send + 'static,
  36. // T: Send + 'static
  37. // {
  38. // }
  39. }
  40. impl Drop for ThreadPool {
  41. fn drop(&mut self) {
  42. println!("Sending terminate message to all workers.");
  43. for _ in &mut self.workers {
  44. self.sender.send(Message::Terminate).unwrap();
  45. }
  46. println!("Shutting down all workers.");
  47. for worker in &mut self.workers {
  48. println!("Shutting down worker {}.", worker.id);
  49. if let Some(thread) = worker.thread.take() {
  50. thread.join().unwrap();
  51. }
  52. }
  53. }
  54. }
  55. struct Worker {
  56. id: usize,
  57. thread: Option<thread::JoinHandle<()>>,
  58. }
  59. impl Worker {
  60. fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) ->
  61. Worker {
  62. let thread = thread::spawn(move ||{
  63. loop {
  64. let message = receiver.lock().unwrap().recv().unwrap();
  65. match message {
  66. Message::NewJob(job) => {
  67. println!("Worker {} got a job; executing.", id);
  68. job();
  69. },
  70. Message::Terminate => {
  71. println!("Worker {} was told to terminate.", id);
  72. break;
  73. },
  74. }
  75. }
  76. });
  77. Worker {
  78. id,
  79. thread: Some(thread),
  80. }
  81. }
  82. }
  83. pub struct Response {
  84. header: String,
  85. content: String,
  86. }
  87. impl Response {
  88. pub fn new(hdr: &str, cnt: &str) -> Response {
  89. Response {
  90. header: String::from(hdr),
  91. content: String::from(cnt),
  92. }
  93. }
  94. pub fn set_header(&mut self, hdr: &str) {
  95. self.header = String::from(hdr);
  96. }
  97. pub fn get_header(&self) -> &String {
  98. &self.header
  99. }
  100. pub fn set_content(&mut self, cnt: &str) {
  101. self.content = String::from(cnt);
  102. }
  103. pub fn add_content(&mut self, cnt: &str) {
  104. self.content.push_str(cnt);
  105. }
  106. pub fn get_content(&self) -> &String {
  107. &self.content
  108. }
  109. }
  110. #[derive(Copy, Clone)]
  111. pub struct Route {
  112. path: &'static str,
  113. action: fn(&&str, &mut Response),
  114. }
  115. impl Route {
  116. pub fn new(p: &'static str, a: fn(&&str, &mut Response)) -> Route {
  117. Route {
  118. path: p,
  119. action: a,
  120. }
  121. }
  122. pub fn set_path(&mut self, p: &'static str) {
  123. self.path = p;
  124. }
  125. pub fn get_path(&mut self) -> &'static str {
  126. &self.path
  127. }
  128. pub fn set_action(&mut self, a: fn(&&str, &mut Response)) {
  129. self.action = a;
  130. }
  131. pub fn get_action(&mut self) -> fn(&&str, &mut Response) {
  132. self.action
  133. }
  134. }