Add waker support to ScancodeStream

This commit is contained in:
Philipp Oppermann
2020-03-22 12:16:17 +01:00
parent 3a2a468a0b
commit a6273614e4

View File

@@ -5,9 +5,10 @@ use core::{
task::{Context, Poll}, task::{Context, Poll},
}; };
use crossbeam_queue::ArrayQueue; use crossbeam_queue::ArrayQueue;
use futures_util::stream::Stream; use futures_util::{stream::Stream, task::AtomicWaker};
static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit(); static SCANCODE_QUEUE: OnceCell<ArrayQueue<u8>> = OnceCell::uninit();
static WAKER: AtomicWaker = AtomicWaker::new();
/// Called by the keyboard interrupt handler /// Called by the keyboard interrupt handler
/// ///
@@ -16,6 +17,8 @@ pub(crate) fn add_scancode(scancode: u8) {
if let Ok(queue) = SCANCODE_QUEUE.try_get() { if let Ok(queue) = SCANCODE_QUEUE.try_get() {
if let Err(_) = queue.push(scancode) { if let Err(_) = queue.push(scancode) {
println!("WARNING: scancode queue full; dropping keyboard input"); println!("WARNING: scancode queue full; dropping keyboard input");
} else {
WAKER.wake();
} }
} else { } else {
println!("WARNING: scancode queue uninitialized"); println!("WARNING: scancode queue uninitialized");
@@ -39,7 +42,16 @@ impl Stream for ScancodeStream {
type Item = u8; type Item = u8;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<u8>> { fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<u8>> {
let queue = SCANCODE_QUEUE.try_get().expect("not initialized"); let queue = SCANCODE_QUEUE
.try_get()
.expect("scancode queue not initialized");
// fast path
if let Ok(scancode) = queue.pop() {
return Poll::Ready(Some(scancode));
}
WAKER.register(&cx.waker());
match queue.pop() { match queue.pop() {
Ok(scancode) => Poll::Ready(Some(scancode)), Ok(scancode) => Poll::Ready(Some(scancode)),
Err(crossbeam_queue::PopError) => Poll::Pending, Err(crossbeam_queue::PopError) => Poll::Pending,