| 2368 | |
| 2369 | #[pyfunction] |
| 2370 | fn current_task(args: LoopArg, vm: &VirtualMachine) -> PyResult { |
| 2371 | let loop_obj = match args.loop_.flatten() { |
| 2372 | Some(l) if !vm.is_none(&l) => l, |
| 2373 | _ => { |
| 2374 | // When loop is None or not provided, use the running loop |
| 2375 | match vm.asyncio_running_loop.borrow().clone() { |
| 2376 | Some(l) => l, |
| 2377 | None => return Err(vm.new_runtime_error("no running event loop")), |
| 2378 | } |
| 2379 | } |
| 2380 | }; |
| 2381 | |
| 2382 | // Fast path: if the loop is the current thread's running loop, |
| 2383 | // return the per-thread running task directly |
| 2384 | let is_current_loop = vm |
| 2385 | .asyncio_running_loop |
| 2386 | .borrow() |
| 2387 | .as_ref() |
| 2388 | .is_some_and(|rl| rl.is(&loop_obj)); |
| 2389 | |
| 2390 | if is_current_loop { |
| 2391 | return Ok(vm |
| 2392 | .asyncio_running_task |
| 2393 | .borrow() |
| 2394 | .clone() |
| 2395 | .unwrap_or_else(|| vm.ctx.none())); |
| 2396 | } |
| 2397 | |
| 2398 | // Slow path: look up in the module-level dict for cross-thread queries |
| 2399 | let current_tasks = get_current_tasks_dict(vm)?; |
| 2400 | let dict: PyDictRef = current_tasks.downcast().unwrap(); |
| 2401 | |
| 2402 | match dict.get_item(&*loop_obj, vm) { |
| 2403 | Ok(task) => Ok(task), |
| 2404 | Err(_) => Ok(vm.ctx.none()), |
| 2405 | } |
| 2406 | } |
| 2407 | |
| 2408 | #[pyfunction] |
| 2409 | fn all_tasks(args: LoopArg, vm: &VirtualMachine) -> PyResult { |