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

Side by Side Diff: src/d8-posix.cc

Issue 63062: Timeout of os.system() in d8 was timing out too soon. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 8 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 98 }
99 } 99 }
100 return 0; 100 return 0;
101 } 101 }
102 102
103 103
104 // Suspends the thread until there is data available from the child process. 104 // Suspends the thread until there is data available from the child process.
105 // Returns false on timeout, true on data ready. 105 // Returns false on timeout, true on data ready.
106 static bool WaitOnFD(int fd, 106 static bool WaitOnFD(int fd,
107 int read_timeout, 107 int read_timeout,
108 int* total_timeout, 108 int total_timeout,
109 struct timeval& start_time) { 109 struct timeval& start_time) {
110 fd_set readfds, writefds, exceptfds; 110 fd_set readfds, writefds, exceptfds;
111 struct timeval timeout; 111 struct timeval timeout;
112 if (*total_timeout != -1) { 112 int gone = 0;
113 if (total_timeout != -1) {
113 struct timeval time_now; 114 struct timeval time_now;
114 gettimeofday(&time_now, NULL); 115 gettimeofday(&time_now, NULL);
115 int seconds = time_now.tv_sec - start_time.tv_sec; 116 int seconds = time_now.tv_sec - start_time.tv_sec;
116 int gone = seconds * 1000 + (time_now.tv_usec - start_time.tv_usec) / 1000; 117 gone = seconds * 1000 + (time_now.tv_usec - start_time.tv_usec) / 1000;
117 if (gone >= *total_timeout) return false; 118 if (gone >= total_timeout) return false;
118 *total_timeout -= gone;
119 } 119 }
120 FD_ZERO(&readfds); 120 FD_ZERO(&readfds);
121 FD_ZERO(&writefds); 121 FD_ZERO(&writefds);
122 FD_ZERO(&exceptfds); 122 FD_ZERO(&exceptfds);
123 FD_SET(fd, &readfds); 123 FD_SET(fd, &readfds);
124 FD_SET(fd, &exceptfds); 124 FD_SET(fd, &exceptfds);
125 if (read_timeout == -1 || 125 if (read_timeout == -1 ||
126 (*total_timeout != -1 && *total_timeout < read_timeout)) { 126 (total_timeout != -1 && total_timeout - gone < read_timeout)) {
127 read_timeout = *total_timeout; 127 read_timeout = total_timeout - gone;
128 } 128 }
129 timeout.tv_usec = (read_timeout % 1000) * 1000; 129 timeout.tv_usec = (read_timeout % 1000) * 1000;
130 timeout.tv_sec = read_timeout / 1000; 130 timeout.tv_sec = read_timeout / 1000;
131 int number_of_fds_ready = select(fd + 1, 131 int number_of_fds_ready = select(fd + 1,
132 &readfds, 132 &readfds,
133 &writefds, 133 &writefds,
134 &exceptfds, 134 &exceptfds,
135 read_timeout != -1 ? &timeout : NULL); 135 read_timeout != -1 ? &timeout : NULL);
136 return number_of_fds_ready == 1; 136 return number_of_fds_ready == 1;
137 } 137 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 299 }
300 return true; 300 return true;
301 } 301 }
302 302
303 303
304 // Accumulates the output from the child in a string handle. Returns true if it 304 // Accumulates the output from the child in a string handle. Returns true if it
305 // succeeded or false if an exception was thrown. 305 // succeeded or false if an exception was thrown.
306 static Handle<Value> GetStdout(int child_fd, 306 static Handle<Value> GetStdout(int child_fd,
307 struct timeval& start_time, 307 struct timeval& start_time,
308 int read_timeout, 308 int read_timeout,
309 int* total_timeout) { 309 int total_timeout) {
310 Handle<String> accumulator = String::Empty(); 310 Handle<String> accumulator = String::Empty();
311 const char* source = "function(a, b) { return a + b; }"; 311 const char* source = "function(a, b) { return a + b; }";
312 Handle<Value> cons_as_obj(Script::Compile(String::New(source))->Run()); 312 Handle<Value> cons_as_obj(Script::Compile(String::New(source))->Run());
313 Handle<Function> cons_function(Function::Cast(*cons_as_obj)); 313 Handle<Function> cons_function(Function::Cast(*cons_as_obj));
314 Handle<Value> cons_args[2]; 314 Handle<Value> cons_args[2];
315 315
316 int fullness = 0; 316 int fullness = 0;
317 static const int kStdoutReadBufferSize = 4096; 317 static const int kStdoutReadBufferSize = 4096;
318 char buffer[kStdoutReadBufferSize]; 318 char buffer[kStdoutReadBufferSize];
319 319
320 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) { 320 if (fcntl(child_fd, F_SETFL, O_NONBLOCK) != 0) {
321 return ThrowException(String::New(strerror(errno))); 321 return ThrowException(String::New(strerror(errno)));
322 } 322 }
323 323
324 int bytes_read; 324 int bytes_read;
325 do { 325 do {
326 bytes_read = read(child_fd, 326 bytes_read = read(child_fd,
327 buffer + fullness, 327 buffer + fullness,
328 kStdoutReadBufferSize - fullness); 328 kStdoutReadBufferSize - fullness);
329 if (bytes_read == -1) { 329 if (bytes_read == -1) {
330 if (errno == EAGAIN) { 330 if (errno == EAGAIN) {
331 if (!WaitOnFD(child_fd, 331 if (!WaitOnFD(child_fd,
332 read_timeout, 332 read_timeout,
333 total_timeout, 333 total_timeout,
334 start_time) || 334 start_time) ||
335 (TimeIsOut(start_time, *total_timeout))) { 335 (TimeIsOut(start_time, total_timeout))) {
336 return ThrowException(String::New("Timed out waiting for output")); 336 return ThrowException(String::New("Timed out waiting for output"));
337 } 337 }
338 continue; 338 continue;
339 } else if (errno == EINTR) { 339 } else if (errno == EINTR) {
340 continue; 340 continue;
341 } else { 341 } else {
342 break; 342 break;
343 } 343 }
344 } 344 }
345 if (bytes_read + fullness > 0) { 345 if (bytes_read + fullness > 0) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 close(exec_error_fds[kWriteFD]); 495 close(exec_error_fds[kWriteFD]);
496 close(stdout_fds[kWriteFD]); 496 close(stdout_fds[kWriteFD]);
497 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]); 497 OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
498 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]); 498 OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
499 499
500 if (!ChildLaunchedOK(exec_error_fds)) return v8::Undefined(); 500 if (!ChildLaunchedOK(exec_error_fds)) return v8::Undefined();
501 501
502 Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD], 502 Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD],
503 start_time, 503 start_time,
504 read_timeout, 504 read_timeout,
505 &total_timeout); 505 total_timeout);
506 if (accumulator->IsUndefined()) { 506 if (accumulator->IsUndefined()) {
507 kill(pid, SIGINT); // On timeout, kill the subprocess. 507 kill(pid, SIGINT); // On timeout, kill the subprocess.
508 return accumulator; 508 return accumulator;
509 } 509 }
510 510
511 if (!WaitForChild(pid, 511 if (!WaitForChild(pid,
512 child_waiter, 512 child_waiter,
513 start_time, 513 start_time,
514 read_timeout, 514 read_timeout,
515 total_timeout)) { 515 total_timeout)) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) { 659 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) {
660 os_templ->Set(String::New("system"), FunctionTemplate::New(System)); 660 os_templ->Set(String::New("system"), FunctionTemplate::New(System));
661 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory)); 661 os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory));
662 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment)); 662 os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment));
663 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask)); 663 os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask));
664 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory)); 664 os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory));
665 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory)); 665 os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory));
666 } 666 }
667 667
668 } // namespace v8 668 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698