[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