|
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