diff --git a/src/services/libs/jinux-std/src/events/events.rs b/src/services/libs/jinux-std/src/events/events.rs new file mode 100644 index 000000000..002197d48 --- /dev/null +++ b/src/services/libs/jinux-std/src/events/events.rs @@ -0,0 +1,2 @@ +/// A trait to represent any events. +pub trait Events: Copy + Clone + Send + Sync + 'static {} diff --git a/src/services/libs/jinux-std/src/events/mod.rs b/src/services/libs/jinux-std/src/events/mod.rs new file mode 100644 index 000000000..18e154e93 --- /dev/null +++ b/src/services/libs/jinux-std/src/events/mod.rs @@ -0,0 +1,7 @@ +mod events; +mod observer; +mod subject; + +pub use self::events::Events; +pub use self::observer::Observer; +pub use self::subject::Subject; diff --git a/src/services/libs/jinux-std/src/events/observer.rs b/src/services/libs/jinux-std/src/events/observer.rs new file mode 100644 index 000000000..315abdd13 --- /dev/null +++ b/src/services/libs/jinux-std/src/events/observer.rs @@ -0,0 +1,11 @@ +use super::Events; + +/// An observer for events. +/// +/// In a sense, event observers are just a fancy form of callback functions. +/// An observer's `on_events` methods are supposed to be called when +/// some events that are interesting to the observer happen. +pub trait Observer: Send + Sync { + /// Notify the observer that some interesting events happen. + fn on_events(&self, events: &E); +} diff --git a/src/services/libs/jinux-std/src/events/subject.rs b/src/services/libs/jinux-std/src/events/subject.rs new file mode 100644 index 000000000..be5d044c5 --- /dev/null +++ b/src/services/libs/jinux-std/src/events/subject.rs @@ -0,0 +1,43 @@ +use crate::prelude::*; + +use super::{Events, Observer}; + +/// A Subject notify interesting events to registered observers. +pub struct Subject { + observers: Mutex>>>, +} + +impl Subject { + pub fn new() -> Self { + Self { + observers: Mutex::new(Vec::new()), + } + } + + /// Register an observer. + pub fn register_observer(&self, observer: Weak>) { + let mut observers = self.observers.lock(); + observers.push(observer); + } + + /// Unregister an observer. + pub fn unregister_observer(&self, observer: Weak>) { + let mut observers = self.observers.lock(); + observers.retain(|e| !Weak::ptr_eq(&e, &observer)); + } + + /// Notify events to all registered observers. + /// It will remove the observers which have been freed. + pub fn notify_observers(&self, events: &E) { + let mut observers = self.observers.lock(); + let mut idx = 0; + while idx < observers.len() { + if let Some(observer) = observers[idx].upgrade() { + observer.on_events(events); + idx += 1; + } else { + observers.remove(idx); + } + } + } +} diff --git a/src/services/libs/jinux-std/src/fs/file_handle/file.rs b/src/services/libs/jinux-std/src/fs/file_handle/file.rs index 4a5a8be9e..283c58903 100644 --- a/src/services/libs/jinux-std/src/fs/file_handle/file.rs +++ b/src/services/libs/jinux-std/src/fs/file_handle/file.rs @@ -1,8 +1,8 @@ +use crate::fs::utils::{IoEvents, IoctlCmd, Metadata, SeekFrom}; use crate::prelude::*; use crate::tty::get_n_tty; -use core::any::Any; -use crate::fs::utils::{IoEvents, IoctlCmd, Metadata, SeekFrom}; +use core::any::Any; /// The basic operations defined on a file pub trait File: Send + Sync + Any { diff --git a/src/services/libs/jinux-std/src/fs/utils/events.rs b/src/services/libs/jinux-std/src/fs/utils/io_events.rs similarity index 88% rename from src/services/libs/jinux-std/src/fs/utils/events.rs rename to src/services/libs/jinux-std/src/fs/utils/io_events.rs index b414fc020..f8d1dbdbc 100644 --- a/src/services/libs/jinux-std/src/fs/utils/events.rs +++ b/src/services/libs/jinux-std/src/fs/utils/io_events.rs @@ -1,6 +1,4 @@ -use crate::prelude::*; - -bitflags! { +crate::bitflags! { pub struct IoEvents: u32 { const POLLIN = 0x0001; const POLLPRI = 0x0002; diff --git a/src/services/libs/jinux-std/src/fs/utils/mod.rs b/src/services/libs/jinux-std/src/fs/utils/mod.rs index 14ca8338a..da0aa34a5 100644 --- a/src/services/libs/jinux-std/src/fs/utils/mod.rs +++ b/src/services/libs/jinux-std/src/fs/utils/mod.rs @@ -4,11 +4,11 @@ pub use access_mode::AccessMode; pub use creation_flags::CreationFlags; pub use dentry_cache::Dentry; pub use dirent_visitor::DirentVisitor; -pub use events::IoEvents; pub use fcntl::FcntlCmd; pub use file_creation_mask::FileCreationMask; pub use fs::{FileSystem, SuperBlock}; pub use inode::{Inode, InodeMode, InodeType, Metadata}; +pub use io_events::IoEvents; pub use ioctl::IoctlCmd; pub use page_cache::PageCacheManager; pub use poll::{c_nfds, c_pollfd, PollFd}; @@ -19,11 +19,11 @@ mod access_mode; mod creation_flags; mod dentry_cache; mod dirent_visitor; -mod events; mod fcntl; mod file_creation_mask; mod fs; mod inode; +mod io_events; mod ioctl; mod page_cache; mod poll; diff --git a/src/services/libs/jinux-std/src/lib.rs b/src/services/libs/jinux-std/src/lib.rs index a770d4f66..90075ebc9 100644 --- a/src/services/libs/jinux-std/src/lib.rs +++ b/src/services/libs/jinux-std/src/lib.rs @@ -31,6 +31,7 @@ extern crate controlled; pub mod driver; pub mod error; +pub mod events; pub mod fs; pub mod prelude; mod process; diff --git a/src/services/libs/jinux-std/src/tty/mod.rs b/src/services/libs/jinux-std/src/tty/mod.rs index 9637abc0b..de8bd9e39 100644 --- a/src/services/libs/jinux-std/src/tty/mod.rs +++ b/src/services/libs/jinux-std/src/tty/mod.rs @@ -1,10 +1,7 @@ use self::line_discipline::LineDiscipline; use crate::driver::tty::TtyDriver; -use crate::fs::utils::{InodeMode, InodeType, Metadata}; -use crate::fs::{ - file_handle::File, - utils::{IoEvents, IoctlCmd}, -}; +use crate::fs::utils::{InodeMode, InodeType, IoEvents, Metadata}; +use crate::fs::{file_handle::File, utils::IoctlCmd}; use crate::prelude::*; use crate::process::{process_table, Pgid}; use crate::util::{read_val_from_user, write_val_to_user};