Skip to content

Commit 1f8cda8

Browse files
committed
Priority queue sender is unsafe
- The priority queue sender holds static reference to queue, and is therefor unsafe. It is up to the caller to ensure a static lifetime for the queue.
1 parent 96a6cda commit 1f8cda8

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

hyperloop-priority-queue/src/lib.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,14 @@ where
326326
}
327327
}
328328

329-
pub fn get_sender(&self) -> PrioritySender<T> {
330-
let queue: &'static Self = unsafe { &*(self as *const Self) };
329+
/// Return sender to queue
330+
///
331+
/// # Safety
332+
///
333+
/// Sender contains a static reference to the queue, so the queue
334+
/// should be static for the sender to be safe.
335+
pub unsafe fn get_sender(&self) -> PrioritySender<T> {
336+
let queue: &'static Self = &*(self as *const Self);
331337

332338
PrioritySender {
333339
slots: &queue.slots,
@@ -540,7 +546,7 @@ mod tests {
540546
#[test]
541547
fn stack() {
542548
let mut heap: PriorityQueue<u32, Min, 10> = PriorityQueue::new();
543-
let sender = heap.get_sender();
549+
let sender = unsafe { heap.get_sender() };
544550

545551
for i in 0..10 {
546552
sender.stack_push(i).unwrap();
@@ -568,7 +574,7 @@ mod tests {
568574
#[test]
569575
fn channel() {
570576
let mut queue: PriorityQueue<u32, Min, 10> = PriorityQueue::new();
571-
let sender = queue.get_sender();
577+
let sender = unsafe { queue.get_sender() };
572578

573579
for i in 0..10 {
574580
sender.send(i).unwrap();
@@ -619,7 +625,7 @@ mod tests {
619625
let n_items = n_threads * n_items_per_thread;
620626

621627
for i in 0..n_threads {
622-
let sender = queue.get_sender();
628+
let sender = unsafe { queue.get_sender() };
623629
let handler = thread::spawn(move || {
624630
for j in 0..n_items_per_thread {
625631
loop {
@@ -683,7 +689,7 @@ mod tests_loom {
683689

684690
let handles: Vec<_> = (0..n_threads)
685691
.map(|i| {
686-
let sender = queue.get_sender();
692+
let sender = unsafe { queue.get_sender() };
687693
thread::spawn(move || {
688694
sender.stack_push(i).unwrap();
689695
})

hyperloop/src/executor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl<const N: usize> Executor<N> {
7070
}
7171
}
7272

73-
fn get_sender(&self) -> TaskSender {
73+
unsafe fn get_sender(&self) -> TaskSender {
7474
self.queue.get_sender()
7575
}
7676

@@ -96,7 +96,7 @@ impl<const N: usize> ExecutorRef<N> {
9696
}
9797

9898
pub fn get_sender(&self) -> TaskSender {
99-
self.executor.get_sender()
99+
unsafe { self.executor.get_sender() }
100100
}
101101
}
102102

hyperloop/src/task.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ where
150150

151151
#[cfg(test)]
152152
mod tests {
153+
use std::boxed::Box;
154+
153155
use crate::{
154156
interrupt::yield_now,
155157
priority_queue::{Max, PriorityQueue},
@@ -159,7 +161,8 @@ mod tests {
159161

160162
#[test]
161163
fn task() {
162-
let mut queue: PriorityQueue<Ticket, Max, 1> = PriorityQueue::new();
164+
let queue: &'static mut PriorityQueue<Ticket, Max, 1> =
165+
Box::leak(Box::new(PriorityQueue::new()));
163166

164167
let test_future = || {
165168
|| {
@@ -175,7 +178,7 @@ mod tests {
175178

176179
let task = Task::new(test_future(), 1);
177180

178-
task.set_sender(queue.get_sender()).unwrap();
181+
task.set_sender(unsafe { queue.get_sender() }).unwrap();
179182

180183
assert_eq!(task.get_state(), TaskState::NotQueued);
181184

hyperloop/src/timer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ impl<const N: usize> Scheduler<N> {
302302
}
303303
}
304304

305-
pub fn get_timer(&self) -> Timer {
305+
pub unsafe fn get_timer(&self) -> Timer {
306306
Timer::new(self.rate, self.counter.clone(), self.queue.get_sender())
307307
}
308308

@@ -379,7 +379,7 @@ mod tests {
379379
let token = counter.get_token();
380380
let scheduler: &'static mut Scheduler<10> =
381381
Box::leak(Box::new(Scheduler::new(1000.Hz(), token.clone())));
382-
let sender = scheduler.queue.get_sender();
382+
let sender = unsafe { scheduler.queue.get_sender() };
383383
let mockwaker = Arc::new(MockWaker::new());
384384
let waker: Waker = mockwaker.clone().into();
385385
let mut cx = Context::from_waker(&waker);
@@ -427,7 +427,7 @@ mod tests {
427427
let token = counter.get_token();
428428
let scheduler: &'static mut Scheduler<10> =
429429
Box::leak(Box::new(Scheduler::new(1000.Hz(), token.clone())));
430-
let timer = scheduler.get_timer();
430+
let timer = unsafe { scheduler.get_timer() };
431431
let mut executor = Box::leak(Box::new(Executor::<10>::new())).get_ref();
432432
let queue = Arc::new(ArrayQueue::new(10));
433433

@@ -544,7 +544,7 @@ mod tests {
544544
let token = counter.get_token();
545545
let scheduler: &'static mut Scheduler<10> =
546546
Box::leak(Box::new(Scheduler::new(1000.Hz(), token.clone())));
547-
let timer = scheduler.get_timer();
547+
let timer = unsafe { scheduler.get_timer() };
548548
let mut executor = Box::leak(Box::new(Executor::<10>::new())).get_ref();
549549
let queue = Arc::new(ArrayQueue::new(10));
550550

0 commit comments

Comments
 (0)