diff --git a/src/context/context.rs b/src/context/context.rs index 2068d399227992dc57f4203eade3e229f137d6e8..fccd6b0ec5d2357ad9ee1161a147b0db7521f4c3 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 f221bc20d0e890123323ec05805478c37661f764..73e2de1f5635a3b4572756222de26c6ebfa6c305 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 6a7322798d2c78cee3895a35cb256600a6661a0c..fe0d65fa655730f09cc928613f22a0ca491a1804 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 8ba07864856b749c8a18ebf6b8d3040ddd96c3d3..c28b8a4fc19c96d591575bf875d40b8d011f6344 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 780f869c513c01d07ce2980c3958efd0abc3864c..dd19ea42a0caee1f7358c3f2a3a0b7175ab8749a 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 4f0cbacf1ed829a10f34897d806ed0063a3084e9..262ffff99f66d539e3a44d4f6a44020aa7bde3d3 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 };