File tree Expand file tree Collapse file tree
library/std/src/sync/mpmc Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -63,14 +63,14 @@ struct Block<T> {
6363
6464impl < T > Block < T > {
6565/// Creates an empty block.
66- fn new ( ) -> Block < T > {
66+ fn new ( ) -> Box < Block < T > > {
6767// SAFETY: This is safe because:
6868// [1] `Block::next` (AtomicPtr) may be safely zero initialized.
6969// [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4].
7070// [3] `Slot::msg` (UnsafeCell) may be safely zero initialized because it
7171// holds a MaybeUninit.
7272// [4] `Slot::state` (AtomicUsize) may be safely zero initialized.
73- unsafe { MaybeUninit :: zeroed ( ) . assume_init ( ) }
73+ unsafe { Box :: new_zeroed ( ) . assume_init ( ) }
7474}
7575
7676/// Waits until the next pointer is set.
@@ -199,13 +199,13 @@ impl<T> Channel<T> {
199199// If we're going to have to install the next block, allocate it in advance in order to
200200// make the wait for other threads as short as possible.
201201if offset + 1 == BLOCK_CAP && next_block. is_none ( ) {
202- next_block = Some ( Box :: new ( Block :: < T > :: new ( ) ) ) ;
202+ next_block = Some ( Block :: < T > :: new ( ) ) ;
203203}
204204
205205// If this is the first message to be sent into the channel, we need to allocate the
206206// first block and install it.
207207if block. is_null ( ) {
208- let new = Box :: into_raw ( Box :: new ( Block :: < T > :: new ( ) ) ) ;
208+ let new = Box :: into_raw ( Block :: < T > :: new ( ) ) ;
209209
210210if self
211211. tail
Original file line number Diff line number Diff line change 1+ //@ run-pass
2+ //@ compile-flags: -Copt-level=0
3+
4+ // The channel's `Block::new` was causing a stack overflow because it held 32 item slots, which is
5+ // 1MiB for this test's `BigStruct` -- instantiated on the stack before moving to `Box::new`.
6+ //
7+ // That block is now initialized directly on the heap.
8+ //
9+ // Ref: https://github.com/rust-lang/rust/issues/102246
10+
11+ use std:: sync:: mpsc:: channel;
12+ use std:: thread;
13+
14+ const N : usize = 32_768 ;
15+ struct BigStruct {
16+ _data : [ u8 ; N ] ,
17+ }
18+
19+ fn main ( ) {
20+ let ( sender, receiver) = channel :: < BigStruct > ( ) ;
21+
22+ let thread1 = thread:: spawn ( move || {
23+ sender. send ( BigStruct { _data : [ 0u8 ; N ] } ) . unwrap ( ) ;
24+ } ) ;
25+
26+ thread1. join ( ) . unwrap ( ) ;
27+ for _data in receiver. try_iter ( ) { }
28+ }
You can’t perform that action at this time.
0 commit comments