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

Side by Side Diff: native_client_sdk/src/tests/nacl_io_test/jspipe_test.cc

Issue 242533005: [NaCl SDK] nacl_io: Add flow control the JavaScript pipes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/ioctl.h> 8 #include <sys/ioctl.h>
9 #include <sys/select.h> 9 #include <sys/select.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
11 #include <sys/time.h> 11 #include <sys/time.h>
12 #include <string> 12 #include <string>
13 13
14 #include "dev_fs_for_testing.h" 14 #include "dev_fs_for_testing.h"
15 #include "fake_ppapi/fake_messaging_interface.h" 15 #include "fake_ppapi/fake_messaging_interface.h"
16 #include "gtest/gtest.h" 16 #include "gtest/gtest.h"
17 #include "nacl_io/devfs/dev_fs.h" 17 #include "nacl_io/devfs/dev_fs.h"
18 #include "nacl_io/filesystem.h" 18 #include "nacl_io/filesystem.h"
19 #include "nacl_io/ioctl.h" 19 #include "nacl_io/ioctl.h"
20 #include "nacl_io/kernel_intercept.h" 20 #include "nacl_io/kernel_intercept.h"
21 #include "nacl_io/kernel_proxy.h" 21 #include "nacl_io/kernel_proxy.h"
22 #include "nacl_io/osdirent.h" 22 #include "nacl_io/osdirent.h"
23 23
24 using namespace nacl_io; 24 using namespace nacl_io;
25 25
26 namespace { 26 namespace {
27 27
28 // Helper function for calling ki_ioctl without having
29 // to construct a va_list.
30 int ki_ioctl_wrapper(int fd, int request, ...) {
31 va_list ap;
32 va_start(ap, request);
33 int rtn = ki_ioctl(fd, request, ap);
34 va_end(ap);
35 return rtn;
36 }
37
38 // Helper function for converting PP_Var to C++ string
39 std::string VarToString(VarInterface* var_iface, PP_Var var) {
40 EXPECT_EQ(PP_VARTYPE_STRING, var.type);
41 uint32_t len = 0;
42 const char* str = var_iface->VarToUtf8(var, &len);
43 return std::string(str, len);
44 }
45
46 PP_Var VarFromCStr(VarInterface* iface, const char* string) {
47 return iface->VarFromUtf8(string, strlen(string));
48 }
49
50 // Helper function for creating message in the format expected by jspipe
51 // nodes: [ name, payload ]
52 PP_Var CreatePipeMessage(PepperInterface* ppapi, const char* pipe,
53 const char* operation, PP_Var payload) {
54 VarInterface* var_iface = ppapi->GetVarInterface();
55 VarDictionaryInterface* dict_iface = ppapi->GetVarDictionaryInterface();
56
57 // Create a two element array containing the name of the message
58 // as the first element. Its up to the caller the then set the
59 // second array element.
60 PP_Var message = dict_iface->Create();
61 PP_Var pipe_var = VarFromCStr(var_iface, pipe);
62 PP_Var operation_var = VarFromCStr(var_iface, operation);
63 PP_Var pipe_key = VarFromCStr(var_iface, "pipe");
64 PP_Var payload_key = VarFromCStr(var_iface, "payload");
65 PP_Var operation_key = VarFromCStr(var_iface, "operation");
66 dict_iface->Set(message, pipe_key, pipe_var);
67 dict_iface->Set(message, operation_key, operation_var);
68 dict_iface->Set(message, payload_key, payload);
69 var_iface->Release(pipe_var);
70 var_iface->Release(operation_var);
71 var_iface->Release(payload);
72 var_iface->Release(pipe_key);
73 var_iface->Release(payload_key);
74 var_iface->Release(operation_key);
75 return message;
76 }
77
78 // Helper function for creating "ack" message in format expected
79 // by jspipe nodes.
80 PP_Var CreateAckMessage(PepperInterface* ppapi, const char* pipe,
81 int32_t count) {
82 return CreatePipeMessage(ppapi, pipe, "ack", PP_MakeInt32(count));
83 }
84
85 // Helper function for creating "write" message in format expected
86 // by jspipe nodes.
87 PP_Var CreateWriteMessage(PepperInterface* ppapi,
88 const char* pipe,
89 const char* string,
90 int length=-1) {
91 VarArrayBufferInterface* buffer_iface = ppapi->GetVarArrayBufferInterface();
92
93 if (length == -1)
94 length = strlen(string);
95
96 PP_Var buffer = buffer_iface->Create(length);
97 memcpy(buffer_iface->Map(buffer), string, length);
98 buffer_iface->Unmap(buffer);
99
100 return CreatePipeMessage(ppapi, pipe, "write", buffer);
101 }
102
28 class JSPipeTest : public ::testing::Test { 103 class JSPipeTest : public ::testing::Test {
29 public: 104 public:
30 JSPipeTest() : fs_(&pepper_) {}
31
32 void SetUp() { 105 void SetUp() {
33 ASSERT_EQ(0, ki_push_state_for_testing()); 106 ASSERT_EQ(0, ki_push_state_for_testing());
34 ASSERT_EQ(0, ki_init(&kp_)); 107 ASSERT_EQ(0, ki_init_interface(&kp_, &ppapi_));
108 }
109
110 void TearDown() {
111 ki_uninit();
112 }
113
114 protected:
115 FakePepperInterface ppapi_;
116 KernelProxy kp_;
117 };
118
119 class JSPipeNodeTest : public ::testing::Test {
120 public:
121 JSPipeNodeTest() : fs_(&ppapi_) {}
122
123 void SetUp() {
124 name_ = "jspipe1";
35 ASSERT_EQ(0, fs_.Access(Path("/jspipe1"), R_OK | W_OK)); 125 ASSERT_EQ(0, fs_.Access(Path("/jspipe1"), R_OK | W_OK));
36 ASSERT_EQ(EACCES, fs_.Access(Path("/jspipe1"), X_OK)); 126 ASSERT_EQ(EACCES, fs_.Access(Path("/jspipe1"), X_OK));
37 ASSERT_EQ(0, fs_.Open(Path("/jspipe1"), O_RDWR, &pipe_dev_)); 127 ASSERT_EQ(0, fs_.Open(Path("/jspipe1"), O_RDWR, &pipe_dev_));
38 ASSERT_NE(NULL_NODE, pipe_dev_.get()); 128 ASSERT_NE(NULL_NODE, pipe_dev_.get());
39 } 129 }
40 130
41 void TearDown() { ki_uninit(); } 131 /**
132 * Create a PP_Var message in the same way that we expect
133 * JavaScript code to, and send it to the pipe using ioctl()
134 */
135 int JSPipeInject(const char* string, int length=-1) {
136 PP_Var message = CreateWriteMessage(&ppapi_, name_, string, length);
137
138 // Send the message via ioctl
139 int rtn = pipe_dev_->Ioctl(NACL_IOC_HANDLEMESSAGE, &message);
140
141 // Release message
142 ppapi_.GetVarInterface()->Release(message);
143 return rtn;
144 }
145
146 int JSPipeInjectAck(int32_t count) {
147 PP_Var message = CreateAckMessage(&ppapi_, name_, count);
148
149 // Send the message via ioctl
150 int rtn = pipe_dev_->Ioctl(NACL_IOC_HANDLEMESSAGE, &message);
151
152 // Release message
153 ppapi_.GetVarInterface()->Release(message);
154 return rtn;
155 }
156
157 // Verify the contents of the jspipe mesage, which should be
158 // {'<pipe_name>' : ['<command_name>', payload] }
159 void VerifyPipeMessage(PP_Var message,
160 const char* pipe_name,
161 const char* operation,
162 const char* payload,
163 int payload_length,
164 int32_t int_payload=0) {
165 VarArrayInterface* array_iface = ppapi_.GetVarArrayInterface();
166 VarDictionaryInterface* dict_iface = ppapi_.GetVarDictionaryInterface();
167 VarInterface* var_iface = ppapi_.GetVarInterface();
168 VarArrayBufferInterface* buffer_iface = ppapi_.GetVarArrayBufferInterface();
169
170 // Verify we have a dictionary with 3 keys
171 ASSERT_EQ(PP_VARTYPE_DICTIONARY, message.type);
172 PP_Var keys = dict_iface->GetKeys(message);
173 ASSERT_EQ(PP_VARTYPE_ARRAY, keys.type);
174 ASSERT_EQ(3, array_iface->GetLength(keys));
175 var_iface->Release(keys);
176
177 // Verify the keys
178 PP_Var key1 = VarFromCStr(var_iface, "pipe");
179 PP_Var key2 = VarFromCStr(var_iface, "operation");
180 PP_Var key3 = VarFromCStr(var_iface, "payload");
181
182 // Verify pipe name and operation values
183 PP_Var value1 = dict_iface->Get(message, key1);
184 ASSERT_STREQ(pipe_name, VarToString(var_iface, value1).c_str());
185 var_iface->Release(value1);
186 var_iface->Release(key1);
187
188 PP_Var value2 = dict_iface->Get(message, key2);
189 ASSERT_STREQ(operation, VarToString(var_iface, value2).c_str());
190 var_iface->Release(value2);
191 var_iface->Release(key2);
192
193 // Verify the payload
194 PP_Var payload_var = dict_iface->Get(message, key3);
195 if (payload != NULL) {
196 ASSERT_EQ(PP_VARTYPE_ARRAY_BUFFER, payload_var.type);
197 ASSERT_EQ(0, memcmp(payload, buffer_iface->Map(payload_var),
198 payload_length));
199 } else {
200 ASSERT_EQ(PP_VARTYPE_INT32, payload_var.type);
201 ASSERT_EQ(int_payload, payload_var.value.as_int);
202 }
203 var_iface->Release(key3);
204 var_iface->Release(payload_var);
205 }
42 206
43 protected: 207 protected:
44 KernelProxy kp_; 208 FakePepperInterface ppapi_;
45 FakePepperInterface pepper_;
46 DevFsForTesting fs_; 209 DevFsForTesting fs_;
47 ScopedNode pipe_dev_; 210 ScopedNode pipe_dev_;
211 const char* name_;
48 }; 212 };
49 213
50 TEST_F(JSPipeTest, InvalidIoctl) { 214 TEST(JSPipeTestBasic, MissingPepper) {
215 // Create a devfs filesystem without giving it any Pepper implemenation.
216 TypedFsFactory<DevFs> factory;
217 ScopedFilesystem fs;
218 FsInitArgs args(1);
219 factory.CreateFilesystem(args, &fs);
220 ScopedNode pipe_dev;
221 ASSERT_EQ(0, fs->Open(Path("/jspipe1"), O_RDWR, &pipe_dev));
222
223 // Writing to a pipe should return EIO because Pepper is missing.
224 HandleAttr attrs;
225 int written = -1;
226 ASSERT_EQ(EIO, pipe_dev->Write(attrs, "test", 4, &written));
227 }
228
229 TEST_F(JSPipeNodeTest, InvalidIoctl) {
51 // 123 is not a valid ioctl request. 230 // 123 is not a valid ioctl request.
52 EXPECT_EQ(EINVAL, pipe_dev_->Ioctl(123)); 231 EXPECT_EQ(EINVAL, pipe_dev_->Ioctl(123));
53 } 232 }
54 233
55 TEST_F(JSPipeTest, JSPipeInput) { 234 TEST_F(JSPipeNodeTest, JSPipeInput) {
235 std::string message("hello, how are you?\n");
236
56 // First we send some data into the pipe. This is how messages 237 // First we send some data into the pipe. This is how messages
57 // from javascript are injected into the pipe nodes. 238 // from javascript are injected into the pipe nodes.
58 std::string message("hello, how are you?\n"); 239 ASSERT_EQ(0, JSPipeInject(message.c_str()));
59 struct tioc_nacl_input_string packaged_message;
60 packaged_message.length = message.size();
61 packaged_message.buffer = message.data();
62 ASSERT_EQ(0, pipe_dev_->Ioctl(TIOCNACLINPUT, &packaged_message));
63 240
64 // Now we make buffer we'll read into. 241 // Now we make buffer we'll read into.
65 // We fill the buffer and a backup buffer with arbitrary data 242 // We fill the buffer and a backup buffer with arbitrary data
66 // and compare them after reading to make sure read doesn't 243 // and compare them after reading to make sure read doesn't
67 // clobber parts of the buffer it shouldn't. 244 // clobber parts of the buffer it shouldn't.
68 int bytes_read; 245 int bytes_read;
69 char buffer[100]; 246 char buffer[100];
70 char backup_buffer[100]; 247 char backup_buffer[100];
71 memset(buffer, 'a', sizeof(buffer)); 248 memset(buffer, 'a', sizeof(buffer));
72 memset(backup_buffer, 'a', sizeof(backup_buffer)); 249 memset(backup_buffer, 'a', sizeof(backup_buffer));
(...skipping 10 matching lines...) Expand all
83 // it doesn't give us more than there is. 260 // it doesn't give us more than there is.
84 ASSERT_EQ(0, pipe_dev_->Read(attrs, buffer + 5, sizeof(buffer)-5, 261 ASSERT_EQ(0, pipe_dev_->Read(attrs, buffer + 5, sizeof(buffer)-5,
85 &bytes_read)); 262 &bytes_read));
86 EXPECT_EQ(bytes_read, message.size() - 5); 263 EXPECT_EQ(bytes_read, message.size() - 5);
87 EXPECT_EQ(0, memcmp(message.data(), buffer, message.size())); 264 EXPECT_EQ(0, memcmp(message.data(), buffer, message.size()));
88 EXPECT_EQ(0, memcmp(buffer + message.size(), 265 EXPECT_EQ(0, memcmp(buffer + message.size(),
89 backup_buffer + message.size(), 266 backup_buffer + message.size(),
90 100 - message.size())); 267 100 - message.size()));
91 } 268 }
92 269
93 TEST_F(JSPipeTest, JSPipeOutput) { 270 TEST_F(JSPipeNodeTest, JSPipeOutput) {
94 const char* message = "hello"; 271 std::string message("hello");
95 const int message_len = strlen(message);
96 272
97 int bytes_written = 999; 273 int bytes_written = 999;
98 HandleAttr attrs; 274 HandleAttr attrs;
99 ASSERT_EQ(0, pipe_dev_->Write(attrs, message, message_len, &bytes_written)); 275 ASSERT_EQ(0, pipe_dev_->Write(attrs, message.c_str(), message.size(),
100 ASSERT_EQ(message_len, bytes_written); 276 &bytes_written));
277 ASSERT_EQ(message.size(), bytes_written);
101 278
102 // Verify that the correct messages was sent via PostMessage.
103 FakeMessagingInterface* iface = 279 FakeMessagingInterface* iface =
104 (FakeMessagingInterface*)fs_.ppapi()->GetMessagingInterface(); 280 (FakeMessagingInterface*)ppapi_.GetMessagingInterface();
105 VarArrayInterface* array_iface = fs_.ppapi()->GetVarArrayInterface();
106 VarInterface* var_iface = fs_.ppapi()->GetVarInterface();
107 VarArrayBufferInterface* buffer_iface =
108 fs_.ppapi()->GetVarArrayBufferInterface();
109 281
110 // Verify that exaclty one message was sent of type PP_VARTYPE_ARRAY 282 // Verify that exactly one message sent.
111 ASSERT_EQ(1, iface->messages.size()); 283 ASSERT_EQ(1, iface->messages.size());
112 PP_Var array = iface->messages[0]; 284 PP_Var message_var = iface->messages[0];
113 ASSERT_EQ(PP_VARTYPE_ARRAY, array.type);
114 285
115 // Verify that the array contains two element, the prefix, 286 // Verify the content of the message.
116 // and an ArrayBuffer containing the message. 287 VerifyPipeMessage(message_var, "jspipe1", "write", message.c_str(),
117 ASSERT_EQ(2, array_iface->GetLength(array)); 288 message.size());
118 PP_Var item0 = array_iface->Get(array, 0);
119 PP_Var item1 = array_iface->Get(array, 1);
120 ASSERT_EQ(PP_VARTYPE_STRING, item0.type);
121 ASSERT_EQ(PP_VARTYPE_ARRAY_BUFFER, item1.type);
122 uint32_t len = 0;
123 const char* item0_string = var_iface->VarToUtf8(item0, &len);
124 ASSERT_STREQ("jspipe1", std::string(item0_string, len).c_str());
125 ASSERT_EQ(0, memcmp(message, buffer_iface->Map(item1), strlen(message)));
126 var_iface->Release(item0);
127 var_iface->Release(item1);
128 } 289 }
129 290
130 TEST_F(JSPipeTest, JSPipeOutputWithNulls) { 291 TEST_F(JSPipeNodeTest, JSPipeOutputWithNulls) {
131 char message[20]; 292 char message[20];
132 int message_len = sizeof(message); 293 int message_len = sizeof(message);
133 294
134 // Construct a 20-byte message containing the string 'hello' but with 295 // Construct a 20-byte message containing the string 'hello' but with
135 // null chars on either end. 296 // null chars on either end.
136 memset(message, 0 , message_len); 297 memset(message, 0 , message_len);
137 memcpy(message+10, "hello", 5); 298 memcpy(message+10, "hello", 5);
138 299
139 int bytes_written = 999; 300 int bytes_written = 999;
140 HandleAttr attrs; 301 HandleAttr attrs;
141 EXPECT_EQ(0, pipe_dev_->Write(attrs, message, message_len, &bytes_written)); 302 EXPECT_EQ(0, pipe_dev_->Write(attrs, message, message_len, &bytes_written));
142 EXPECT_EQ(message_len, bytes_written); 303 EXPECT_EQ(message_len, bytes_written);
143 304
144 // Verify that the correct messages was sent via PostMessage. 305 // Verify that the correct messages was sent via PostMessage.
145 FakeMessagingInterface* iface = 306 FakeMessagingInterface* iface =
146 (FakeMessagingInterface*)fs_.ppapi()->GetMessagingInterface(); 307 (FakeMessagingInterface*)ppapi_.GetMessagingInterface();
147 VarArrayInterface* array_iface = fs_.ppapi()->GetVarArrayInterface();
148 VarInterface* var_iface = fs_.ppapi()->GetVarInterface();
149 VarArrayBufferInterface* buffer_iface =
150 fs_.ppapi()->GetVarArrayBufferInterface();
151 308
152 // Verify that exactly one message was sent of type PP_VARTYPE_ARRAY 309 // Verify that exaclty one message sent.
153 EXPECT_EQ(1, iface->messages.size()); 310 ASSERT_EQ(1, iface->messages.size());
154 PP_Var array = iface->messages[0]; 311 PP_Var message_var = iface->messages[0];
155 ASSERT_EQ(PP_VARTYPE_ARRAY, array.type);
156 312
157 // Verify that the array contains two element, the prefix, 313 // Verify the content of the message.
158 // and an ArrayBuffer containing the message. 314 VerifyPipeMessage(message_var, "jspipe1", "write", message, message_len);
159 ASSERT_EQ(2, array_iface->GetLength(array));
160 PP_Var item0 = array_iface->Get(array, 0);
161 PP_Var item1 = array_iface->Get(array, 1);
162 ASSERT_EQ(PP_VARTYPE_STRING, item0.type);
163 ASSERT_EQ(PP_VARTYPE_ARRAY_BUFFER, item1.type);
164 uint32_t len = 0;
165 ASSERT_STREQ("jspipe1", var_iface->VarToUtf8(item0, &len));
166 ASSERT_EQ(0, memcmp(message, buffer_iface->Map(item1), strlen(message)));
167 var_iface->Release(item0);
168 var_iface->Release(item1);
169 } 315 }
170 316
171 static int ki_ioctl_wrapper(int fd, int request, ...) { 317 #define CHUNK_SIZE 678
172 va_list ap; 318 TEST_F(JSPipeNodeTest, JSPipeOutputBuffer) {
173 va_start(ap, request); 319 int ospace_orig = -1;
174 int rtn = ki_ioctl(fd, request, ap); 320 ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETOSPACE, &ospace_orig));
175 va_end(ap); 321 ASSERT_GT(ospace_orig, 0);
176 return rtn; 322
323 HandleAttr attrs;
324 attrs.flags = O_NONBLOCK;
325 char* message = (char*)malloc(CHUNK_SIZE);
326
327 // Keep writing data until we block.
328 int total_written = 0;
329 while (1) {
330 int bytes_written;
331 // Write some data
332 int rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
333 if (rtn != 0) {
334 ASSERT_EQ(EWOULDBLOCK, rtn);
335 int ospace = -1;
336 ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETOSPACE, &ospace));
337 ASSERT_EQ(0, ospace);
338 ASSERT_EQ(total_written, ospace_orig);
339 break;
340 }
341 total_written += bytes_written;
342 }
343
344 // At this point writes should always block
345 int bytes_written;
346 int rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
347 ASSERT_EQ(EWOULDBLOCK, rtn);
348
349 // Now inject and ACK message from JavaScript.
350 ASSERT_EQ(0, JSPipeInjectAck(10));
351
352 // Now it should be possible to write 10 bytes to the pipe.
353 rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
354 ASSERT_EQ(0, rtn);
355 ASSERT_EQ(10, bytes_written);
356
357 free(message);
177 } 358 }
178 359
179 static int JSPipeWrite(int fd, const char* string) { 360 TEST_F(JSPipeNodeTest, JSPipeInputBuffer) {
180 struct tioc_nacl_input_string input; 361 char* message = (char*)malloc(CHUNK_SIZE);
181 input.buffer = string; 362 memset(message, 1, CHUNK_SIZE);
182 input.length = strlen(input.buffer); 363
183 return ki_ioctl_wrapper(fd, TIOCNACLINPUT, &input); 364 int ispace_orig = -1;
365 ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETISPACE, &ispace_orig));
366
367 // Keep injecting data until the ioctl fails
368 int total_written = 0;
369 while (1) {
370 int rtn = JSPipeInject(message, CHUNK_SIZE);
371 if (rtn != 0) {
372 ASSERT_LT(total_written, ispace_orig);
373 ASSERT_GT(total_written, ispace_orig - CHUNK_SIZE - 1);
374 break;
375 }
376 total_written += CHUNK_SIZE;
377 }
378
379 int ispace = -1;
380 ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETISPACE, &ispace));
381 ASSERT_EQ(0, ispace);
382
383 // Check that no messages have thus far been sent to JavaScript
384 FakeMessagingInterface* iface =
385 (FakeMessagingInterface*)ppapi_.GetMessagingInterface();
386 ASSERT_EQ(0, iface->messages.size());
387
388 // Read some data from the pipe, which should trigger an ack message
389 int bytes_read = -1;
390 HandleAttr attrs;
391 ASSERT_EQ(0, pipe_dev_->Read(attrs, message, 5, &bytes_read));
392 ASSERT_EQ(5, bytes_read);
393
394 // Verify that an ack was sent to JavaScript
395 ASSERT_EQ(1, iface->messages.size());
396 PP_Var message_var = iface->messages[0];
397 VerifyPipeMessage(message_var, "jspipe1", "ack", NULL, 0, 5);
184 } 398 }
185 399
186 // Returns: 400 // Returns:
187 // 0 -> Not readable 401 // 0 -> Not readable
188 // 1 -> Readable 402 // 1 -> Readable
189 // -1 -> Error occured 403 // -1 -> Error occured
190 static int IsReadable(int fd) { 404 int IsReadable(int fd) {
191 struct timeval timeout = {0, 0}; 405 struct timeval timeout = {0, 0};
192 fd_set readfds; 406 fd_set readfds;
193 fd_set errorfds; 407 fd_set errorfds;
194 FD_ZERO(&readfds); 408 FD_ZERO(&readfds);
195 FD_ZERO(&errorfds); 409 FD_ZERO(&errorfds);
196 FD_SET(fd, &readfds); 410 FD_SET(fd, &readfds);
197 FD_SET(fd, &errorfds); 411 FD_SET(fd, &errorfds);
198 int rtn = ki_select(fd + 1, &readfds, NULL, &errorfds, &timeout); 412 int rtn = ki_select(fd + 1, &readfds, NULL, &errorfds, &timeout);
199 if (rtn == 0) 413 if (rtn == 0)
200 return 0; // not readable 414 return 0; // not readable
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 FD_SET(pipe_fd, &readfds); 449 FD_SET(pipe_fd, &readfds);
236 FD_SET(pipe_fd, &writefds); 450 FD_SET(pipe_fd, &writefds);
237 FD_SET(pipe_fd, &errorfds); 451 FD_SET(pipe_fd, &errorfds);
238 // Pipe should be writable on startup. 452 // Pipe should be writable on startup.
239 rtn = ki_select(pipe_fd + 1, &readfds, &writefds, &errorfds, NULL); 453 rtn = ki_select(pipe_fd + 1, &readfds, &writefds, &errorfds, NULL);
240 ASSERT_EQ(1, rtn); 454 ASSERT_EQ(1, rtn);
241 ASSERT_TRUE(FD_ISSET(pipe_fd, &writefds)); 455 ASSERT_TRUE(FD_ISSET(pipe_fd, &writefds));
242 ASSERT_FALSE(FD_ISSET(pipe_fd, &readfds)); 456 ASSERT_FALSE(FD_ISSET(pipe_fd, &readfds));
243 ASSERT_FALSE(FD_ISSET(pipe_fd, &errorfds)); 457 ASSERT_FALSE(FD_ISSET(pipe_fd, &errorfds));
244 458
245 // Send 4 bytes to the pipe 459 // Send 4 bytes to the pipe via ioctl
246 ASSERT_EQ(0, JSPipeWrite(pipe_fd, "test")); 460 PP_Var message = CreateWriteMessage(&ppapi_, "jspipe1", "test");
461 ASSERT_EQ(0, ki_ioctl_wrapper(pipe_fd, NACL_IOC_HANDLEMESSAGE, &message));
462 ppapi_.GetVarInterface()->Release(message);
247 463
248 // Pipe should now be readable 464 // Pipe should now be readable
249 ASSERT_EQ(1, IsReadable(pipe_fd)); 465 ASSERT_EQ(1, IsReadable(pipe_fd));
250 466
251 ki_close(pipe_fd); 467 ki_close(pipe_fd);
252 } 468 }
253 469
254 } 470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698