Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 #include "nacl_io/kernel_object.h" | 5 #include "nacl_io/kernel_object.h" |
| 6 | 6 |
| 7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <pthread.h> | 10 #include <pthread.h> |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 pthread_mutex_init(&process_lock_, NULL); | 24 pthread_mutex_init(&process_lock_, NULL); |
| 25 } | 25 } |
| 26 | 26 |
| 27 KernelObject::~KernelObject() { | 27 KernelObject::~KernelObject() { |
| 28 pthread_mutex_destroy(&process_lock_); | 28 pthread_mutex_destroy(&process_lock_); |
| 29 pthread_mutex_destroy(&kernel_lock_); | 29 pthread_mutex_destroy(&kernel_lock_); |
| 30 } | 30 } |
| 31 | 31 |
| 32 // Uses longest prefix to find the mount for the give path, then | 32 // Uses longest prefix to find the mount for the give path, then |
| 33 // acquires the mount and returns it with a relative path. | 33 // acquires the mount and returns it with a relative path. |
| 34 Mount* KernelObject::AcquireMountAndPath(const std::string& relpath, | 34 int KernelObject::AcquireMountAndPath(const std::string& relpath, |
| 35 Path* out_path) { | 35 Mount** out_mount, |
| 36 Path* out_path) { | |
| 37 *out_mount = NULL; | |
| 38 *out_path = Path(); | |
| 39 | |
| 36 Path abs_path; | 40 Path abs_path; |
| 37 { | 41 { |
| 38 AutoLock lock(&process_lock_); | 42 AutoLock lock(&process_lock_); |
| 39 abs_path = GetAbsPathLocked(relpath); | 43 abs_path = GetAbsPathLocked(relpath); |
| 40 } | 44 } |
| 41 | 45 |
| 42 AutoLock lock(&kernel_lock_); | 46 AutoLock lock(&kernel_lock_); |
| 43 Mount* mount = NULL; | 47 Mount* mount = NULL; |
| 44 | 48 |
| 45 | |
| 46 // Find longest prefix | 49 // Find longest prefix |
| 47 size_t max = abs_path.Size(); | 50 size_t max = abs_path.Size(); |
| 48 for (size_t len = 0; len < abs_path.Size(); len++) { | 51 for (size_t len = 0; len < abs_path.Size(); len++) { |
| 49 MountMap_t::iterator it = mounts_.find(abs_path.Range(0, max - len)); | 52 MountMap_t::iterator it = mounts_.find(abs_path.Range(0, max - len)); |
| 50 if (it != mounts_.end()) { | 53 if (it != mounts_.end()) { |
| 51 out_path->Set("/"); | 54 out_path->Set("/"); |
| 52 out_path->Append(abs_path.Range(max - len, max)); | 55 out_path->Append(abs_path.Range(max - len, max)); |
| 53 mount = it->second; | 56 mount = it->second; |
| 54 break; | 57 break; |
| 55 } | 58 } |
| 56 } | 59 } |
| 57 | 60 |
| 58 if (NULL == mount) { | 61 if (NULL == mount) |
| 59 errno = ENOTDIR; | 62 return ENOTDIR; |
| 60 return NULL; | |
| 61 } | |
| 62 | 63 |
| 63 // Acquire the mount while we hold the proxy lock | 64 // Acquire the mount while we hold the proxy lock |
|
noelallen1
2013/06/07 21:48:43
if (*out_mount) {
Should we support only computin
binji
2013/06/07 23:23:11
As per our discussion, non-NULL is assumed and doc
| |
| 64 mount->Acquire(); | 65 mount->Acquire(); |
| 65 return mount; | 66 *out_mount = mount; |
| 67 return 0; | |
|
noelallen1
2013/06/07 21:48:43
Error(EOK)
binji
2013/06/07 23:23:11
Will fix in next CL.
| |
| 66 } | 68 } |
| 67 | 69 |
| 68 void KernelObject::ReleaseMount(Mount* mnt) { | 70 void KernelObject::ReleaseMount(Mount* mnt) { |
| 69 AutoLock lock(&kernel_lock_); | 71 AutoLock lock(&kernel_lock_); |
| 70 mnt->Release(); | 72 mnt->Release(); |
| 71 } | 73 } |
| 72 | 74 |
| 73 KernelHandle* KernelObject::AcquireHandle(int fd) { | 75 int KernelObject::AcquireHandle(int fd, KernelHandle** out_handle) { |
| 76 *out_handle = NULL; | |
| 77 | |
|
noelallen1
2013/06/07 21:48:43
Same. EINVAL?
binji
2013/06/07 23:23:11
Done.
| |
| 74 AutoLock lock(&process_lock_); | 78 AutoLock lock(&process_lock_); |
| 75 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) { | 79 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) |
| 76 errno = EBADF; | 80 return EBADF; |
| 77 return NULL; | |
| 78 } | |
| 79 | 81 |
| 80 KernelHandle* handle = handle_map_[fd]; | 82 KernelHandle* handle = handle_map_[fd]; |
| 81 if (NULL == handle) { | 83 if (NULL == handle) |
| 82 errno = EBADF; | 84 return EBADF; |
| 83 return NULL; | |
| 84 } | |
| 85 | 85 |
| 86 // Ref count while holding parent mutex | 86 // Ref count while holding parent mutex |
| 87 handle->Acquire(); | 87 handle->Acquire(); |
| 88 | 88 |
| 89 lock.Unlock(); | 89 lock.Unlock(); |
| 90 if (handle->node_) handle->mount_->AcquireNode(handle->node_); | 90 if (handle->node_) |
| 91 handle->mount_->AcquireNode(handle->node_); | |
| 91 | 92 |
| 92 return handle; | 93 *out_handle = handle; |
| 94 return 0; | |
|
noelallen1
2013/06/07 21:48:43
Error(EOK)
binji
2013/06/07 23:23:11
Done.
| |
| 93 } | 95 } |
| 94 | 96 |
| 95 void KernelObject::ReleaseHandle(KernelHandle* handle) { | 97 void KernelObject::ReleaseHandle(KernelHandle* handle) { |
| 96 // The handle must already be held before taking the | 98 // The handle must already be held before taking the |
| 97 // kernel lock. | 99 // kernel lock. |
| 98 if (handle->node_) handle->mount_->ReleaseNode(handle->node_); | 100 if (handle->node_) |
| 101 handle->mount_->ReleaseNode(handle->node_); | |
| 99 | 102 |
| 100 AutoLock lock(&process_lock_); | 103 AutoLock lock(&process_lock_); |
| 101 handle->Release(); | 104 handle->Release(); |
| 102 } | 105 } |
| 103 | 106 |
| 104 // Helper function to properly sort FD order in the heap, forcing | |
| 105 // lower numbered FD to be available first. | |
| 106 static bool FdOrder(int i, int j) { | |
| 107 return i > j; | |
| 108 } | |
| 109 | |
| 110 int KernelObject::AllocateFD(KernelHandle* handle) { | 107 int KernelObject::AllocateFD(KernelHandle* handle) { |
| 111 AutoLock lock(&process_lock_); | 108 AutoLock lock(&process_lock_); |
| 112 int id; | 109 int id; |
| 113 | 110 |
| 114 // Acquire the handle and its mount since we are about to track it with | 111 // Acquire the handle and its mount since we are about to track it with |
| 115 // this FD. | 112 // this FD. |
| 116 handle->Acquire(); | 113 handle->Acquire(); |
| 117 handle->mount_->Acquire(); | 114 handle->mount_->Acquire(); |
| 118 | 115 |
| 119 // If we can recycle and FD, use that first | 116 // If we can recycle and FD, use that first |
| 120 if (free_fds_.size()) { | 117 if (free_fds_.size()) { |
| 121 id = free_fds_.front(); | 118 id = free_fds_.front(); |
| 122 std::pop_heap(free_fds_.begin(), free_fds_.end(), FdOrder); | 119 // Force lower numbered FD to be available first. |
|
noelallen1
2013/06/07 21:48:43
I don't think this comment or code is correct.
I b
| |
| 120 std::pop_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); | |
| 123 free_fds_.pop_back(); | 121 free_fds_.pop_back(); |
| 124 handle_map_[id] = handle; | 122 handle_map_[id] = handle; |
| 125 } else { | 123 } else { |
| 126 id = handle_map_.size(); | 124 id = handle_map_.size(); |
| 127 handle_map_.push_back(handle); | 125 handle_map_.push_back(handle); |
| 128 } | 126 } |
| 129 return id; | 127 return id; |
| 130 } | 128 } |
| 131 | 129 |
| 132 void KernelObject::FreeAndReassignFD(int fd, KernelHandle* handle) { | 130 void KernelObject::FreeAndReassignFD(int fd, KernelHandle* handle) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 159 AutoLock lock(&process_lock_); | 157 AutoLock lock(&process_lock_); |
| 160 | 158 |
| 161 // Release the mount and handle since we no longer | 159 // Release the mount and handle since we no longer |
| 162 // track them with this FD. | 160 // track them with this FD. |
| 163 KernelHandle* handle = handle_map_[fd]; | 161 KernelHandle* handle = handle_map_[fd]; |
| 164 handle->Release(); | 162 handle->Release(); |
| 165 handle->mount_->Release(); | 163 handle->mount_->Release(); |
| 166 | 164 |
| 167 handle_map_[fd] = NULL; | 165 handle_map_[fd] = NULL; |
| 168 free_fds_.push_back(fd); | 166 free_fds_.push_back(fd); |
| 169 std::push_heap(free_fds_.begin(), free_fds_.end(), FdOrder); | 167 // Force lower numbered FD to be available first. |
| 168 std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); | |
| 170 } | 169 } |
| 171 | 170 |
| 172 Path KernelObject::GetAbsPathLocked(const std::string& path) { | 171 Path KernelObject::GetAbsPathLocked(const std::string& path) { |
| 173 // Generate absolute path | 172 // Generate absolute path |
| 174 Path abs_path(cwd_); | 173 Path abs_path(cwd_); |
| 175 if (path[0] == '/') { | 174 if (path[0] == '/') { |
| 176 abs_path = path; | 175 abs_path = path; |
| 177 } else { | 176 } else { |
| 178 abs_path = cwd_; | 177 abs_path = cwd_; |
| 179 abs_path.Append(path); | 178 abs_path.Append(path); |
| 180 } | 179 } |
| 181 | 180 |
| 182 return abs_path; | 181 return abs_path; |
| 183 } | 182 } |
| OLD | NEW |