Skip to content

stdio handles are not UnwindSafe #51863

Closed
@abonander

Description

@abonander

io::{Stdout, Stderr, StdoutLock, StderrLock} are not UnwindSafe:

use std::io::{Stdout, Stderr, StdoutLock, StderrLock};
use std::panic::UnwindSafe;

fn assert_unwind_safe<T: UnwindSafe>() {}

fn main() {
    assert_unwind_safe::<Stdout>();
    assert_unwind_safe::<Stderr>();
    assert_unwind_safe::<StdoutLock<'static>>();
    assert_unwind_safe::<StderrLock<'static>>();
}

However, because they are protected by mutexes, it doesn't make sense why these handles shouldn't be UnwindSafe. It seems to be an oversight because they use ReentrantMutex internally, which transitively opts-out of UnwindSafe because it contains an UnsafeCell.

This makes io::Stdout a pain to use with slog which requires Send + Sync + UnwindSafe on its output, necessitating a second mutex wrapping the handle or a custom wrapper implementing UnwindSafe. AssertUnwindSafe is not a solution here because it doesn't implement Write for its contained type.

Either ReentrantMutex should manually implement UnwindSafe as well, or the stdio handles should. I also recommend adding delegated impls of Read, Write and BufRead to AssertUnwindSafe.

Addendum: I'm still having problems with slog but for another reason; slog_json::Json is also not UnwindSafe or Sync because it uses RefCell internally.

Addendum 2: because it uses Mutex and not ReentrantMutex, Stdin is already UnwindSafe + RefUnwindSafe, and thus StdinLock is too. My original code example didn't error for those types but I didn't notice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-enhancementCategory: An issue proposing an enhancement or a PR with one.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions