task.rs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. //! Thin wrapper for spawn and spawn_local for native and wasm.
  2. use std::future::Future;
  3. #[cfg(not(target_arch = "wasm32"))]
  4. use std::sync::OnceLock;
  5. use tokio::task::JoinHandle;
  6. #[cfg(not(target_arch = "wasm32"))]
  7. static GLOBAL_RUNTIME: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
  8. /// Spawns a new asynchronous task returning nothing
  9. ///
  10. /// # Panics
  11. ///
  12. /// Panics if the global Tokio runtime cannot be created when no runtime exists on the current thread.
  13. #[cfg(not(target_arch = "wasm32"))]
  14. pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
  15. where
  16. F: Future + Send + 'static,
  17. F::Output: Send + 'static,
  18. {
  19. if let Ok(handle) = tokio::runtime::Handle::try_current() {
  20. handle.spawn(future)
  21. } else {
  22. // No runtime on this thread (FFI/regular sync context):
  23. // use (or lazily create) a global runtime and spawn on it.
  24. GLOBAL_RUNTIME
  25. .get_or_init(|| {
  26. tokio::runtime::Builder::new_multi_thread()
  27. .enable_all()
  28. .build()
  29. .expect("failed to build global Tokio runtime")
  30. })
  31. .spawn(future)
  32. }
  33. }
  34. /// Spawns a new asynchronous task returning nothing
  35. #[cfg(target_arch = "wasm32")]
  36. pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
  37. where
  38. F: Future + 'static,
  39. F::Output: 'static,
  40. {
  41. tokio::task::spawn_local(future)
  42. }