From 83dea72a5068eb0f3f984f5df07584c3f590fa38 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Sat, 13 Feb 2021 12:57:53 -0700 Subject: [PATCH] Switch Context::files to RwLock --- src/context/context.rs | 14 +++++++------- src/event.rs | 2 +- src/scheme/sys/iostat.rs | 2 +- src/scheme/user.rs | 4 ++-- src/syscall/fs.rs | 2 +- src/syscall/process.rs | 10 +++++----- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/context/context.rs b/src/context/context.rs index 2068d399..fccd6b0e 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -127,7 +127,7 @@ impl ContextSnapshot { pub fn new(context: &Context) -> Self { let name = context.name.read().clone(); let mut files = Vec::new(); - for descriptor_opt in context.files.lock().iter() { + for descriptor_opt in context.files.read().iter() { let description = if let Some(descriptor) = descriptor_opt { let description = descriptor.description.read(); Some(FileDescription { @@ -239,7 +239,7 @@ pub struct Context { /// The current working directory pub cwd: Arc<RwLock<Vec<u8>>>, /// The open files in the scheme - pub files: Arc<Mutex<Vec<Option<FileDescriptor>>>>, + pub files: Arc<RwLock<Vec<Option<FileDescriptor>>>>, /// Signal actions pub actions: Arc<Mutex<Vec<(SigAction, usize)>>>, /// The pointer to the user-space registers, saved after certain @@ -294,7 +294,7 @@ impl Context { grants: Arc::new(Mutex::new(UserGrants::default())), name: Arc::new(RwLock::new(String::new().into_boxed_str())), cwd: Arc::new(RwLock::new(Vec::new())), - files: Arc::new(Mutex::new(Vec::new())), + files: Arc::new(RwLock::new(Vec::new())), actions: Arc::new(Mutex::new(vec![( SigAction { sa_handler: unsafe { mem::transmute(SIG_DFL) }, @@ -416,7 +416,7 @@ impl Context { /// Add a file to the lowest available slot greater than or equal to min. /// Return the file descriptor number or None if no slot was found pub fn add_file_min(&self, file: FileDescriptor, min: usize) -> Option<FileHandle> { - let mut files = self.files.lock(); + let mut files = self.files.write(); for (i, file_option) in files.iter_mut().enumerate() { if file_option.is_none() && i >= min { *file_option = Some(file); @@ -439,7 +439,7 @@ impl Context { /// Get a file pub fn get_file(&self, i: FileHandle) -> Option<FileDescriptor> { - let files = self.files.lock(); + let files = self.files.read(); if i.into() < files.len() { files[i.into()].clone() } else { @@ -450,7 +450,7 @@ impl Context { /// Insert a file with a specific handle number. This is used by dup2 /// Return the file descriptor number or None if the slot was not empty, or i was invalid pub fn insert_file(&self, i: FileHandle, file: FileDescriptor) -> Option<FileHandle> { - let mut files = self.files.lock(); + let mut files = self.files.write(); if i.into() < super::CONTEXT_MAX_FILES { while i.into() >= files.len() { files.push(None); @@ -469,7 +469,7 @@ impl Context { /// Remove a file // TODO: adjust files vector to smaller size if possible pub fn remove_file(&self, i: FileHandle) -> Option<FileDescriptor> { - let mut files = self.files.lock(); + let mut files = self.files.write(); if i.into() < files.len() { files[i.into()].take() } else { diff --git a/src/event.rs b/src/event.rs index f221bc20..73e2de1f 100644 --- a/src/event.rs +++ b/src/event.rs @@ -35,7 +35,7 @@ impl EventQueue { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - let files = context.files.lock(); + let files = context.files.read(); match files.get(event.id).ok_or(Error::new(EBADF))? { Some(file) => file.clone(), None => return Err(Error::new(EBADF)) diff --git a/src/scheme/sys/iostat.rs b/src/scheme/sys/iostat.rs index 6a732279..fe0d65fa 100644 --- a/src/scheme/sys/iostat.rs +++ b/src/scheme/sys/iostat.rs @@ -16,7 +16,7 @@ pub fn resource() -> Result<Vec<u8>> { let contexts = context::contexts(); for (id, context_lock) in contexts.iter() { let context = context_lock.read(); - rows.push((*id, context.name.read().clone(), context.files.lock().clone())); + rows.push((*id, context.name.read().clone(), context.files.read().clone())); } } diff --git a/src/scheme/user.rs b/src/scheme/user.rs index 8ba07864..c28b8a4f 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -349,7 +349,7 @@ impl Scheme for UserScheme { // TODO: Faster, cleaner mechanism to get descriptor let scheme = inner.scheme_id.load(Ordering::SeqCst); let mut desc_res = Err(Error::new(EBADF)); - for context_file_opt in context.files.lock().iter() { + for context_file_opt in context.files.read().iter() { if let Some(context_file) = context_file_opt { let (context_scheme, context_number) = { let desc = context_file.description.read(); @@ -402,7 +402,7 @@ impl Scheme for UserScheme { // TODO: Faster, cleaner mechanism to get descriptor let scheme = inner.scheme_id.load(Ordering::SeqCst); let mut desc_res = Err(Error::new(EBADF)); - for context_file_opt in context.files.lock().iter() { + for context_file_opt in context.files.read().iter() { if let Some(context_file) = context_file_opt { let (context_scheme, context_number) = { let desc = context_file.description.read(); diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 780f869c..dd19ea42 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -377,7 +377,7 @@ pub fn fcntl(fd: FileHandle, cmd: usize, arg: usize) -> Result<usize> { let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - let mut files = context.files.lock(); + let mut files = context.files.write(); match *files.get_mut(fd.into()).ok_or(Error::new(EBADF))? { Some(ref mut file) => match cmd { F_GETFD => { diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 4f0cbacf..262ffff9 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -259,7 +259,7 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> { if flags.contains(CLONE_FILES) { files = Arc::clone(&context.files); } else { - files = Arc::new(Mutex::new(context.files.lock().clone())); + files = Arc::new(RwLock::new(context.files.read().clone())); } if flags.contains(CLONE_SIGHAND) { @@ -272,7 +272,7 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> { // If not cloning files, dup to get a new number from scheme // This has to be done outside the context lock to prevent deadlocks if !flags.contains(CLONE_FILES) { - for (_fd, file_opt) in files.lock().iter_mut().enumerate() { + for (_fd, file_opt) in files.write().iter_mut().enumerate() { let new_file_opt = if let Some(ref file) = *file_opt { Some(FileDescriptor { description: Arc::clone(&file.description), @@ -866,7 +866,7 @@ fn fexec_noreturn( (vfork, context.ppid, files) }; - for (_fd, file_opt) in files.lock().iter_mut().enumerate() { + for (_fd, file_opt) in files.write().iter_mut().enumerate() { let mut cloexec = false; if let Some(ref file) = *file_opt { if file.cloexec { @@ -1108,12 +1108,12 @@ pub fn exit(status: usize) -> ! { let pid = { let mut context = context_lock.write(); { - let mut lock = context.files.lock(); + let mut lock = context.files.write(); if Arc::strong_count(&context.files) == 1 { mem::swap(lock.deref_mut(), &mut close_files); } } - context.files = Arc::new(Mutex::new(Vec::new())); + context.files = Arc::new(RwLock::new(Vec::new())); context.id }; -- GitLab