Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: native_client_sdk/src/libraries/nacl_io/kernel_object.cc

Issue 18129008: Clean up locking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename mount functions Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..e4934cbf39663b1c1403dc9ffcb8408061a04099 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_object.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_object.cc
@@ -23,38 +23,66 @@
#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::AttachMountAtPath(const ScopedMount& mnt,
+ const std::string& path) {
+ std::string abs_path = GetAbsParts(path).Join();
+
+ AutoLock lock(&mount_lock_);
+ if (mounts_.find(abs_path) != mounts_.end())
+ return EBUSY;
+
+ mounts_[abs_path] = mnt;
+ return 0;
+}
+
+Error KernelObject::DetachMountAtPath(const std::string& path) {
+ std::string abs_path = GetAbsParts(path).Join();
+
+ AutoLock lock(&mount_lock_);
+ MountMap_t::iterator it = mounts_.find(abs_path);
+ 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;
}
// 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* rel_parts) {
+ Path abs_parts = GetAbsParts(path);
- *out_path = Path();
- Path abs_path;
- {
- AutoLock lock(&process_lock_);
- abs_path = GetAbsPathLocked(relpath);
- }
+ out_mount->reset(NULL);
+ *rel_parts = Path();
- AutoLock lock(&kernel_lock_);
+ AutoLock lock(&mount_lock_);
// Find longest prefix
- size_t max = abs_path.Size();
- for (size_t len = 0; len < abs_path.Size(); len++) {
- MountMap_t::iterator it = mounts_.find(abs_path.Range(0, max - len));
+ size_t max = abs_parts.Size();
+ for (size_t len = 0; len < abs_parts.Size(); len++) {
+ MountMap_t::iterator it = mounts_.find(abs_parts.Range(0, max - len));
if (it != mounts_.end()) {
- out_path->Set("/");
- out_path->Append(abs_path.Range(max - len, max));
+ rel_parts->Set("/");
+ rel_parts->Append(abs_parts.Range(max - len, max));
*out_mount = it->second;
return 0;
@@ -64,10 +92,69 @@ Error KernelObject::AcquireMountAndPath(const std::string& relpath,
return ENOTDIR;
}
+// Given a path, acquire the associated mount and node, creating the
+// 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_parts;
+ out_mount->reset(NULL);
+ out_node->reset(NULL);
+ Error error = AcquireMountAndRelPath(path, out_mount, &rel_parts);
+ if (error)
+ return error;
+
+ error = (*out_mount)->Open(rel_parts, oflags, out_node);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+Path KernelObject::GetAbsParts(const std::string& path) {
+ AutoLock lock(&cwd_lock_);
+
+ Path abs_parts(cwd_);
+ if (path[0] == '/') {
+ abs_parts = path;
+ } else {
+ abs_parts = cwd_;
+ abs_parts.Append(path);
+ }
+
+ return abs_parts;
+}
+
+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 = GetAbsParts(path).Join();
+
+ ScopedMount mnt;
+ ScopedMountNode node;
+
+ Error error = AcquireMountAndNode(abs_path, O_RDONLY, &mnt, &node);
+ if (error)
+ return error;
+
+ 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 +165,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 +186,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 +197,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 +205,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;
-}
-
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/kernel_object.h ('k') | native_client_sdk/src/libraries/nacl_io/kernel_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698