task.rs 1.2 KB

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