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

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

Issue 26703008: [NaCl SDK] nacl_io: Add support for non-blocking connect/accept (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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_handle.h" 5 #include "nacl_io/kernel_handle.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <pthread.h> 8 #include <pthread.h>
9 9
10 #include "nacl_io/mount.h" 10 #include "nacl_io/mount.h"
11 #include "nacl_io/mount_node.h" 11 #include "nacl_io/mount_node.h"
12 #include "nacl_io/mount_node_socket.h"
12 #include "nacl_io/osunistd.h" 13 #include "nacl_io/osunistd.h"
13 14
14 #include "sdk_util/auto_lock.h" 15 #include "sdk_util/auto_lock.h"
15 16
16 namespace nacl_io { 17 namespace nacl_io {
17 18
18 // It is only legal to construct a handle while the kernel lock is held. 19 // It is only legal to construct a handle while the kernel lock is held.
19 KernelHandle::KernelHandle() 20 KernelHandle::KernelHandle()
20 : mount_(NULL), node_(NULL) {} 21 : mount_(NULL), node_(NULL) {}
21 22
22 KernelHandle::KernelHandle(const ScopedMount& mnt, const ScopedMountNode& node) 23 KernelHandle::KernelHandle(const ScopedMount& mnt, const ScopedMountNode& node)
23 : mount_(mnt), node_(node) {} 24 : mount_(mnt), node_(node) {}
24 25
25 KernelHandle::~KernelHandle() { 26 KernelHandle::~KernelHandle() {
26 // Force release order for cases where mount_ is not ref'd by mounting. 27 // Force release order for cases where mount_ is not ref'd by mounting.
27 node_.reset(NULL); 28 node_.reset(NULL);
28 mount_.reset(NULL); 29 mount_.reset(NULL);
29 } 30 }
30 31
31 // Returns the MountNodeSocket* if this node is a socket. 32 // Returns the MountNodeSocket* if this node is a socket.
32 MountNodeSocket* KernelHandle::socket_node() { 33 MountNodeSocket* KernelHandle::socket_node() {
33 if (node_.get() && node_->IsaSock()) 34 if (node_.get() && node_->IsaSock())
34 return reinterpret_cast<MountNodeSocket*>(node_.get()); 35 return reinterpret_cast<MountNodeSocket*>(node_.get());
35 return NULL; 36 return NULL;
36 } 37 }
37 38
38 Error KernelHandle::Init(int open_flags) { 39 Error KernelHandle::Init(int open_flags) {
39 handle_data_.flags = open_flags; 40 handle_attr_.flags = open_flags;
40 41
41 if (open_flags & O_APPEND) { 42 if (open_flags & O_APPEND) {
42 Error error = node_->GetSize(&handle_data_.offs); 43 Error error = node_->GetSize(&handle_attr_.offs);
43 if (error) 44 if (error)
44 return error; 45 return error;
45 } 46 }
46 47
47 return 0; 48 return 0;
48 } 49 }
49 50
50 Error KernelHandle::Seek(off_t offset, int whence, off_t* out_offset) { 51 Error KernelHandle::Seek(off_t offset, int whence, off_t* out_offset) {
51 // By default, don't move the offset. 52 // By default, don't move the offset.
52 *out_offset = offset; 53 *out_offset = offset;
53 size_t base; 54 size_t base;
54 size_t node_size; 55 size_t node_size;
55 56
56 AUTO_LOCK(handle_lock_); 57 AUTO_LOCK(handle_lock_);
57 Error error = node_->GetSize(&node_size); 58 Error error = node_->GetSize(&node_size);
58 if (error) 59 if (error)
59 return error; 60 return error;
60 61
61 switch (whence) { 62 switch (whence) {
62 default: 63 default:
63 return -1; 64 return -1;
64 case SEEK_SET: 65 case SEEK_SET:
65 base = 0; 66 base = 0;
66 break; 67 break;
67 case SEEK_CUR: 68 case SEEK_CUR:
68 base = handle_data_.offs; 69 base = handle_attr_.offs;
69 break; 70 break;
70 case SEEK_END: 71 case SEEK_END:
71 base = node_size; 72 base = node_size;
72 break; 73 break;
73 } 74 }
74 75
75 if (base + offset < 0) 76 if (base + offset < 0)
76 return EINVAL; 77 return EINVAL;
77 78
78 off_t new_offset = base + offset; 79 off_t new_offset = base + offset;
79 80
80 // Seeking past the end of the file will zero out the space between the old 81 // Seeking past the end of the file will zero out the space between the old
81 // end and the new end. 82 // end and the new end.
82 if (new_offset > node_size) { 83 if (new_offset > node_size) {
83 error = node_->FTruncate(new_offset); 84 error = node_->FTruncate(new_offset);
84 if (error) 85 if (error)
85 return EINVAL; 86 return EINVAL;
86 } 87 }
87 88
88 *out_offset = handle_data_.offs = new_offset; 89 *out_offset = handle_attr_.offs = new_offset;
89 return 0; 90 return 0;
90 } 91 }
91 92
92 Error KernelHandle::Read(void* buf, size_t nbytes, int* cnt) { 93 Error KernelHandle::Read(void* buf, size_t nbytes, int* cnt) {
93 AUTO_LOCK(handle_lock_); 94 AUTO_LOCK(handle_lock_);
94 Error error = node_->Read(handle_data_, buf, nbytes, cnt); 95 Error error = node_->Read(handle_attr_, buf, nbytes, cnt);
95 if (0 == error) 96 if (0 == error)
96 handle_data_.offs += *cnt; 97 handle_attr_.offs += *cnt;
97 return error; 98 return error;
98 } 99 }
99 100
100 Error KernelHandle::Write(const void* buf, size_t nbytes, int* cnt) { 101 Error KernelHandle::Write(const void* buf, size_t nbytes, int* cnt) {
101 AUTO_LOCK(handle_lock_); 102 AUTO_LOCK(handle_lock_);
102 Error error = node_->Write(handle_data_, buf, nbytes, cnt); 103 Error error = node_->Write(handle_attr_, buf, nbytes, cnt);
103 if (0 == error) 104 if (0 == error)
104 handle_data_.offs += *cnt; 105 handle_attr_.offs += *cnt;
105 return error; 106 return error;
106 } 107 }
107 108
108 Error KernelHandle::GetDents(struct dirent* pdir, size_t nbytes, int* cnt) { 109 Error KernelHandle::GetDents(struct dirent* pdir, size_t nbytes, int* cnt) {
109 AUTO_LOCK(handle_lock_); 110 AUTO_LOCK(handle_lock_);
110 Error error = node_->GetDents(handle_data_.offs, pdir, nbytes, cnt); 111 Error error = node_->GetDents(handle_attr_.offs, pdir, nbytes, cnt);
111 if (0 == error) 112 if (0 == error)
112 handle_data_.offs += *cnt; 113 handle_attr_.offs += *cnt;
113 return error; 114 return error;
114 } 115 }
115 116
116 Error KernelHandle::Fcntl(int request, int* result, ...) { 117 Error KernelHandle::Fcntl(int request, int* result, ...) {
117 va_list ap; 118 va_list ap;
118 va_start(ap, result); 119 va_start(ap, result);
119 Error rtn = VFcntl(request, result, ap); 120 Error rtn = VFcntl(request, result, ap);
120 va_end(ap); 121 va_end(ap);
121 return rtn; 122 return rtn;
122 } 123 }
123 124
124 Error KernelHandle::VFcntl(int request, int* result, va_list args) { 125 Error KernelHandle::VFcntl(int request, int* result, va_list args) {
125 switch (request) { 126 switch (request) {
126 case F_GETFL: { 127 case F_GETFL: {
127 *result = handle_data_.flags; 128 *result = handle_attr_.flags;
128 return 0; 129 return 0;
129 } 130 }
130 case F_SETFL: { 131 case F_SETFL: {
131 AUTO_LOCK(handle_lock_); 132 AUTO_LOCK(handle_lock_);
132 int flags = va_arg(args, int); 133 int flags = va_arg(args, int);
133 if (!(flags & O_APPEND) && (handle_data_.flags & O_APPEND)) { 134 if (!(flags & O_APPEND) && (handle_attr_.flags & O_APPEND)) {
134 // Attempt to clear O_APPEND. 135 // Attempt to clear O_APPEND.
135 return EPERM; 136 return EPERM;
136 } 137 }
137 // Only certain flags are mutable 138 // Only certain flags are mutable
138 const int mutable_flags = O_ASYNC | O_NONBLOCK; 139 const int mutable_flags = O_ASYNC | O_NONBLOCK;
139 flags &= mutable_flags; 140 flags &= mutable_flags;
140 handle_data_.flags &= ~mutable_flags; 141 handle_attr_.flags &= ~mutable_flags;
141 handle_data_.flags |= flags; 142 handle_attr_.flags |= flags;
142 return 0; 143 return 0;
143 } 144 }
144 } 145 }
145 return ENOSYS; 146 return ENOSYS;
146 } 147 }
147 148
149 Error KernelHandle::Accept(PP_Resource* new_sock, struct sockaddr* addr,
150 socklen_t* len) {
151 MountNodeSocket* sock = socket_node();
152 if (!sock)
153 return ENOTSOCK;
154
155 AUTO_LOCK(handle_lock_);
156 return sock->Accept(handle_attr_, new_sock, addr, len);
157 }
158
159 Error KernelHandle::Connect(const struct sockaddr* addr, socklen_t len) {
160 MountNodeSocket* sock = socket_node();
161 if (!sock)
162 return ENOTSOCK;
163
164 AUTO_LOCK(handle_lock_);
165 return sock->Connect(handle_attr_, addr, len);
166 }
167
168 Error KernelHandle::Recv(void* buf, size_t len, int flags, int* out_len) {
169 MountNodeSocket* sock = socket_node();
170 if (!sock)
171 return ENOTSOCK;
172
173 AUTO_LOCK(handle_lock_);
174 return sock->Recv(handle_attr_, buf, len, flags, out_len);
175 }
176
177 Error KernelHandle::RecvFrom(void* buf,
178 size_t len,
179 int flags,
180 struct sockaddr* src_addr,
181 socklen_t* addrlen,
182 int* out_len) {
183 MountNodeSocket* sock = socket_node();
184 if (!sock)
185 return ENOTSOCK;
186
187 AUTO_LOCK(handle_lock_);
188 return sock->RecvFrom(handle_attr_, buf, len, flags, src_addr, addrlen,
189 out_len);
190 }
191
192 Error KernelHandle::Send(const void* buf,
193 size_t len,
194 int flags,
195 int* out_len) {
196 MountNodeSocket* sock = socket_node();
197 if (!sock)
198 return ENOTSOCK;
199
200 AUTO_LOCK(handle_lock_);
201 return sock->Send(handle_attr_, buf, len, flags, out_len);
202 }
203
204 Error KernelHandle::SendTo(const void* buf,
205 size_t len,
206 int flags,
207 const struct sockaddr* dest_addr,
208 socklen_t addrlen,
209 int* out_len) {
210 MountNodeSocket* sock = socket_node();
211 if (!sock)
212 return ENOTSOCK;
213
214 AUTO_LOCK(handle_lock_);
215 return sock->SendTo(handle_attr_, buf, len, flags, dest_addr, addrlen,
216 out_len);
217 }
218
148 } // namespace nacl_io 219 } // namespace nacl_io
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698