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

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

Issue 12194030: Rename mount (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix whitespace Created 7 years, 10 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
(Empty)
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
3 * found in the LICENSE file.
4 */
5 #include "nacl_mounts/kernel_object.h"
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <pthread.h>
11
12 #include <algorithm>
13 #include <map>
14 #include <string>
15 #include <vector>
16
17 #include "nacl_mounts/kernel_handle.h"
18 #include "nacl_mounts/mount.h"
19 #include "nacl_mounts/mount_node.h"
20 #include "utils/auto_lock.h"
21
22 KernelObject::KernelObject() {
23 pthread_mutex_init(&kernel_lock_, NULL);
24 pthread_mutex_init(&process_lock_, NULL);
25 }
26
27 KernelObject::~KernelObject() {
28 pthread_mutex_destroy(&process_lock_);
29 pthread_mutex_destroy(&kernel_lock_);
30 }
31
32 // Uses longest prefix to find the mount for the give path, then
33 // acquires the mount and returns it with a relative path.
34 Mount* KernelObject::AcquireMountAndPath(const std::string& relpath,
35 Path* out_path) {
36 Path abs_path;
37 {
38 AutoLock lock(&process_lock_);
39 abs_path = GetAbsPathLocked(relpath);
40 }
41
42 AutoLock lock(&kernel_lock_);
43 Mount* mount = NULL;
44
45
46 // Find longest prefix
47 size_t max = abs_path.Size();
48 for (size_t len = 0; len < abs_path.Size(); len++) {
49 MountMap_t::iterator it = mounts_.find(abs_path.Range(0, max - len));
50 if (it != mounts_.end()) {
51 out_path->Set("/");
52 out_path->Append(abs_path.Range(max - len, max));
53 mount = it->second;
54 break;
55 }
56 }
57
58 if (NULL == mount) {
59 errno = ENOTDIR;
60 return NULL;
61 }
62
63 // Acquire the mount while we hold the proxy lock
64 mount->Acquire();
65 return mount;
66 }
67
68 void KernelObject::ReleaseMount(Mount* mnt) {
69 AutoLock lock(&kernel_lock_);
70 mnt->Release();
71 }
72
73 KernelHandle* KernelObject::AcquireHandle(int fd) {
74 AutoLock lock(&process_lock_);
75 if (fd < 0 || fd >= static_cast<int>(handle_map_.size())) {
76 errno = EBADF;
77 return NULL;
78 }
79
80 KernelHandle* handle = handle_map_[fd];
81 if (NULL == handle) {
82 errno = EBADF;
83 return NULL;
84 }
85
86 // Ref count while holding parent mutex
87 handle->Acquire();
88
89 lock.Unlock();
90 if (handle->node_) handle->mount_->AcquireNode(handle->node_);
91
92 return handle;
93 }
94
95 void KernelObject::ReleaseHandle(KernelHandle* handle) {
96 // The handle must already be held before taking the
97 // kernel lock.
98 if (handle->node_) handle->mount_->ReleaseNode(handle->node_);
99
100 AutoLock lock(&process_lock_);
101 handle->Release();
102 }
103
104 // Helper function to properly sort FD order in the heap, forcing
105 // lower numberd 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) {
111 AutoLock lock(&process_lock_);
112 int id;
113
114 // Acquire the handle and its mount since we are about to track it with
115 // this FD.
116 handle->Acquire();
117 handle->mount_->Acquire();
118
119 // If we can recycle and FD, use that first
120 if (free_fds_.size()) {
121 id = free_fds_.front();
122 std::pop_heap(free_fds_.begin(), free_fds_.end(), FdOrder);
123 free_fds_.pop_back();
124 handle_map_[id] = handle;
125 } else {
126 id = handle_map_.size();
127 handle_map_.push_back(handle);
128 }
129 return id;
130 }
131
132 void KernelObject::AssignFD(int fd, KernelHandle* handle) {
133 AutoLock lock(&process_lock_);
134
135 // Acquire the handle and its mount since we are about to track it with
136 // this FD.
137 handle->Acquire();
138 handle->mount_->Acquire();
139
140 if (fd >= handle_map_.size())
141 handle_map_.resize(fd + 1);
142
143 assert(handle_map_[fd] == NULL);
144 handle_map_[fd] = handle;
145 }
146
147 void KernelObject::FreeFD(int fd) {
148 AutoLock lock(&process_lock_);
149
150 // Release the mount and handle since we no longer
151 // track them with this FD.
152 KernelHandle* handle = handle_map_[fd];
153 handle->mount_->Release();
154 handle->Release();
155
156 handle_map_[fd] = NULL;
157 free_fds_.push_back(fd);
158 std::push_heap(free_fds_.begin(), free_fds_.end(), FdOrder);
159 }
160
161 Path KernelObject::GetAbsPathLocked(const std::string& path) {
162 // Generate absolute path
163 Path abs_path(cwd_);
164 if (path[0] == '/') {
165 abs_path = path;
166 } else {
167 abs_path = cwd_;
168 abs_path.Append(path);
169 }
170
171 return abs_path;
172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698