in sdk/core/azure_core/src/task/standard_spawn.rs [87:145]
fn spawn(&self, f: TaskFuture) -> SpawnedTask {
#[cfg(target_arch = "wasm32")]
{
panic!("std::thread::spawn is not supported on wasm32")
}
#[cfg(not(target_arch = "wasm32"))]
{
let join_state = Arc::new(Mutex::new(ThreadJoinState::default()));
{
let Ok(mut js) = join_state.lock() else {
return Box::pin(future::ready(Err(Box::new(crate::Error::message(
crate::error::ErrorKind::Other,
"Thread panicked.",
))
as Box<dyn std::error::Error + Send>)));
};
// Clone the join state so it can be moved into the thread
// and used to notify the waker when the thread finishes.
let join_state_clone = join_state.clone();
js.join_handle = Some(thread::spawn(move || {
// Create a local executor
let mut local_pool = LocalPool::new();
let spawner = local_pool.spawner();
// Spawn the future on the local executor
let Ok(future_handle) = spawner.spawn_with_handle(f) else {
return Err(Box::new(crate::Error::message(
crate::error::ErrorKind::Other,
"Failed to spawn future.",
))
as Box<dyn std::error::Error + Send>);
};
// Drive the executor until the future completes
local_pool.run_until(future_handle);
let Ok(mut join_state) = join_state_clone.lock() else {
return Err(Box::new(crate::Error::message(
crate::error::ErrorKind::Other,
"Failed to lock join state",
))
as Box<dyn std::error::Error + Send>);
};
// The thread has finished, so we can take the waker
// and notify it.
join_state.thread_finished = true;
if let Some(waker) = join_state.waker.take() {
waker.wake();
}
Ok(())
}));
}
// Create a future that will complete when the thread joins
let join_future = ThreadJoinFuture { join_state };
Box::pin(join_future)
}
}