|
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