Skip to content

QueuingExecutor is not panic-safe #397

@Patryk27

Description

@Patryk27

Hi, seems you're already aware of it:

// FIXME: are we potentially sending ourselves `Unavailable` and reading it

... but I thought it'd be nice to drop an example as well, since it's quite easy to trigger this behavior:

#[test]
fn test_panic() {
    let (executor, spawner) = executor_and_spawner();

    struct MyTask;

    impl Future for MyTask {
        type Output = ();

        fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
            cx.waker().wake_by_ref();
            panic!();
        }
    }

    spawner.spawn(MyTask);

    _ = std::panic::catch_unwind(|| {
        executor.run_all();
    });

    executor.run_all(); // runs forever
}

(note that the deadlocking is not caused by calling MyTask::poll() in a loop - that poll happens just once, .run_all() gets blocked via self.ready_sender.send(task_id) that gets picked up on the next iteration of the loop)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions