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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 145 |
146 Error KernelObject::GetFDFlags(int fd, int* out_flags) { | 146 Error KernelObject::GetFDFlags(int fd, int* out_flags) { |
147 AUTO_LOCK(handle_lock_); | 147 AUTO_LOCK(handle_lock_); |
148 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) | 148 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) |
149 return EBADF; | 149 return EBADF; |
150 | 150 |
151 *out_flags = handle_map_[fd].flags; | 151 *out_flags = handle_map_[fd].flags; |
152 return 0; | 152 return 0; |
153 } | 153 } |
154 | 154 |
155 std::string KernelObject::GetFDPath(int fd) { | |
156 AUTO_LOCK(handle_lock_); | |
157 | |
158 FdPathMap_t::iterator iter = fd_paths_.find(fd); | |
159 if (iter == fd_paths_.end()) | |
160 return std::string(); | |
161 | |
162 return iter->second; | |
163 } | |
164 | |
155 Error KernelObject::SetFDFlags(int fd, int flags) { | 165 Error KernelObject::SetFDFlags(int fd, int flags) { |
156 AUTO_LOCK(handle_lock_); | 166 AUTO_LOCK(handle_lock_); |
157 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) | 167 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) |
158 return EBADF; | 168 return EBADF; |
159 | 169 |
160 // Only setting of FD_CLOEXEC is supported. | 170 // Only setting of FD_CLOEXEC is supported. |
161 if (flags & ~FD_CLOEXEC) | 171 if (flags & ~FD_CLOEXEC) |
162 return EINVAL; | 172 return EINVAL; |
163 | 173 |
164 handle_map_[fd].flags = flags; | 174 handle_map_[fd].flags = flags; |
165 return 0; | 175 return 0; |
166 } | 176 } |
167 | 177 |
168 Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) { | 178 Error KernelObject::AcquireHandle(int fd, ScopedKernelHandle* out_handle) { |
169 out_handle->reset(NULL); | 179 out_handle->reset(NULL); |
170 | 180 |
171 AUTO_LOCK(handle_lock_); | 181 AUTO_LOCK(handle_lock_); |
172 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) | 182 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) |
173 return EBADF; | 183 return EBADF; |
174 | 184 |
175 *out_handle = handle_map_[fd].handle; | 185 *out_handle = handle_map_[fd].handle; |
176 if (out_handle) | 186 if (out_handle) |
177 return 0; | 187 return 0; |
178 | 188 |
179 return EBADF; | 189 return EBADF; |
180 } | 190 } |
181 | 191 |
182 int KernelObject::AllocateFD(const ScopedKernelHandle& handle) { | 192 Error KernelObject::AcquireHandleAndPath(int fd, ScopedKernelHandle* out_handle, |
193 std::string &out_path){ | |
Sam Clegg
2014/01/07 23:56:39
Put '&' next to the type according to the local st
| |
194 out_handle->reset(NULL); | |
195 | |
196 AUTO_LOCK(handle_lock_); | |
197 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) | |
198 return EBADF; | |
199 | |
200 *out_handle = handle_map_[fd].handle; | |
201 if (!out_handle) | |
202 return EBADF; | |
203 | |
204 out_path = fd_paths_[fd]; | |
205 | |
206 return 0; | |
207 } | |
208 | |
209 int KernelObject::AllocateFD(const ScopedKernelHandle& handle, | |
210 std::string path) { | |
Sam Clegg
2014/01/07 23:56:39
Why not pass string by reference here too?
| |
183 AUTO_LOCK(handle_lock_); | 211 AUTO_LOCK(handle_lock_); |
184 int id; | 212 int id; |
185 | 213 |
186 Descriptor_t descriptor(handle); | 214 Descriptor_t descriptor(handle); |
187 | 215 |
188 // If we can recycle and FD, use that first | 216 // If we can recycle and FD, use that first |
189 if (free_fds_.size()) { | 217 if (free_fds_.size()) { |
190 id = free_fds_.front(); | 218 id = free_fds_.front(); |
191 // Force lower numbered FD to be available first. | 219 // Force lower numbered FD to be available first. |
192 std::pop_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); | 220 std::pop_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); |
193 free_fds_.pop_back(); | 221 free_fds_.pop_back(); |
194 handle_map_[id] = descriptor; | 222 handle_map_[id] = descriptor; |
195 } else { | 223 } else { |
196 id = handle_map_.size(); | 224 id = handle_map_.size(); |
197 handle_map_.push_back(descriptor); | 225 handle_map_.push_back(descriptor); |
198 } | 226 } |
227 // With our final fd identifier, we insert into our fd_paths_ mapping as long | |
228 // as path is non-NULL. | |
229 if (!path.empty()) | |
230 fd_paths_[id] = GetAbsParts(path).Join(); | |
231 | |
199 return id; | 232 return id; |
200 } | 233 } |
201 | 234 |
202 void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle) { | 235 void KernelObject::FreeAndReassignFD(int fd, const ScopedKernelHandle& handle, |
236 const std::string &path) { | |
Sam Clegg
2014/01/07 23:56:39
& next to type name.
| |
203 if (NULL == handle) { | 237 if (NULL == handle) { |
204 FreeFD(fd); | 238 FreeFD(fd); |
205 } else { | 239 } else { |
206 AUTO_LOCK(handle_lock_); | 240 AUTO_LOCK(handle_lock_); |
207 | 241 |
208 // If the required FD is larger than the current set, grow the set | 242 // If the required FD is larger than the current set, grow the set |
209 if (fd >= (int)handle_map_.size()) | 243 if (fd >= (int)handle_map_.size()) |
210 handle_map_.resize(fd + 1); | 244 handle_map_.resize(fd + 1); |
211 | 245 |
212 handle_map_[fd] = Descriptor_t(handle); | 246 handle_map_[fd] = Descriptor_t(handle); |
247 // Safe even if oldfd has no path. | |
248 fd_paths_[fd] = path; | |
213 } | 249 } |
214 } | 250 } |
215 | 251 |
216 void KernelObject::FreeFD(int fd) { | 252 void KernelObject::FreeFD(int fd) { |
217 AUTO_LOCK(handle_lock_); | 253 AUTO_LOCK(handle_lock_); |
218 | 254 |
219 handle_map_[fd].handle.reset(NULL); | 255 handle_map_[fd].handle.reset(NULL); |
220 free_fds_.push_back(fd); | 256 free_fds_.push_back(fd); |
221 | 257 |
222 // Force lower numbered FD to be available first. | 258 // Force lower numbered FD to be available first. |
223 std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); | 259 std::push_heap(free_fds_.begin(), free_fds_.end(), std::greater<int>()); |
260 // | |
261 // Remove the FD from the map of fd to absolute path | |
262 fd_paths_.erase(fd); | |
224 } | 263 } |
225 | 264 |
226 } // namespace nacl_io | 265 } // namespace nacl_io |
OLD | NEW |