[libos] Replace file table with internally implemented mutex
This commit is contained in:
parent
9a174aee01
commit
bfc97f5ba2
@ -8,7 +8,7 @@ use crate::prelude::*;
|
||||
|
||||
/// An event notifier broadcasts interesting events to registered observers.
|
||||
pub struct Notifier<E: Event, F: EventFilter<E> = DummyEventFilter<E>> {
|
||||
subscribers: SgxMutex<VecDeque<Subscriber<E, F>>>,
|
||||
subscribers: Mutex<VecDeque<Subscriber<E, F>>>,
|
||||
}
|
||||
|
||||
struct Subscriber<E: Event, F: EventFilter<E>> {
|
||||
@ -20,7 +20,7 @@ struct Subscriber<E: Event, F: EventFilter<E>> {
|
||||
impl<E: Event, F: EventFilter<E>> Notifier<E, F> {
|
||||
/// Create an event notifier.
|
||||
pub fn new() -> Self {
|
||||
let subscribers = SgxMutex::new(VecDeque::new());
|
||||
let subscribers = Mutex::new(VecDeque::new());
|
||||
Self { subscribers }
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ impl<E: Event, F: EventFilter<E>> Notifier<E, F> {
|
||||
filter: Option<F>,
|
||||
metadata: Option<Weak<dyn Any + Send + Sync>>,
|
||||
) {
|
||||
let mut subscribers = self.subscribers.lock().unwrap();
|
||||
let mut subscribers = self.subscribers.lock();
|
||||
subscribers.push_back(Subscriber {
|
||||
observer,
|
||||
filter,
|
||||
@ -41,13 +41,13 @@ impl<E: Event, F: EventFilter<E>> Notifier<E, F> {
|
||||
|
||||
/// Unregister an observer.
|
||||
pub fn unregister(&self, observer: &Weak<dyn Observer<E>>) {
|
||||
let mut subscribers = self.subscribers.lock().unwrap();
|
||||
let mut subscribers = self.subscribers.lock();
|
||||
subscribers.retain(|subscriber| !Weak::ptr_eq(&subscriber.observer, observer));
|
||||
}
|
||||
|
||||
/// Broadcast an event to all registered observers.
|
||||
pub fn broadcast(&self, event: &E) {
|
||||
let subscribers = self.subscribers.lock().unwrap();
|
||||
let subscribers = self.subscribers.lock();
|
||||
for subscriber in subscribers.iter() {
|
||||
if let Some(filter) = subscriber.filter.as_ref() {
|
||||
if !filter.filter(event) {
|
||||
|
@ -10,7 +10,7 @@ pub fn do_dup(old_fd: FileDesc) -> Result<FileDesc> {
|
||||
|
||||
pub fn do_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<FileDesc> {
|
||||
let current = current!();
|
||||
let mut files = current.files().lock().unwrap();
|
||||
let mut files = current.files().lock();
|
||||
let file = files.get(old_fd)?;
|
||||
let soft_rlimit_nofile = current!()
|
||||
.rlimits()
|
||||
@ -34,7 +34,7 @@ pub fn do_dup2(old_fd: FileDesc, new_fd: FileDesc) -> Result<FileDesc> {
|
||||
pub fn do_dup3(old_fd: FileDesc, new_fd: FileDesc, flags: u32) -> Result<FileDesc> {
|
||||
let creation_flags = CreationFlags::from_bits_truncate(flags);
|
||||
let current = current!();
|
||||
let mut files = current.files().lock().unwrap();
|
||||
let mut files = current.files().lock();
|
||||
let file = files.get(old_fd)?;
|
||||
let soft_rlimit_nofile = current!()
|
||||
.rlimits()
|
||||
|
@ -63,7 +63,7 @@ pub fn do_fcntl(fd: FileDesc, cmd: &mut FcntlCmd) -> Result<isize> {
|
||||
debug!("fcntl: fd: {:?}, cmd: {:?}", &fd, cmd);
|
||||
|
||||
let current = current!();
|
||||
let mut file_table = current.files().lock().unwrap();
|
||||
let mut file_table = current.files().lock();
|
||||
|
||||
let ret = match cmd {
|
||||
FcntlCmd::DupFd(min_fd) => {
|
||||
|
@ -46,7 +46,7 @@ impl DirProcINode for LockedProcFdDirINode {
|
||||
.process_ref
|
||||
.main_thread()
|
||||
.ok_or(FsError::EntryNotFound)?;
|
||||
let fds = main_thread.files().lock().unwrap().fds();
|
||||
let fds = main_thread.files().lock().fds();
|
||||
let fd = fds.iter().nth(i - 2).ok_or(FsError::EntryNotFound)?;
|
||||
Ok(fd.to_string())
|
||||
}
|
||||
@ -72,7 +72,7 @@ impl DirProcINode for LockedProcFdDirINode {
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
let fds = main_thread.files().lock().unwrap().fds();
|
||||
let fds = main_thread.files().lock().fds();
|
||||
let start_offset = *offset;
|
||||
for fd in fds.iter().skip(start_offset - 2) {
|
||||
rcore_fs::visit_entry!(
|
||||
|
@ -108,14 +108,14 @@ impl EpollFile {
|
||||
fn register_to_file_table(&self) {
|
||||
let weak_observer = self.weak_self.clone() as Weak<dyn Observer<_>>;
|
||||
let thread = current!();
|
||||
let file_table = thread.files().lock().unwrap();
|
||||
let file_table = thread.files().lock();
|
||||
file_table.notifier().register(weak_observer, None, None);
|
||||
}
|
||||
|
||||
fn unregister_from_file_table(&self) {
|
||||
let weak_observer = self.weak_self.clone() as Weak<dyn Observer<_>>;
|
||||
let thread = current!();
|
||||
let file_table = thread.files().lock().unwrap();
|
||||
let file_table = thread.files().lock();
|
||||
file_table.notifier().unregister(&weak_observer);
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ fn new_process_common(
|
||||
let vm_ref = Arc::new(vm);
|
||||
let files_ref = {
|
||||
let files = init_files(current_ref, file_actions, host_stdio_fds, &reuse_tid)?;
|
||||
Arc::new(SgxMutex::new(files))
|
||||
Arc::new(Mutex::new(files))
|
||||
};
|
||||
let fs_ref = Arc::new(RwLock::new(current_ref.fs().read().unwrap().clone()));
|
||||
let sched_ref = Arc::new(SgxMutex::new(current_ref.sched().lock().unwrap().clone()));
|
||||
@ -361,7 +361,7 @@ fn init_files(
|
||||
let should_inherit_file_table = current_ref.process().pid() > 0;
|
||||
if should_inherit_file_table {
|
||||
// Fork: clone file table
|
||||
let mut cloned_file_table = current_ref.files().lock().unwrap().clone();
|
||||
let mut cloned_file_table = current_ref.files().lock().clone();
|
||||
|
||||
// By default, file descriptors remain open across an execve().
|
||||
// File descriptors that are marked close-on-exec are closed, which will cause
|
||||
|
@ -77,7 +77,7 @@ pub fn do_vfork(mut context: *mut CpuContext) -> Result<isize> {
|
||||
let parent_pid = current.process().pid();
|
||||
let mut vfork_file_tables = VFORK_PARENT_FILE_TABLES.lock().unwrap();
|
||||
let parent_file_table = {
|
||||
let mut current_file_table = current.files().lock().unwrap();
|
||||
let mut current_file_table = current.files().lock();
|
||||
let new_file_table = current_file_table.clone();
|
||||
// FileTable contains non-cloned struct, so here we do a memory replacement to use new
|
||||
// file table in child and store the original file table in TLS.
|
||||
@ -156,7 +156,7 @@ fn restore_parent_process(mut context: *mut CpuContext, current_ref: &ThreadRef)
|
||||
// Close all child opened files
|
||||
close_files_opened_by_child(current_ref, &parent_file_table)?;
|
||||
|
||||
let mut current_file_table = current_ref.files().lock().unwrap();
|
||||
let mut current_file_table = current_ref.files().lock();
|
||||
*current_file_table = parent_file_table;
|
||||
|
||||
// Get child pid and restore CpuContext
|
||||
@ -195,7 +195,7 @@ pub fn check_vfork_for_exec(current_ref: &ThreadRef) -> Option<(ThreadId, Option
|
||||
}
|
||||
|
||||
fn close_files_opened_by_child(current: &ThreadRef, parent_file_table: &FileTable) -> Result<()> {
|
||||
let current_file_table = current.files().lock().unwrap();
|
||||
let current_file_table = current.files().lock();
|
||||
let child_open_fds: Vec<FileDesc> = current_file_table
|
||||
.table()
|
||||
.iter()
|
||||
|
@ -14,6 +14,7 @@ use crate::misc::ResourceLimits;
|
||||
use crate::prelude::*;
|
||||
use crate::sched::{NiceValue, SchedAgent};
|
||||
use crate::signal::{SigDispositions, SigQueues};
|
||||
use crate::util::sync::Mutex;
|
||||
use crate::vm::ProcessVM;
|
||||
|
||||
use self::pgrp::ProcessGrp;
|
||||
@ -74,7 +75,7 @@ pub type gid_t = u32;
|
||||
|
||||
pub type ProcessRef = Arc<Process>;
|
||||
pub type ThreadRef = Arc<Thread>;
|
||||
pub type FileTableRef = Arc<SgxMutex<FileTable>>;
|
||||
pub type FileTableRef = Arc<Mutex<FileTable>>;
|
||||
pub type ProcessVMRef = Arc<ProcessVM>;
|
||||
pub type FsViewRef = Arc<RwLock<FsView>>;
|
||||
pub type SchedAgentRef = Arc<SgxMutex<SchedAgent>>;
|
||||
|
@ -133,12 +133,12 @@ impl Thread {
|
||||
|
||||
/// Get a file from the file table.
|
||||
pub fn file(&self, fd: FileDesc) -> Result<FileRef> {
|
||||
self.files().lock().unwrap().get(fd)
|
||||
self.files().lock().get(fd)
|
||||
}
|
||||
|
||||
/// Add a file to the file table.
|
||||
pub fn add_file(&self, new_file: FileRef, close_on_spawn: bool) -> FileDesc {
|
||||
self.files().lock().unwrap().put(new_file, close_on_spawn)
|
||||
self.files().lock().put(new_file, close_on_spawn)
|
||||
}
|
||||
|
||||
/// Close a file from the file table. It will release the POSIX advisory locks owned
|
||||
@ -147,7 +147,7 @@ impl Thread {
|
||||
// Deadlock note: EpollFile's drop method needs to access file table. So
|
||||
// if the drop method is invoked inside the del method, then there will be
|
||||
// a deadlock.
|
||||
let file = self.files().lock().unwrap().del(fd)?;
|
||||
let file = self.files().lock().del(fd)?;
|
||||
file.release_advisory_locks();
|
||||
Ok(())
|
||||
}
|
||||
@ -156,7 +156,7 @@ impl Thread {
|
||||
/// by current process.
|
||||
pub fn close_all_files(&self) {
|
||||
// Deadlock note: Same with the issue in close_file method
|
||||
let files = self.files().lock().unwrap().del_all();
|
||||
let files = self.files().lock().del_all();
|
||||
for file in files {
|
||||
file.release_advisory_locks();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user