(&self, func: PyObjectRef, vm: &VirtualMachine)
| 363 | |
| 364 | #[pymethod] |
| 365 | fn remove_done_callback(&self, func: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> { |
| 366 | if self.fut_loop.read().is_none() { |
| 367 | return Err(vm.new_runtime_error("Future object is not initialized.")); |
| 368 | } |
| 369 | let mut cleared_callback0 = 0usize; |
| 370 | |
| 371 | // Check fut_callback0 first |
| 372 | // Clone to release lock before comparison (which may run Python code) |
| 373 | let cb0 = self.fut_callback0.read().clone(); |
| 374 | if let Some(cb0) = cb0 { |
| 375 | let cmp = vm.identical_or_equal(&cb0, &func)?; |
| 376 | if cmp { |
| 377 | *self.fut_callback0.write() = None; |
| 378 | *self.fut_context0.write() = None; |
| 379 | cleared_callback0 = 1; |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | // Check if fut_callbacks exists |
| 384 | let callbacks = self.fut_callbacks.read().clone(); |
| 385 | let callbacks = match callbacks { |
| 386 | Some(c) => c, |
| 387 | None => return Ok(cleared_callback0), |
| 388 | }; |
| 389 | |
| 390 | let list: PyListRef = callbacks.downcast().unwrap(); |
| 391 | let len = list.borrow_vec().len(); |
| 392 | |
| 393 | if len == 0 { |
| 394 | *self.fut_callbacks.write() = None; |
| 395 | return Ok(cleared_callback0); |
| 396 | } |
| 397 | |
| 398 | // Special case for single callback |
| 399 | if len == 1 { |
| 400 | let item = list.borrow_vec().first().cloned(); |
| 401 | if let Some(item) = item { |
| 402 | let tuple: &PyTuple = item.downcast_ref().unwrap(); |
| 403 | let cb = tuple.first().unwrap().clone(); |
| 404 | let cmp = vm.identical_or_equal(&cb, &func)?; |
| 405 | if cmp { |
| 406 | *self.fut_callbacks.write() = None; |
| 407 | return Ok(1 + cleared_callback0); |
| 408 | } |
| 409 | } |
| 410 | return Ok(cleared_callback0); |
| 411 | } |
| 412 | |
| 413 | // Multiple callbacks - iterate with index, checking validity each time |
| 414 | // to handle evil comparisons |
| 415 | let mut new_callbacks = Vec::with_capacity(len); |
| 416 | let mut i = 0usize; |
| 417 | let mut removed = 0usize; |
| 418 | |
| 419 | loop { |
| 420 | // Re-check fut_callbacks on each iteration (evil code may have cleared it) |
| 421 | let callbacks = self.fut_callbacks.read().clone(); |
| 422 | let callbacks = match callbacks { |
nothing calls this directly
no test coverage detected