Skip to content

Commit

Permalink
Explicitly explain failure points in allow_threads implementation for…
Browse files Browse the repository at this point in the history
… better debuggability.
  • Loading branch information
adamreichold committed Dec 14, 2023
1 parent 8a812ee commit b703d9f
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ impl<'py> Python<'py> {
use std::mem::transmute;
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
use std::sync::mpsc::{sync_channel, SendError, SyncSender};
use std::thread::{spawn, Result};
use std::thread::{Builder, Result};
use std::time::Duration;

use parking_lot::{const_mutex, Mutex};
Expand All @@ -344,11 +344,15 @@ impl<'py> Python<'py> {
let mut f = Some(f);

let mut task = || {
let f = f.take().unwrap();
let f = f
.take()
.expect("allow_threads closure called more than once");

let result = catch_unwind(AssertUnwindSafe(f));

result_sender.send(result).unwrap();
result_sender
.send(result)
.expect("allow_threads runtime task was abandoned");
};

// SAFETY: the current thread will block until the closure has returned
Expand All @@ -371,22 +375,27 @@ impl<'py> Python<'py> {

let (task_sender, task_receiver) = sync_channel::<Task>(0);

spawn(move || {
let mut next_task = Ok(task);
Builder::new()
.name("pyo3 allow_threads runtime".to_owned())
.spawn(move || {
let mut next_task = Ok(task);

while let Ok(task) = next_task {
// SAFETY: all data accessed by `task` will stay alive until it completes
unsafe { (*task.0)() };
while let Ok(task) = next_task {
// SAFETY: all data accessed by `task` will stay alive until it completes
unsafe { (*task.0)() };

next_task = task_receiver.recv_timeout(Duration::from_secs(60));
}
});
next_task = task_receiver.recv_timeout(Duration::from_secs(60));
}
})
.expect("failed to create allow_threads runtime thread");

task_sender
};

// 3. Wait for completion and check result
let result = result_receiver.recv().unwrap();
let result = result_receiver
.recv()
.expect("allow_threads runtime thread died unexpectedly");

trap.disarm();

Expand Down

0 comments on commit b703d9f

Please sign in to comment.