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

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/kernel_object.cc

Issue 16232016: [NaCl SDK] nacl_io: big refactor to return error value (errno). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge master, fix windows Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 Error 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
64 mount->Acquire(); 65 mount->Acquire();
65 return mount; 66 *out_mount = mount;
67 return 0;
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 Error KernelObject::AcquireHandle(int fd, KernelHandle** out_handle) {
76 *out_handle = NULL;
77
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;
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.
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
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 }
OLDNEW
« 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