mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Add waker support to ScancodeStream
This commit is contained in:
@@ -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,9 +42,21 @@ 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) => {
|
||||||
|
WAKER.take();
|
||||||
|
Poll::Ready(Some(scancode))
|
||||||
|
}
|
||||||
Err(crossbeam_queue::PopError) => Poll::Pending,
|
Err(crossbeam_queue::PopError) => Poll::Pending,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user