Chromium Code Reviews| Index: native_client_sdk/src/libraries/nacl_io/kernel_object.cc |
| diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_object.cc b/native_client_sdk/src/libraries/nacl_io/kernel_object.cc |
| index f593d21ce29e0808304098164541cb7ee9622e79..14f3d2aa8484f676ae7a14ba4b15e0cff34e9148 100644 |
| --- a/native_client_sdk/src/libraries/nacl_io/kernel_object.cc |
| +++ b/native_client_sdk/src/libraries/nacl_io/kernel_object.cc |
| @@ -23,30 +23,58 @@ |
| #include "sdk_util/scoped_ref.h" |
| KernelObject::KernelObject() { |
| - pthread_mutex_init(&kernel_lock_, NULL); |
| - pthread_mutex_init(&process_lock_, NULL); |
| + pthread_mutex_init(&mount_lock_, NULL); |
| + pthread_mutex_init(&handle_lock_, NULL); |
| + pthread_mutex_init(&cwd_lock_,NULL); |
| + |
| + cwd_ = "/"; |
| } |
| KernelObject::~KernelObject() { |
| - pthread_mutex_destroy(&process_lock_); |
| - pthread_mutex_destroy(&kernel_lock_); |
| + pthread_mutex_destroy(&cwd_lock_); |
| + pthread_mutex_destroy(&handle_lock_); |
| + pthread_mutex_destroy(&mount_lock_); |
| +} |
| + |
| +Error KernelObject::MountAtPath(const ScopedMount& mnt, |
| + const std::string& path) { |
| + std::string abs_targ = GetAbsPath(path); |
|
binji
2013/07/10 21:24:34
nit: how about just "abs_path"
noelallen1
2013/07/10 22:11:07
Done.
|
| + |
| + AutoLock lock(&mount_lock_); |
| + if (mounts_.find(abs_targ) != mounts_.end()) |
| + return EBUSY; |
| + |
| + mounts_[abs_targ] = mnt; |
| + return 0; |
| +} |
| + |
| +Error KernelObject::UnmountPath(const std::string& path) { |
| + std::string abs_targ = GetAbsPath(path); |
|
binji
2013/07/10 21:24:34
ditto
noelallen1
2013/07/10 22:11:07
Done.
|
| + |
| + AutoLock lock(&mount_lock_); |
| + MountMap_t::iterator it = mounts_.find(abs_targ); |
| + if (mounts_.end() == it) |
| + return EINVAL; |
| + |
| + // It is only legal to unmount if there are no open references |
| + if (it->second->RefCount() != 1) |
| + return EBUSY; |
| + |
| + mounts_.erase(it); |
| + return 0; |
| } |
|
binji
2013/07/10 21:24:34
nit: remove extra line
noelallen1
2013/07/10 22:11:07
Done.
|
| + |
| // Uses longest prefix to find the mount for the give path, then |
| // acquires the mount and returns it with a relative path. |
| -Error KernelObject::AcquireMountAndPath(const std::string& relpath, |
| - ScopedMount* out_mount, |
| - Path* out_path) { |
| - out_mount->reset(NULL); |
| +Error KernelObject::AcquireMountAndRelPath(const std::string& path, |
| + ScopedMount* out_mount, |
| + Path* out_path) { |
| + Path abs_path(GetAbsPath(path)); |
| + AutoLock lock(&mount_lock_); |
|
binji
2013/07/10 21:24:34
This can move below clearing out_mount/out_path.
noelallen1
2013/07/10 22:11:07
Done.
|
| + out_mount->reset(NULL); |
| *out_path = Path(); |
| - Path abs_path; |
| - { |
| - AutoLock lock(&process_lock_); |
| - abs_path = GetAbsPathLocked(relpath); |
| - } |
| - |
| - AutoLock lock(&kernel_lock_); |
| // Find longest prefix |
| size_t max = abs_path.Size(); |
| @@ -64,10 +92,70 @@ Error KernelObject::AcquireMountAndPath(const std::string& relpath, |
| return ENOTDIR; |
| } |
| +// Given a path, acquire the associated mount and node, creating then |
|
binji
2013/07/10 21:24:34
s/then/the/
noelallen1
2013/07/10 22:11:07
Done.
|
| +// node if needed based on the provided flags. |
| +Error KernelObject::AcquireMountAndNode(const std::string& path, |
| + int oflags, |
| + ScopedMount* out_mount, |
| + ScopedMountNode* out_node) { |
| + Path rel; |
| + out_mount->reset(NULL); |
| + out_node->reset(NULL); |
| + Error error = AcquireMountAndRelPath(path, out_mount, &rel); |
| + if (error) |
| + return error; |
| + |
| + error = (*out_mount)->Open(rel, oflags, out_node); |
| + if (error) |
| + return error; |
| + |
| + return 0; |
| +} |
| + |
| +std::string KernelObject::GetAbsPath(const std::string& path) { |
|
binji
2013/07/10 21:24:34
Why not return this is a Path, like before? Otherw
noelallen1
2013/07/10 22:11:07
Done.
|
| + AutoLock lock(&cwd_lock_); |
| + |
| + Path abs_path(cwd_); |
| + if (path[0] == '/') { |
| + abs_path = path; |
| + } else { |
| + abs_path = cwd_; |
| + abs_path.Append(path); |
| + } |
| + |
| + return abs_path.Join(); |
| +} |
| + |
| +std::string KernelObject::GetCWD() { |
| + AutoLock lock(&cwd_lock_); |
| + std::string out = cwd_; |
| + |
| + return out; |
| +} |
| + |
| +Error KernelObject::SetCWD(const std::string& path) { |
| + std::string abs_path = GetAbsPath(path); |
| + |
| + ScopedMount mnt; |
| + ScopedMountNode node; |
| + |
| + Error error = AcquireMountAndNode(abs_path, O_RDONLY, &mnt, &node); |
| + if (error) |
| + return error; |
| + |
| + struct stat statbuf; |
|
binji
2013/07/10 21:24:34
unused, remove
noelallen1
2013/07/10 22:11:07
Done.
|
| + if ((node->GetType() & S_IFDIR) == 0) |
| + return ENOTDIR; |
| + |
| + AutoLock lock(&cwd_lock_); |
| + cwd_ = abs_path; |
| + return 0; |
| +} |
| + |
| Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) { |
| out_handle->reset(NULL); |
| - AutoLock lock(&process_lock_); |
| + AutoLock lock(&handle_lock_); |
| if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) |
| return EBADF; |
| @@ -78,7 +166,7 @@ Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) { |
| } |
| int KernelObject::AllocateFD(const ScopedKernelHandle& handle) { |
| - AutoLock lock(&process_lock_); |
| + AutoLock lock(&handle_lock_); |
| int id; |
| // If we can recycle and FD, use that first |
| @@ -99,7 +187,7 @@ void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle) { |
| if (NULL == handle) { |
| FreeFD(fd); |
| } else { |
| - AutoLock lock(&process_lock_); |
| + AutoLock lock(&handle_lock_); |
| // If the required FD is larger than the current set, grow the set |
| if (fd >= handle_map_.size()) |
| @@ -110,7 +198,7 @@ void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle) { |
| } |
| void KernelObject::FreeFD(int fd) { |
| - AutoLock lock(&process_lock_); |
| + AutoLock lock(&handle_lock_); |
| handle_map_[fd].reset(NULL); |
| free_fds_.push_back(fd); |
| @@ -118,18 +206,3 @@ void KernelObject::FreeFD(int fd) { |
| // Force lower numbered FD to be available first. |
| std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); |
| } |
| - |
| -Path KernelObject::GetAbsPathLocked(const std::string& path) { |
| - // Generate absolute path |
| - Path abs_path(cwd_); |
| - |
| - if (path[0] == '/') { |
| - abs_path = path; |
| - } else { |
| - abs_path = cwd_; |
| - abs_path.Append(path); |
| - } |
| - |
| - return abs_path; |
| -} |
| - |