|
26 | 26 | html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png" |
27 | 27 | )] |
28 | 28 |
|
29 | | -use std::cell::RefCell; |
30 | 29 | use std::fmt; |
31 | 30 | use std::future::Future; |
32 | 31 | use std::marker::PhantomData; |
@@ -236,56 +235,29 @@ impl<'a> Executor<'a> { |
236 | 235 | let runner = Runner::new(self.state()); |
237 | 236 | let mut rng = fastrand::Rng::new(); |
238 | 237 |
|
239 | | - // Set the local queue while we're running. |
240 | | - LocalQueue::set(self.state(), &runner.local, { |
241 | | - let runner = &runner; |
242 | | - async move { |
243 | | - // A future that runs tasks forever. |
244 | | - let run_forever = async { |
245 | | - loop { |
246 | | - for _ in 0..200 { |
247 | | - let runnable = runner.runnable(&mut rng).await; |
248 | | - runnable.run(); |
249 | | - } |
250 | | - future::yield_now().await; |
251 | | - } |
252 | | - }; |
253 | | - |
254 | | - // Run `future` and `run_forever` concurrently until `future` completes. |
255 | | - future.or(run_forever).await |
| 238 | + // A future that runs tasks forever. |
| 239 | + let run_forever = async { |
| 240 | + loop { |
| 241 | + for _ in 0..200 { |
| 242 | + let runnable = runner.runnable(&mut rng).await; |
| 243 | + runnable.run(); |
| 244 | + } |
| 245 | + future::yield_now().await; |
256 | 246 | } |
257 | | - }) |
258 | | - .await |
| 247 | + }; |
| 248 | + |
| 249 | + // Run `future` and `run_forever` concurrently until `future` completes. |
| 250 | + future.or(run_forever).await |
259 | 251 | } |
260 | 252 |
|
261 | 253 | /// Returns a function that schedules a runnable task when it gets woken up. |
262 | 254 | fn schedule(&self) -> impl Fn(Runnable) + Send + Sync + 'static { |
263 | 255 | let state = self.state().clone(); |
264 | 256 |
|
265 | | - // If possible, push into the current local queue and notify the ticker. |
| 257 | + // TODO: If possible, push into the current local queue and notify the ticker. |
266 | 258 | move |runnable| { |
267 | | - let mut runnable = Some(runnable); |
268 | | - |
269 | | - // Try to push into the local queue. |
270 | | - LocalQueue::with(|local_queue| { |
271 | | - // Make sure that we don't accidentally push to an executor that isn't ours. |
272 | | - if local_queue.state != &*state as *const State as usize { |
273 | | - return; |
274 | | - } |
275 | | - |
276 | | - if let Err(e) = local_queue.queue.push(runnable.take().unwrap()) { |
277 | | - runnable = Some(e.into_inner()); |
278 | | - return; |
279 | | - } |
280 | | - |
281 | | - local_queue.waker.wake_by_ref(); |
282 | | - }); |
283 | | - |
284 | | - // If the local queue push failed, just push to the global queue. |
285 | | - if let Some(runnable) = runnable { |
286 | | - state.queue.push(runnable).unwrap(); |
287 | | - state.notify(); |
288 | | - } |
| 259 | + state.queue.push(runnable).unwrap(); |
| 260 | + state.notify(); |
289 | 261 | } |
290 | 262 | } |
291 | 263 |
|
@@ -853,106 +825,6 @@ impl Drop for Runner<'_> { |
853 | 825 | } |
854 | 826 | } |
855 | 827 |
|
856 | | -/// The state of the currently running local queue. |
857 | | -struct LocalQueue { |
858 | | - /// The pointer to the state of the executor. |
859 | | - /// |
860 | | - /// Used to make sure we don't push runnables to the wrong executor. |
861 | | - state: usize, |
862 | | - |
863 | | - /// The concurrent queue. |
864 | | - queue: Arc<ConcurrentQueue<Runnable>>, |
865 | | - |
866 | | - /// The waker for the runnable. |
867 | | - waker: Waker, |
868 | | -} |
869 | | - |
870 | | -impl LocalQueue { |
871 | | - /// Run a function with the current local queue. |
872 | | - fn with<R>(f: impl FnOnce(&LocalQueue) -> R) -> Option<R> { |
873 | | - std::thread_local! { |
874 | | - /// The current local queue. |
875 | | - static LOCAL_QUEUE: RefCell<Option<LocalQueue>> = RefCell::new(None); |
876 | | - } |
877 | | - |
878 | | - impl LocalQueue { |
879 | | - /// Run a function with a set local queue. |
880 | | - async fn set<F>( |
881 | | - state: &State, |
882 | | - queue: &Arc<ConcurrentQueue<Runnable>>, |
883 | | - fut: F, |
884 | | - ) -> F::Output |
885 | | - where |
886 | | - F: Future, |
887 | | - { |
888 | | - // Make the `LocalQueue` structure. |
889 | | - let make_local_queue = |waker: &Waker| LocalQueue { |
890 | | - state: state as *const State as usize, |
891 | | - queue: queue.clone(), |
892 | | - waker: waker.clone(), |
893 | | - }; |
894 | | - |
895 | | - // Store the local queue and the current waker. |
896 | | - let mut old = with_waker(|waker| { |
897 | | - LOCAL_QUEUE.with(move |slot| slot.borrow_mut().replace(make_local_queue(waker))) |
898 | | - }) |
899 | | - .await; |
900 | | - |
901 | | - // Restore the old local queue on drop. |
902 | | - let _guard = CallOnDrop(move || { |
903 | | - let old = old.take(); |
904 | | - let _ = LOCAL_QUEUE.try_with(move |slot| { |
905 | | - *slot.borrow_mut() = old; |
906 | | - }); |
907 | | - }); |
908 | | - |
909 | | - // Pin the future. |
910 | | - futures_lite::pin!(fut); |
911 | | - |
912 | | - // Run it such that the waker is updated every time it's polled. |
913 | | - future::poll_fn(move |cx| { |
914 | | - LOCAL_QUEUE |
915 | | - .try_with({ |
916 | | - let waker = cx.waker(); |
917 | | - move |slot| { |
918 | | - let mut slot = slot.borrow_mut(); |
919 | | - let qaw = match slot.as_mut() { |
920 | | - None => { |
921 | | - // Another local queue dropped itself and replaced with None, |
922 | | - // we can take its place! |
923 | | - *slot = Some(make_local_queue(waker)); |
924 | | - return; |
925 | | - } |
926 | | - Some(qaw) => qaw, |
927 | | - }; |
928 | | - |
929 | | - // If we've been replaced, just ignore the slot. |
930 | | - if !Arc::ptr_eq(&qaw.queue, queue) { |
931 | | - return; |
932 | | - } |
933 | | - |
934 | | - // Update the waker, if it has changed. |
935 | | - if !qaw.waker.will_wake(waker) { |
936 | | - qaw.waker = waker.clone(); |
937 | | - } |
938 | | - } |
939 | | - }) |
940 | | - .ok(); |
941 | | - |
942 | | - // Poll the future. |
943 | | - fut.as_mut().poll(cx) |
944 | | - }) |
945 | | - .await |
946 | | - } |
947 | | - } |
948 | | - |
949 | | - LOCAL_QUEUE |
950 | | - .try_with(|local_queue| local_queue.borrow().as_ref().map(f)) |
951 | | - .ok() |
952 | | - .flatten() |
953 | | - } |
954 | | -} |
955 | | - |
956 | 828 | /// Steals some items from one queue into another. |
957 | 829 | fn steal<T>(src: &ConcurrentQueue<T>, dest: &ConcurrentQueue<T>) { |
958 | 830 | // Half of `src`'s length rounded up. |
@@ -1053,15 +925,6 @@ impl<F: FnMut()> Drop for CallOnDrop<F> { |
1053 | 925 | } |
1054 | 926 | } |
1055 | 927 |
|
1056 | | -/// Run a closure with the current waker. |
1057 | | -fn with_waker<F: FnOnce(&Waker) -> R, R>(f: F) -> impl Future<Output = R> { |
1058 | | - let mut f = Some(f); |
1059 | | - future::poll_fn(move |cx| { |
1060 | | - let f = f.take().unwrap(); |
1061 | | - Poll::Ready(f(cx.waker())) |
1062 | | - }) |
1063 | | -} |
1064 | | - |
1065 | 928 | fn _ensure_send_and_sync() { |
1066 | 929 | use futures_lite::future::pending; |
1067 | 930 |
|
|
0 commit comments