Skip to content

Commit

Permalink
Fix SIGSEGV in atomic_stack.
Browse files Browse the repository at this point in the history
  • Loading branch information
emgre committed Jul 23, 2020
1 parent 17490d8 commit f1b3090
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 16 deletions.
7 changes: 6 additions & 1 deletion tokio/src/runtime/blocking/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ impl Spawner {
if let Some(shutdown_tx) = shutdown_tx {
let handle = self.spawn_thread(shutdown_tx, rt);

self.inner.shared.lock().unwrap().worker_threads.push(handle);
self.inner
.shared
.lock()
.unwrap()
.worker_threads
.push(handle);
}

Ok(())
Expand Down
6 changes: 4 additions & 2 deletions tokio/src/runtime/spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ pub(crate) enum Spawner {
impl Spawner {
pub(crate) fn shutdown(&mut self) {
#[cfg(feature = "rt-threaded")]
if let Spawner::ThreadPool(spawner) = self {
spawner.shutdown();
{
if let Spawner::ThreadPool(spawner) = self {
spawner.shutdown();
}
}
}
}
Expand Down
17 changes: 4 additions & 13 deletions tokio/src/time/driver/atomic_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ impl AtomicStack {

// Update the `next` pointer. This is safe because setting the queued
// bit is a "lock" on this field.
if !curr.is_null() {
unsafe {
*(entry.next_atomic.get()) = curr;
}
unsafe {
*(entry.next_atomic.get()) = curr;
}

let actual = self.head.compare_and_swap(curr, ptr, SeqCst);
Expand Down Expand Up @@ -97,22 +95,15 @@ impl Iterator for AtomicStackEntries {
type Item = Arc<Entry>;

fn next(&mut self) -> Option<Self::Item> {
if self.ptr.is_null() {
if self.ptr.is_null() || self.ptr == SHUTDOWN {
return None;
}

// Convert the pointer to an `Arc<Entry>`
let entry = unsafe { Arc::from_raw(self.ptr) };

// Update `self.ptr` to point to the next element of the stack
self.ptr = unsafe {
let entry = entry.next_atomic.get();
if entry.is_null() {
return None
}

*entry
};
self.ptr = unsafe { *entry.next_atomic.get() };

// Unset the queued flag
let res = entry.queued.fetch_and(false, SeqCst);
Expand Down

0 comments on commit f1b3090

Please sign in to comment.