blob: f0dac0fee4f29da6aaa0239e21308686c536ca6d [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::task::{RawWaker, RawWakerVTable};
// Boiler-plate for creating a waker with function pointers.
// This waker sets the atomic bool it is passed to true.
// The bool will be used by the executor to know which futures to poll
// Convert the pointer back to the Rc it was created from and drop it.
unsafe fn waker_drop(data_ptr: *const ()) {
// from_raw, then drop
let _rc_bool = Rc::<AtomicBool>::from_raw(data_ptr as *const _);
}
unsafe fn waker_wake(_: *const ()) {}
// Called when the bool should be set to true to wake the waker.
unsafe fn waker_wake_by_ref(data_ptr: *const ()) {
let bool_atomic_ptr = data_ptr as *const AtomicBool;
let bool_atomic_ref = bool_atomic_ptr.as_ref().unwrap();
bool_atomic_ref.store(true, Ordering::Relaxed);
}
// The data_ptr will be a pointer to an Rc<AtomicBool>.
unsafe fn waker_clone(data_ptr: *const ()) -> RawWaker {
let rc_bool = Rc::<AtomicBool>::from_raw(data_ptr as *const _);
let new_ptr = rc_bool.clone();
Rc::into_raw(rc_bool); // Don't decrement the ref count of the original, so back to raw.
create_waker(Rc::into_raw(new_ptr) as *const _)
}
static WAKER_VTABLE: RawWakerVTable =
RawWakerVTable::new(waker_clone, waker_wake, waker_wake_by_ref, waker_drop);
/// To use safely, data_ptr must be from Rc<AtomicBool>::from_raw().
pub unsafe fn create_waker(data_ptr: *const ()) -> RawWaker {
RawWaker::new(data_ptr, &WAKER_VTABLE)
}