|
1 | 1 | #![cfg_attr(loom, allow(unused_imports))] |
2 | 2 |
|
| 3 | +use crate::runtime::blocking::BlockingPool; |
3 | 4 | use crate::runtime::handle::Handle; |
4 | | -use crate::runtime::{blocking, driver, Callback, HistogramBuilder, Runtime, TaskCallback}; |
| 5 | +use crate::runtime::scheduler::CurrentThread; |
| 6 | +use crate::runtime::{blocking, driver, Callback, HistogramBuilder, Runtime}; |
5 | 7 | #[cfg(tokio_unstable)] |
6 | | -use crate::runtime::{metrics::HistogramConfiguration, LocalOptions, LocalRuntime, TaskMeta}; |
| 8 | +use crate::runtime::{ |
| 9 | + metrics::HistogramConfiguration, LocalOptions, LocalRuntime, OptionalTaskHooksFactory, |
| 10 | + TaskHookHarnessFactory, |
| 11 | +}; |
7 | 12 | use crate::util::rand::{RngSeed, RngSeedGenerator}; |
8 | | - |
9 | | -use crate::runtime::blocking::BlockingPool; |
10 | | -use crate::runtime::scheduler::CurrentThread; |
11 | 13 | use std::fmt; |
12 | 14 | use std::io; |
| 15 | +#[cfg(tokio_unstable)] |
| 16 | +use std::sync::Arc; |
13 | 17 | use std::thread::ThreadId; |
14 | 18 | use std::time::Duration; |
15 | 19 |
|
@@ -85,19 +89,8 @@ pub struct Builder { |
85 | 89 | /// To run after each thread is unparked. |
86 | 90 | pub(super) after_unpark: Option<Callback>, |
87 | 91 |
|
88 | | - /// To run before each task is spawned. |
89 | | - pub(super) before_spawn: Option<TaskCallback>, |
90 | | - |
91 | | - /// To run before each poll |
92 | 92 | #[cfg(tokio_unstable)] |
93 | | - pub(super) before_poll: Option<TaskCallback>, |
94 | | - |
95 | | - /// To run after each poll |
96 | | - #[cfg(tokio_unstable)] |
97 | | - pub(super) after_poll: Option<TaskCallback>, |
98 | | - |
99 | | - /// To run after each task is terminated. |
100 | | - pub(super) after_termination: Option<TaskCallback>, |
| 93 | + pub(super) task_hook_harness_factory: OptionalTaskHooksFactory, |
101 | 94 |
|
102 | 95 | /// Customizable keep alive timeout for `BlockingPool` |
103 | 96 | pub(super) keep_alive: Option<Duration>, |
@@ -287,13 +280,8 @@ impl Builder { |
287 | 280 | before_park: None, |
288 | 281 | after_unpark: None, |
289 | 282 |
|
290 | | - before_spawn: None, |
291 | | - after_termination: None, |
292 | | - |
293 | 283 | #[cfg(tokio_unstable)] |
294 | | - before_poll: None, |
295 | | - #[cfg(tokio_unstable)] |
296 | | - after_poll: None, |
| 284 | + task_hook_harness_factory: None, |
297 | 285 |
|
298 | 286 | keep_alive: None, |
299 | 287 |
|
@@ -685,188 +673,19 @@ impl Builder { |
685 | 673 | self |
686 | 674 | } |
687 | 675 |
|
688 | | - /// Executes function `f` just before a task is spawned. |
689 | | - /// |
690 | | - /// `f` is called within the Tokio context, so functions like |
691 | | - /// [`tokio::spawn`](crate::spawn) can be called, and may result in this callback being |
692 | | - /// invoked immediately. |
693 | | - /// |
694 | | - /// This can be used for bookkeeping or monitoring purposes. |
695 | | - /// |
696 | | - /// Note: There can only be one spawn callback for a runtime; calling this function more |
697 | | - /// than once replaces the last callback defined, rather than adding to it. |
698 | | - /// |
699 | | - /// This *does not* support [`LocalSet`](crate::task::LocalSet) at this time. |
700 | | - /// |
701 | | - /// **Note**: This is an [unstable API][unstable]. The public API of this type |
702 | | - /// may break in 1.x releases. See [the documentation on unstable |
703 | | - /// features][unstable] for details. |
704 | | - /// |
705 | | - /// [unstable]: crate#unstable-features |
706 | | - /// |
707 | | - /// # Examples |
708 | | - /// |
709 | | - /// ``` |
710 | | - /// # use tokio::runtime; |
711 | | - /// # pub fn main() { |
712 | | - /// let runtime = runtime::Builder::new_current_thread() |
713 | | - /// .on_task_spawn(|_| { |
714 | | - /// println!("spawning task"); |
715 | | - /// }) |
716 | | - /// .build() |
717 | | - /// .unwrap(); |
718 | | - /// |
719 | | - /// runtime.block_on(async { |
720 | | - /// tokio::task::spawn(std::future::ready(())); |
721 | | - /// |
722 | | - /// for _ in 0..64 { |
723 | | - /// tokio::task::yield_now().await; |
724 | | - /// } |
725 | | - /// }) |
726 | | - /// # } |
727 | | - /// ``` |
728 | | - #[cfg(all(not(loom), tokio_unstable))] |
729 | | - #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] |
730 | | - pub fn on_task_spawn<F>(&mut self, f: F) -> &mut Self |
731 | | - where |
732 | | - F: Fn(&TaskMeta<'_>) + Send + Sync + 'static, |
733 | | - { |
734 | | - self.before_spawn = Some(std::sync::Arc::new(f)); |
735 | | - self |
736 | | - } |
737 | | - |
738 | | - /// Executes function `f` just before a task is polled |
739 | | - /// |
740 | | - /// `f` is called within the Tokio context, so functions like |
741 | | - /// [`tokio::spawn`](crate::spawn) can be called, and may result in this callback being |
742 | | - /// invoked immediately. |
743 | | - /// |
744 | | - /// **Note**: This is an [unstable API][unstable]. The public API of this type |
745 | | - /// may break in 1.x releases. See [the documentation on unstable |
746 | | - /// features][unstable] for details. |
747 | | - /// |
748 | | - /// [unstable]: crate#unstable-features |
749 | | - /// |
750 | | - /// # Examples |
751 | | - /// |
752 | | - /// ``` |
753 | | - /// # use std::sync::{atomic::AtomicUsize, Arc}; |
754 | | - /// # use tokio::task::yield_now; |
755 | | - /// # pub fn main() { |
756 | | - /// let poll_start_counter = Arc::new(AtomicUsize::new(0)); |
757 | | - /// let poll_start = poll_start_counter.clone(); |
758 | | - /// let rt = tokio::runtime::Builder::new_multi_thread() |
759 | | - /// .enable_all() |
760 | | - /// .on_before_task_poll(move |meta| { |
761 | | - /// println!("task {} is about to be polled", meta.id()) |
762 | | - /// }) |
763 | | - /// .build() |
764 | | - /// .unwrap(); |
765 | | - /// let task = rt.spawn(async { |
766 | | - /// yield_now().await; |
767 | | - /// }); |
768 | | - /// let _ = rt.block_on(task); |
769 | | - /// |
770 | | - /// # } |
771 | | - /// ``` |
772 | | - #[cfg(tokio_unstable)] |
773 | | - pub fn on_before_task_poll<F>(&mut self, f: F) -> &mut Self |
774 | | - where |
775 | | - F: Fn(&TaskMeta<'_>) + Send + Sync + 'static, |
776 | | - { |
777 | | - self.before_poll = Some(std::sync::Arc::new(f)); |
778 | | - self |
779 | | - } |
780 | | - |
781 | | - /// Executes function `f` just after a task is polled |
782 | | - /// |
783 | | - /// `f` is called within the Tokio context, so functions like |
784 | | - /// [`tokio::spawn`](crate::spawn) can be called, and may result in this callback being |
785 | | - /// invoked immediately. |
786 | | - /// |
787 | | - /// **Note**: This is an [unstable API][unstable]. The public API of this type |
788 | | - /// may break in 1.x releases. See [the documentation on unstable |
789 | | - /// features][unstable] for details. |
790 | | - /// |
791 | | - /// [unstable]: crate#unstable-features |
792 | | - /// |
793 | | - /// # Examples |
794 | | - /// |
795 | | - /// ``` |
796 | | - /// # use std::sync::{atomic::AtomicUsize, Arc}; |
797 | | - /// # use tokio::task::yield_now; |
798 | | - /// # pub fn main() { |
799 | | - /// let poll_stop_counter = Arc::new(AtomicUsize::new(0)); |
800 | | - /// let poll_stop = poll_stop_counter.clone(); |
801 | | - /// let rt = tokio::runtime::Builder::new_multi_thread() |
802 | | - /// .enable_all() |
803 | | - /// .on_after_task_poll(move |meta| { |
804 | | - /// println!("task {} completed polling", meta.id()); |
805 | | - /// }) |
806 | | - /// .build() |
807 | | - /// .unwrap(); |
808 | | - /// let task = rt.spawn(async { |
809 | | - /// yield_now().await; |
810 | | - /// }); |
811 | | - /// let _ = rt.block_on(task); |
812 | | - /// |
813 | | - /// # } |
814 | | - /// ``` |
815 | | - #[cfg(tokio_unstable)] |
816 | | - pub fn on_after_task_poll<F>(&mut self, f: F) -> &mut Self |
817 | | - where |
818 | | - F: Fn(&TaskMeta<'_>) + Send + Sync + 'static, |
819 | | - { |
820 | | - self.after_poll = Some(std::sync::Arc::new(f)); |
821 | | - self |
822 | | - } |
823 | | - |
824 | | - /// Executes function `f` just after a task is terminated. |
825 | | - /// |
826 | | - /// `f` is called within the Tokio context, so functions like |
827 | | - /// [`tokio::spawn`](crate::spawn) can be called. |
828 | | - /// |
829 | | - /// This can be used for bookkeeping or monitoring purposes. |
830 | | - /// |
831 | | - /// Note: There can only be one task termination callback for a runtime; calling this |
832 | | - /// function more than once replaces the last callback defined, rather than adding to it. |
| 676 | + /// Factory method for producing "fallback" task hook harnesses. |
833 | 677 | /// |
834 | | - /// This *does not* support [`LocalSet`](crate::task::LocalSet) at this time. |
835 | | - /// |
836 | | - /// **Note**: This is an [unstable API][unstable]. The public API of this type |
837 | | - /// may break in 1.x releases. See [the documentation on unstable |
838 | | - /// features][unstable] for details. |
839 | | - /// |
840 | | - /// [unstable]: crate#unstable-features |
841 | | - /// |
842 | | - /// # Examples |
843 | | - /// |
844 | | - /// ``` |
845 | | - /// # use tokio::runtime; |
846 | | - /// # pub fn main() { |
847 | | - /// let runtime = runtime::Builder::new_current_thread() |
848 | | - /// .on_task_terminate(|_| { |
849 | | - /// println!("killing task"); |
850 | | - /// }) |
851 | | - /// .build() |
852 | | - /// .unwrap(); |
853 | | - /// |
854 | | - /// runtime.block_on(async { |
855 | | - /// tokio::task::spawn(std::future::ready(())); |
856 | | - /// |
857 | | - /// for _ in 0..64 { |
858 | | - /// tokio::task::yield_now().await; |
859 | | - /// } |
860 | | - /// }) |
861 | | - /// # } |
862 | | - /// ``` |
| 678 | + /// The order of operations for assigning the hook harness for a task are as follows: |
| 679 | + /// 1. [`crate::task::spawn_with_hooks`], if used. |
| 680 | + /// 2. [`crate::runtime::task_hooks::TaskHookHarnessFactory`], if it returns something other than [Option::None]. |
| 681 | + /// 3. This function. |
863 | 682 | #[cfg(all(not(loom), tokio_unstable))] |
864 | 683 | #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))] |
865 | | - pub fn on_task_terminate<F>(&mut self, f: F) -> &mut Self |
| 684 | + pub fn hook_harness_factory<T>(&mut self, hooks: T) -> &mut Self |
866 | 685 | where |
867 | | - F: Fn(&TaskMeta<'_>) + Send + Sync + 'static, |
| 686 | + T: TaskHookHarnessFactory + Send + Sync + 'static, |
868 | 687 | { |
869 | | - self.after_termination = Some(std::sync::Arc::new(f)); |
| 688 | + self.task_hook_harness_factory = Some(Arc::new(hooks)); |
870 | 689 | self |
871 | 690 | } |
872 | 691 |
|
@@ -1475,12 +1294,8 @@ impl Builder { |
1475 | 1294 | Config { |
1476 | 1295 | before_park: self.before_park.clone(), |
1477 | 1296 | after_unpark: self.after_unpark.clone(), |
1478 | | - before_spawn: self.before_spawn.clone(), |
1479 | | - #[cfg(tokio_unstable)] |
1480 | | - before_poll: self.before_poll.clone(), |
1481 | 1297 | #[cfg(tokio_unstable)] |
1482 | | - after_poll: self.after_poll.clone(), |
1483 | | - after_termination: self.after_termination.clone(), |
| 1298 | + task_hook_factory: self.task_hook_harness_factory.clone(), |
1484 | 1299 | global_queue_interval: self.global_queue_interval, |
1485 | 1300 | event_interval: self.event_interval, |
1486 | 1301 | #[cfg(tokio_unstable)] |
@@ -1628,12 +1443,8 @@ cfg_rt_multi_thread! { |
1628 | 1443 | Config { |
1629 | 1444 | before_park: self.before_park.clone(), |
1630 | 1445 | after_unpark: self.after_unpark.clone(), |
1631 | | - before_spawn: self.before_spawn.clone(), |
1632 | | - #[cfg(tokio_unstable)] |
1633 | | - before_poll: self.before_poll.clone(), |
1634 | 1446 | #[cfg(tokio_unstable)] |
1635 | | - after_poll: self.after_poll.clone(), |
1636 | | - after_termination: self.after_termination.clone(), |
| 1447 | + task_hook_factory: self.task_hook_harness_factory.clone(), |
1637 | 1448 | global_queue_interval: self.global_queue_interval, |
1638 | 1449 | event_interval: self.event_interval, |
1639 | 1450 | #[cfg(tokio_unstable)] |
|
0 commit comments