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

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

Issue 18644009: [NaCl SDK] Upate atomic ops in nacl_io (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add declartions for newval and oldval 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 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>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <map> 13 #include <map>
14 #include <string> 14 #include <string>
15 #include <vector> 15 #include <vector>
16 16
17 #include "nacl_io/kernel_handle.h" 17 #include "nacl_io/kernel_handle.h"
18 #include "nacl_io/mount.h" 18 #include "nacl_io/mount.h"
19 #include "nacl_io/mount_node.h" 19 #include "nacl_io/mount_node.h"
20 20
21 #include "sdk_util/auto_lock.h" 21 #include "sdk_util/auto_lock.h"
22 #include "sdk_util/ref_object.h" 22 #include "sdk_util/ref_object.h"
23 #include "sdk_util/scoped_ref.h" 23 #include "sdk_util/scoped_ref.h"
24 24
25 KernelObject::KernelObject() { 25 KernelObject::KernelObject() {
26 pthread_mutex_init(&mount_lock_, NULL);
27 pthread_mutex_init(&handle_lock_, NULL);
28 pthread_mutex_init(&cwd_lock_,NULL);
29
30 cwd_ = "/"; 26 cwd_ = "/";
31 } 27 }
32 28
33 KernelObject::~KernelObject() { 29 KernelObject::~KernelObject() {};
34 pthread_mutex_destroy(&cwd_lock_);
35 pthread_mutex_destroy(&handle_lock_);
36 pthread_mutex_destroy(&mount_lock_);
37 }
38 30
39 Error KernelObject::AttachMountAtPath(const ScopedMount& mnt, 31 Error KernelObject::AttachMountAtPath(const ScopedMount& mnt,
40 const std::string& path) { 32 const std::string& path) {
41 std::string abs_path = GetAbsParts(path).Join(); 33 std::string abs_path = GetAbsParts(path).Join();
42 34
43 AutoLock lock(&mount_lock_); 35 AUTO_LOCK(mount_lock_);
44 if (mounts_.find(abs_path) != mounts_.end()) 36 if (mounts_.find(abs_path) != mounts_.end())
45 return EBUSY; 37 return EBUSY;
46 38
47 mounts_[abs_path] = mnt; 39 mounts_[abs_path] = mnt;
48 return 0; 40 return 0;
49 } 41 }
50 42
51 Error KernelObject::DetachMountAtPath(const std::string& path) { 43 Error KernelObject::DetachMountAtPath(const std::string& path) {
52 std::string abs_path = GetAbsParts(path).Join(); 44 std::string abs_path = GetAbsParts(path).Join();
53 45
54 AutoLock lock(&mount_lock_); 46 AUTO_LOCK(mount_lock_);
55 MountMap_t::iterator it = mounts_.find(abs_path); 47 MountMap_t::iterator it = mounts_.find(abs_path);
56 if (mounts_.end() == it) 48 if (mounts_.end() == it)
57 return EINVAL; 49 return EINVAL;
58 50
59 // It is only legal to unmount if there are no open references 51 // It is only legal to unmount if there are no open references
60 if (it->second->RefCount() != 1) 52 if (it->second->RefCount() != 1)
61 return EBUSY; 53 return EBUSY;
62 54
63 mounts_.erase(it); 55 mounts_.erase(it);
64 return 0; 56 return 0;
65 } 57 }
66 58
67 // Uses longest prefix to find the mount for the give path, then 59 // Uses longest prefix to find the mount for the give path, then
68 // acquires the mount and returns it with a relative path. 60 // acquires the mount and returns it with a relative path.
69 Error KernelObject::AcquireMountAndRelPath(const std::string& path, 61 Error KernelObject::AcquireMountAndRelPath(const std::string& path,
70 ScopedMount* out_mount, 62 ScopedMount* out_mount,
71 Path* rel_parts) { 63 Path* rel_parts) {
72 Path abs_parts = GetAbsParts(path); 64 Path abs_parts = GetAbsParts(path);
73 65
74 out_mount->reset(NULL); 66 out_mount->reset(NULL);
75 *rel_parts = Path(); 67 *rel_parts = Path();
76 68
77 AutoLock lock(&mount_lock_); 69 AUTO_LOCK(mount_lock_);
78 70
79 // Find longest prefix 71 // Find longest prefix
80 size_t max = abs_parts.Size(); 72 size_t max = abs_parts.Size();
81 for (size_t len = 0; len < abs_parts.Size(); len++) { 73 for (size_t len = 0; len < abs_parts.Size(); len++) {
82 MountMap_t::iterator it = mounts_.find(abs_parts.Range(0, max - len)); 74 MountMap_t::iterator it = mounts_.find(abs_parts.Range(0, max - len));
83 if (it != mounts_.end()) { 75 if (it != mounts_.end()) {
84 rel_parts->Set("/"); 76 rel_parts->Set("/");
85 rel_parts->Append(abs_parts.Range(max - len, max)); 77 rel_parts->Append(abs_parts.Range(max - len, max));
86 78
87 *out_mount = it->second; 79 *out_mount = it->second;
(...skipping 18 matching lines...) Expand all
106 return error; 98 return error;
107 99
108 error = (*out_mount)->Open(rel_parts, oflags, out_node); 100 error = (*out_mount)->Open(rel_parts, oflags, out_node);
109 if (error) 101 if (error)
110 return error; 102 return error;
111 103
112 return 0; 104 return 0;
113 } 105 }
114 106
115 Path KernelObject::GetAbsParts(const std::string& path) { 107 Path KernelObject::GetAbsParts(const std::string& path) {
116 AutoLock lock(&cwd_lock_); 108 AUTO_LOCK(cwd_lock_);
117 109
118 Path abs_parts(cwd_); 110 Path abs_parts(cwd_);
119 if (path[0] == '/') { 111 if (path[0] == '/') {
120 abs_parts = path; 112 abs_parts = path;
121 } else { 113 } else {
122 abs_parts = cwd_; 114 abs_parts = cwd_;
123 abs_parts.Append(path); 115 abs_parts.Append(path);
124 } 116 }
125 117
126 return abs_parts; 118 return abs_parts;
127 } 119 }
128 120
129 std::string KernelObject::GetCWD() { 121 std::string KernelObject::GetCWD() {
130 AutoLock lock(&cwd_lock_); 122 AUTO_LOCK(cwd_lock_);
131 std::string out = cwd_; 123 std::string out = cwd_;
132 124
133 return out; 125 return out;
134 } 126 }
135 127
136 Error KernelObject::SetCWD(const std::string& path) { 128 Error KernelObject::SetCWD(const std::string& path) {
137 std::string abs_path = GetAbsParts(path).Join(); 129 std::string abs_path = GetAbsParts(path).Join();
138 130
139 ScopedMount mnt; 131 ScopedMount mnt;
140 ScopedMountNode node; 132 ScopedMountNode node;
141 133
142 Error error = AcquireMountAndNode(abs_path, O_RDONLY, &mnt, &node); 134 Error error = AcquireMountAndNode(abs_path, O_RDONLY, &mnt, &node);
143 if (error) 135 if (error)
144 return error; 136 return error;
145 137
146 if ((node->GetType() & S_IFDIR) == 0) 138 if ((node->GetType() & S_IFDIR) == 0)
147 return ENOTDIR; 139 return ENOTDIR;
148 140
149 AutoLock lock(&cwd_lock_); 141 AUTO_LOCK(cwd_lock_);
150 cwd_ = abs_path; 142 cwd_ = abs_path;
151 return 0; 143 return 0;
152 } 144 }
153 145
154 Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) { 146 Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) {
155 out_handle->reset(NULL); 147 out_handle->reset(NULL);
156 148
157 AutoLock lock(&handle_lock_); 149 AUTO_LOCK(handle_lock_);
158 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) 150 if (fd < 0 || fd >= static_cast<int>(handle_map_.size()))
159 return EBADF; 151 return EBADF;
160 152
161 *out_handle = handle_map_[fd]; 153 *out_handle = handle_map_[fd];
162 if (out_handle) return 0; 154 if (out_handle) return 0;
163 155
164 return EBADF; 156 return EBADF;
165 } 157 }
166 158
167 int KernelObject::AllocateFD(const ScopedKernelHandle& handle) { 159 int KernelObject::AllocateFD(const ScopedKernelHandle& handle) {
168 AutoLock lock(&handle_lock_); 160 AUTO_LOCK(handle_lock_);
169 int id; 161 int id;
170 162
171 // If we can recycle and FD, use that first 163 // If we can recycle and FD, use that first
172 if (free_fds_.size()) { 164 if (free_fds_.size()) {
173 id = free_fds_.front(); 165 id = free_fds_.front();
174 // Force lower numbered FD to be available first. 166 // Force lower numbered FD to be available first.
175 std::pop_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); 167 std::pop_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>());
176 free_fds_.pop_back(); 168 free_fds_.pop_back();
177 handle_map_[id] = handle; 169 handle_map_[id] = handle;
178 } else { 170 } else {
179 id = handle_map_.size(); 171 id = handle_map_.size();
180 handle_map_.push_back(handle); 172 handle_map_.push_back(handle);
181 } 173 }
182 return id; 174 return id;
183 } 175 }
184 176
185 void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle) { 177 void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle) {
186 if (NULL == handle) { 178 if (NULL == handle) {
187 FreeFD(fd); 179 FreeFD(fd);
188 } else { 180 } else {
189 AutoLock lock(&handle_lock_); 181 AUTO_LOCK(handle_lock_);
190 182
191 // If the required FD is larger than the current set, grow the set 183 // If the required FD is larger than the current set, grow the set
192 if (fd >= handle_map_.size()) 184 if (fd >= handle_map_.size())
193 handle_map_.resize(fd + 1, ScopedRef<KernelHandle>()); 185 handle_map_.resize(fd + 1, ScopedRef<KernelHandle>());
194 186
195 handle_map_[fd] = handle; 187 handle_map_[fd] = handle;
196 } 188 }
197 } 189 }
198 190
199 void KernelObject::FreeFD(int fd) { 191 void KernelObject::FreeFD(int fd) {
200 AutoLock lock(&handle_lock_); 192 AUTO_LOCK(handle_lock_);
201 193
202 handle_map_[fd].reset(NULL); 194 handle_map_[fd].reset(NULL);
203 free_fds_.push_back(fd); 195 free_fds_.push_back(fd);
204 196
205 // Force lower numbered FD to be available first. 197 // Force lower numbered FD to be available first.
206 std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); 198 std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>());
207 } 199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698