Skip to content

Commit

Permalink
Merge pull request #500 from caelunshun/ub-fix
Browse files Browse the repository at this point in the history
Fix potential undefined behavior in ArrayQueue initialization
  • Loading branch information
Stjepan Glavina authored May 17, 2020
2 parents 485971e + 2180b82 commit 010ced5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 23 deletions.
22 changes: 11 additions & 11 deletions crossbeam-channel/src/flavors/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,23 @@ impl<T> Channel<T> {
// Tail is initialized to `{ lap: 0, mark: 0, index: 0 }`.
let tail = 0;

// Allocate a buffer of `cap` slots.
// Allocate a buffer of `cap` slots initialized
// with stamps.
let buffer = {
let mut v = Vec::<Slot<T>>::with_capacity(cap);
let mut v: Vec<Slot<T>> = (0..cap)
.map(|i| {
// Set the stamp to `{ lap: 0, mark: 0, index: i }`.
Slot {
stamp: AtomicUsize::new(i),
msg: UnsafeCell::new(MaybeUninit::uninit()),
}
})
.collect();
let ptr = v.as_mut_ptr();
mem::forget(v);
ptr
};

// Initialize stamps in the slots.
for i in 0..cap {
unsafe {
// Set the stamp to `{ lap: 0, mark: 0, index: i }`.
let slot = buffer.add(i);
ptr::write(&mut (*slot).stamp, AtomicUsize::new(i));
}
}

Channel {
buffer,
cap,
Expand Down
23 changes: 11 additions & 12 deletions crossbeam-queue/src/array_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use core::cell::UnsafeCell;
use core::fmt;
use core::marker::PhantomData;
use core::mem;
use core::ptr;
use core::sync::atomic::{self, AtomicUsize, Ordering};

use crossbeam_utils::{Backoff, CachePadded};
Expand Down Expand Up @@ -110,23 +109,23 @@ impl<T> ArrayQueue<T> {
let head = 0;
let tail = 0;

// Allocate a buffer of `cap` slots.
// Allocate a buffer of `cap` slots initialized
// with stamps.
let buffer = {
let mut v = Vec::<Slot<T>>::with_capacity(cap);
let mut v: Vec<Slot<T>> = (0..cap)
.map(|i| {
// Set the stamp to `{ lap: 0, index: i }`.
Slot {
stamp: AtomicUsize::new(i),
value: UnsafeCell::new(MaybeUninit::uninit()),
}
})
.collect();
let ptr = v.as_mut_ptr();
mem::forget(v);
ptr
};

// Initialize stamps in the slots.
for i in 0..cap {
unsafe {
// Set the stamp to `{ lap: 0, index: i }`.
let slot = buffer.add(i);
ptr::write(&mut (*slot).stamp, AtomicUsize::new(i));
}
}

// One lap is the smallest power of two greater than `cap`.
let one_lap = (cap + 1).next_power_of_two();

Expand Down

0 comments on commit 010ced5

Please sign in to comment.