File tree Expand file tree Collapse file tree 2 files changed +32
-4
lines changed
library/std/src/sync/mpmc Expand file tree Collapse file tree 2 files changed +32
-4
lines changed 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.
201201 if 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.
207207 if block. is_null ( ) {
208- let new = Box :: into_raw ( Box :: new ( Block :: < T > :: new ( ) ) ) ;
208+ let new = Box :: into_raw ( Block :: < T > :: new ( ) ) ;
209209
210210 if 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