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

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

Issue 23498015: [NaCl SDK] Support non blocking TCP/UDP (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added Fifo Tests Created 7 years, 3 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 5
6 #include "nacl_io/ossocket.h" 6 #include "nacl_io/ossocket.h"
7 #ifdef PROVIDES_SOCKET_API 7 #ifdef PROVIDES_SOCKET_API
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <string.h> 10 #include <string.h>
11 #include <algorithm> 11 #include <algorithm>
12 12
13 #include "nacl_io/mount.h"
14 #include "nacl_io/mount_node_socket.h"
15 #include "nacl_io/mount_node_tcp.h" 13 #include "nacl_io/mount_node_tcp.h"
14 #include "nacl_io/mount_stream.h"
16 #include "nacl_io/pepper_interface.h" 15 #include "nacl_io/pepper_interface.h"
17 16
17 namespace {
18 size_t kMaxPacketSize = 65536;
binji 2013/09/15 22:18:58 const
noelallen1 2013/09/17 21:21:54 Done.
19 size_t kDefaultFifoSize = kMaxPacketSize * 8;
20 }
21
18 namespace nacl_io { 22 namespace nacl_io {
19 23
20 MountNodeTCP::MountNodeTCP(Mount* mount) : MountNodeSocket(mount) {} 24 class TCPWork : public MountStreamWork {
25 public:
26 TCPWork(EventEmitterTCP* emitter)
binji 2013/09/15 22:18:58 explicit
noelallen1 2013/09/17 21:21:54 Done.
27 : MountStreamWork(emitter->stream()->mount_stream()),
28 emitter_(emitter) {}
29
30 TCPSocketInterface* TCPInterface() {
31 return mount()->ppapi()->GetTCPSocketInterface();
32 }
33
34 protected:
35 ScopedEventEmitterTCP emitter_;
36 };
21 37
22 38
23 TCPSocketInterface* MountNodeTCP::TCPSocket() { 39 class TCPSendWork : public TCPWork {
24 if (mount_->ppapi() == NULL) 40 public:
25 return NULL; 41 TCPSendWork(EventEmitterTCP* emitter) : TCPWork(emitter) {}
binji 2013/09/15 22:18:58 explicit
noelallen1 2013/09/17 21:21:54 Done.
26 42
27 return mount_->ppapi()->GetTCPSocketInterface(); 43 virtual bool Start(int32_t val) {
44 AUTO_LOCK(emitter_->GetLock());
45 MountNodeTCP* stream = reinterpret_cast<MountNodeTCP*>(emitter_->stream());
binji 2013/09/15 22:18:58 static_cast (though unnecessary if you use covaria
noelallen1 2013/09/17 21:21:54 Done.
46 // If the stream is valid, and we are not currently sending
47 if (stream && ((stream->GetStreamFlags() & SSF_SENDING) == 0)) {
48 size_t tx_data_avail = emitter_->tx_fifo()->ReadAvailable();
49 int capped_len =
50 static_cast<int32_t>(std::min(tx_data_avail, kMaxPacketSize));
51 if (capped_len == 0)
52 return false;
53
54 char* data = new char[capped_len];
55 emitter_->ReadTXBytes_Locked(data, capped_len);
56
57 stream->SetStreamFlags(SSF_SENDING);
58 int err = TCPInterface()->Write(stream->socket_resource(),
59 data,
60 capped_len,
61 mount()->GetRunCompletion(this));
62 delete data;
binji 2013/09/15 22:18:58 Deleting the data sent to an async call?
noelallen1 2013/09/17 21:21:54 Consolidated into base class.
63 if (err == PP_OK_COMPLETIONPENDING)
binji 2013/09/15 22:18:58 any way to return this error in case it is not PP_
noelallen1 2013/09/17 21:21:54 Will log once we officially have logging.
64 return true;
65
66 stream->ClearStreamFlags(SSF_SENDING);
67 }
68 return false;
69 }
70
71 virtual void Run(int32_t val) {
binji 2013/09/15 22:18:58 Run is a strange name for this; it isn't meant to
noelallen1 2013/09/17 21:21:54 MountStream::GetOnCompletedCompletion?
72 AUTO_LOCK(emitter_->GetLock());
73 MountNodeTCP* stream = reinterpret_cast<MountNodeTCP*>(emitter_->stream());
binji 2013/09/15 22:18:58 static_cast
noelallen1 2013/09/17 21:21:54 Done.
74
75 // If the stream is still there, see if we can queue more output
76 if (stream) {
77 stream->ClearStreamFlags(SSF_SENDING);
78 stream->QueueOutput();
79 }
80 }
81 };
82
83 class TCPRecvWork : public TCPWork {
84 public:
85 TCPRecvWork(EventEmitterTCP* emitter) : TCPWork(emitter), data_(NULL) {}
binji 2013/09/15 22:18:58 explicit
noelallen1 2013/09/17 21:21:54 Done.
86
87 ~TCPRecvWork() {
88 delete[] data_;
89 }
90
91 virtual bool Start(int32_t val) {
92 AUTO_LOCK(emitter_->GetLock());
93 MountNodeTCP* stream = reinterpret_cast<MountNodeTCP*>(emitter_->stream());
binji 2013/09/15 22:18:58 static_cast
noelallen1 2013/09/17 21:21:54 Done.
94
95 size_t rx_space_avail = emitter_->rx_fifo()->WriteAvailable();
96 int capped_len =
97 static_cast<int32_t>(std::min(rx_space_avail, kMaxPacketSize));
98
99 if (NULL == stream || (stream->GetStreamFlags() & SSF_RECVING) == 0)
100 return false;
101
102 if (capped_len <= 0)
103 return false;
104
105 stream->SetStreamFlags(SSF_RECVING);
106 data_ = new char[capped_len];
107 int err = TCPInterface()->Read(stream->socket_resource(),
108 data_,
binji 2013/09/15 22:18:58 nit: align params
noelallen1 2013/09/17 21:21:54 Done.
109 capped_len,
110 mount()->GetRunCompletion(this));
111 if (err == PP_OK_COMPLETIONPENDING)
112 return true;
113
114 stream->ClearStreamFlags(SSF_RECVING);
115 return false;
116 }
117
118 virtual void Run(int32_t val) {
119 AUTO_LOCK(emitter_->GetLock());
120 MountNodeTCP* stream =
121 reinterpret_cast<MountNodeTCP*>(emitter_->stream());
binji 2013/09/15 22:18:58 static_cast
noelallen1 2013/09/17 21:21:54 Done.
122
123 if (NULL == stream)
124 return;
125
126 // If the stream is still there, see if we can queue more input
127 if (val > 0)
binji 2013/09/15 22:18:58 better name for val? (bytes_read or something?)
noelallen1 2013/09/17 21:21:54 Done.
128 emitter_->WriteRXBytes_Locked(data_, val);
129
130 stream->ClearStreamFlags(SSF_RECVING);
131 stream->QueueInput();
132 }
133
134 private:
135 char* data_;
binji 2013/09/15 22:18:58 std::vector
136 };
137
138
139 MountNodeTCP::MountNodeTCP(Mount* mount)
140 : MountNodeSocket(mount) {
28 } 141 }
29 142
30 Error MountNodeTCP::Init(int flags) { 143 Error MountNodeTCP::Init(int flags) {
31 if (TCPSocket() == NULL) 144 if (TCPInterface() == NULL)
32 return EACCES; 145 return EACCES;
33 146
34 socket_resource_ = TCPSocket()->Create(mount_->ppapi()->GetInstance()); 147 socket_resource_ = TCPInterface()->Create(mount_->ppapi()->GetInstance());
35 if (0 == socket_resource_) 148 if (0 == socket_resource_)
36 return EACCES; 149 return EACCES;
37 150
38 return 0; 151 return 0;
39 } 152 }
40 153
154 EventEmitter* MountNodeTCP::GetEventEmitter() {
155 return NULL;
binji 2013/09/15 22:18:58 Why no emitter?
noelallen1 2013/09/17 21:21:54 Done.
156 }
157
binji 2013/09/15 22:18:58 Looks like TCP is not yet implemented?
noelallen1 2013/09/17 21:21:54 Bind is not allowed on client sockets. There's no
binji 2013/09/19 00:48:54 Sorry, I wasn't talking about Bind, I meant non-bl
noelallen1 2013/09/19 21:29:27 Ah I see, fixed.
41 Error MountNodeTCP::Bind(const struct sockaddr* addr, socklen_t len) { 158 Error MountNodeTCP::Bind(const struct sockaddr* addr, socklen_t len) {
42 AUTO_LOCK(node_lock_); 159 AUTO_LOCK(node_lock_);
43 160
44 if (0 == socket_resource_) 161 if (0 == socket_resource_)
45 return EBADF; 162 return EBADF;
46 163
47 /* Only bind once. */ 164 /* Only bind once. */
48 if (local_addr_ != 0) 165 if (local_addr_ != 0)
49 return EINVAL; 166 return EINVAL;
50 167
51 /* Lie, we won't know until we connect. */ 168 /* Lie, we won't know until we connect. */
52 return 0; 169 return 0;
53 } 170 }
54 171
55 Error MountNodeTCP::Connect(const struct sockaddr* addr, socklen_t len) { 172 Error MountNodeTCP::Connect(const struct sockaddr* addr, socklen_t len) {
56 AUTO_LOCK(node_lock_); 173 AUTO_LOCK(node_lock_);
57 174
58 if (0 == socket_resource_) 175 if (0 == socket_resource_)
59 return EBADF; 176 return EBADF;
60 177
61 if (remote_addr_ != 0) 178 if (remote_addr_ != 0)
62 return EISCONN; 179 return EISCONN;
63 180
64 remote_addr_ = SockAddrToResource(addr, len); 181 remote_addr_ = SockAddrToResource(addr, len);
65 if (0 == remote_addr_) 182 if (0 == remote_addr_)
66 return EINVAL; 183 return EINVAL;
67 184
68 int err = TCPSocket()->Connect(socket_resource_, 185 int err = TCPInterface()->Connect(socket_resource_,
69 remote_addr_, 186 remote_addr_,
70 PP_BlockUntilComplete()); 187 PP_BlockUntilComplete());
71 188
72 // If we fail, release the dest addr resource 189 // If we fail, release the dest addr resource
73 if (err != PP_OK) { 190 if (err != PP_OK) {
74 mount_->ppapi()->ReleaseResource(remote_addr_); 191 mount_->ppapi()->ReleaseResource(remote_addr_);
75 remote_addr_ = 0; 192 remote_addr_ = 0;
76 return PPErrorToErrno(err); 193 return PPErrorToErrno(err);
77 } 194 }
78 195
79 local_addr_ = TCPSocket()->GetLocalAddress(socket_resource_); 196 local_addr_ = TCPInterface()->GetLocalAddress(socket_resource_);
80 mount_->ppapi()->AddRefResource(local_addr_); 197 mount_->ppapi()->AddRefResource(local_addr_);
81 return 0; 198 return 0;
82 } 199 }
83 200
84 Error MountNodeTCP::Recv(void* buf, size_t len, int flags, int* out_len) { 201 Error MountNodeTCP::Recv(void* buf, size_t len, int flags, int* out_len) {
85 AUTO_LOCK(node_lock_); 202 AUTO_LOCK(node_lock_);
86 if (0 == socket_resource_) 203 if (0 == socket_resource_)
87 return EBADF; 204 return EBADF;
88 205
89 int capped_len = static_cast<int32_t>(std::min(len, MAX_SOCK_TRANSFER)); 206 int capped_len = static_cast<int32_t>(std::min(len, MAX_SOCK_TRANSFER));
90 int err = TCPSocket()->Read(socket_resource_, 207 int err = TCPInterface()->Read(socket_resource_,
91 static_cast<char*>(buf), 208 static_cast<char*>(buf),
92 capped_len, 209 capped_len,
93 PP_BlockUntilComplete()); 210 PP_BlockUntilComplete());
94 if (err < 0) 211 if (err < 0)
95 return PPErrorToErrno(err); 212 return PPErrorToErrno(err);
96 213
97 *out_len = err; 214 *out_len = err;
98 return 0; 215 return 0;
99 } 216 }
100 217
101 Error MountNodeTCP::RecvFrom(void* buf, 218 Error MountNodeTCP::RecvFrom(void* buf,
102 size_t len, 219 size_t len,
103 int flags, 220 int flags,
(...skipping 10 matching lines...) Expand all
114 Error MountNodeTCP::Send(const void* buf, size_t len, int flags, int* out_len) { 231 Error MountNodeTCP::Send(const void* buf, size_t len, int flags, int* out_len) {
115 AUTO_LOCK(node_lock_); 232 AUTO_LOCK(node_lock_);
116 233
117 if (0 == socket_resource_) 234 if (0 == socket_resource_)
118 return EBADF; 235 return EBADF;
119 236
120 if (0 == remote_addr_) 237 if (0 == remote_addr_)
121 return ENOTCONN; 238 return ENOTCONN;
122 239
123 int capped_len = static_cast<int32_t>(std::min(len, MAX_SOCK_TRANSFER)); 240 int capped_len = static_cast<int32_t>(std::min(len, MAX_SOCK_TRANSFER));
124 int err = TCPSocket()->Write(socket_resource_, 241 int err = TCPInterface()->Write(socket_resource_,
125 static_cast<const char*>(buf), 242 static_cast<const char*>(buf),
126 capped_len, 243 capped_len,
127 PP_BlockUntilComplete()); 244 PP_BlockUntilComplete());
128 if (err < 0) 245 if (err < 0)
129 return PPErrorToErrno(err); 246 return PPErrorToErrno(err);
130 247
131 *out_len = err; 248 *out_len = err;
132 return 0; 249 return 0;
133 } 250 }
134 251
135 Error MountNodeTCP::SendTo(const void* buf, 252 Error MountNodeTCP::SendTo(const void* buf,
136 size_t len, 253 size_t len,
137 int flags, 254 int flags,
138 const struct sockaddr* dest_addr, 255 const struct sockaddr* dest_addr,
139 socklen_t addrlen, 256 socklen_t addrlen,
140 int* out_len) { 257 int* out_len) {
141 return Send(buf, len, flags, out_len); 258 return Send(buf, len, flags, out_len);
142 } 259 }
143 260
144 } // namespace nacl_io 261 } // namespace nacl_io
145 262
146 #endif // PROVIDES_SOCKET_API 263 #endif // PROVIDES_SOCKET_API
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698