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