-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Follow-up changes for blocking unamed_socket #4099
Changes from 3 commits
8c044ec
e252bc6
a0b952e
c2a3b7b
6b513fc
67af109
21a6a90
7f844ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//@ignore-target: windows # No libc socketpair on Windows | ||
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / coverage reportexpexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics
|
||
//@compile-flags: -Zmiri-preemption-rate=0 | ||
|
||
use std::thread; | ||
|
||
fn main() { | ||
let mut fds = [-1, -1]; | ||
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; | ||
assert_eq!(res, 0); | ||
let thread1 = thread::spawn(move || { | ||
// Let this thread block on read. | ||
let mut buf: [u8; 3] = [0; 3]; | ||
let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; | ||
Check failure on line 13 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 13 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 13 in tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
|
||
assert_eq!(res, 3); | ||
assert_eq!(&buf, "abc".as_bytes()); | ||
}); | ||
let thread2 = thread::spawn(move || { | ||
// Close the socketpair fd while thread1 is blocking on it. | ||
assert_eq!(unsafe { libc::close(fds[1]) }, 0); | ||
let data = "abc".as_bytes().as_ptr(); | ||
let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; | ||
// This will fail because we can't write anything if the peer_fd is closed. | ||
assert_eq!(res, -1); | ||
}); | ||
thread1.join().unwrap(); | ||
thread2.join().unwrap(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
error: deadlock: the evaluated program deadlocked | ||
| | ||
= note: the evaluated program deadlocked | ||
= note: (no span available) | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
| | ||
LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE: | ||
= note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
= note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
= note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
note: inside `main` | ||
--> tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs:LL:CC | ||
| | ||
LL | thread1.join().unwrap(); | ||
| ^^^^^^^^^^^^^^ | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs:LL:CC | ||
| | ||
LL | let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
= note: inside closure at tests/fail-dep/libc/socketpair_closed_while_read_blocking.rs:LL:CC | ||
|
||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | ||
|
||
error: aborting due to 3 previous errors | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
//@ignore-target: windows # No libc socketpair on Windows | ||
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / coverage reportexpexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)expexted error patterns
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics outside the testfile
Check failure on line 1 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (windows-latest, i686-pc-windows-msvc)Unmatched diagnostics
|
||
//@compile-flags: -Zmiri-preemption-rate=0 | ||
|
||
use std::thread; | ||
|
||
fn main() { | ||
let mut fds = [-1, -1]; | ||
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; | ||
assert_eq!(res, 0); | ||
let arr1: [u8; 212992] = [1; 212992]; | ||
// Exhaust the space in the buffer so the subsequent write will block. | ||
let res = unsafe { libc::write(fds[0], arr1.as_ptr() as *const libc::c_void, 212992) }; | ||
assert_eq!(res, 212992); | ||
let thread1 = thread::spawn(move || { | ||
let data = "abc".as_bytes().as_ptr(); | ||
// The write below will be blocked because the buffer is already full. | ||
let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; | ||
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / coverage reportUnmatched diagnostics
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (ubuntu-latest, x86_64-unknown-linux-gnu)Unmatched diagnostics
Check failure on line 17 in tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs GitHub Actions / build (macos-14, aarch64-apple-darwin)Unmatched diagnostics
|
||
assert_eq!(res, 3); | ||
}); | ||
let thread2 = thread::spawn(move || { | ||
// Close the socketpair fd while thread1 is blocking on it. | ||
assert_eq!(unsafe { libc::close(fds[0]) }, 0); | ||
// Unblock thread1 by freeing up some space. | ||
let mut buf: [u8; 3] = [0; 3]; | ||
let res = unsafe { libc::read(fds[1], buf.as_mut_ptr().cast(), buf.len() as libc::size_t) }; | ||
assert_eq!(res, 3); | ||
assert_eq!(buf, [1, 1, 1]); | ||
}); | ||
thread1.join().unwrap(); | ||
thread2.join().unwrap(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
error: deadlock: the evaluated program deadlocked | ||
| | ||
= note: the evaluated program deadlocked | ||
= note: (no span available) | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
| | ||
LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE: | ||
= note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC | ||
= note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
= note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC | ||
note: inside `main` | ||
--> tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs:LL:CC | ||
| | ||
LL | thread1.join().unwrap(); | ||
| ^^^^^^^^^^^^^^ | ||
|
||
error: deadlock: the evaluated program deadlocked | ||
--> tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs:LL:CC | ||
| | ||
LL | let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 3) }; | ||
| ^ the evaluated program deadlocked | ||
| | ||
= note: BACKTRACE on thread `unnamed-ID`: | ||
= note: inside closure at tests/fail-dep/libc/socketpair_closed_while_write_blocking.rs:LL:CC | ||
|
||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace | ||
|
||
error: aborting due to 3 previous errors | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unsupported in
anonsocket_read
should be unreachable too because in order to hit that path, it needs to fulfil these conditions:read
must be unblocked (after previously blocked)fds[1]
) onread
is closed.But after the fd blocked on
read
(fds[1]
) is closed, it is impossible to have a successwrite
onfds[0]
, soread
is never unblocked, condition1.
couldn't be fulfilled.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right... we only wake up a thread if we successfully upgraded the weak ref stored in the peer, and then ofc the weak ref stored in the callback also must still be valid.