Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of git://github.com/ry/node into ry-rebase

  • Loading branch information...
commit 33505c38743c66e50d7bf711ae4aa4f7662409ca 2 parents ec4ecc8 + 311d7de
@herby herby authored
View
24 ChangeLog
@@ -1,4 +1,26 @@
-2010.04.09, Version 0.1.90
+2010.04.15, Version 0.1.91
+
+ * Add incoming.httpVersion
+
+ * Object.prototype problem with C-Ares binding
+
+ * REPL can be run from multiple different streams. (Matt Ranney)
+
+ * After V8 heap is compact, don't use a timer every 2 seconds.
+
+ * Improve nextTick implementation.
+
+ * Add primative support for Upgrading HTTP connections.
+ (See commit log for docs 760bba5)
+
+ * Add timeout and maxBuffer options to child_process.exec
+
+ * Fix bugs.
+
+ * Upgrade V8 to 2.2.3.1
+
+
+2010.04.09, Version 0.1.90, 07e64d45ffa1856e824c4fa6afd0442ba61d6fd8
* Merge writing of networking system (net2)
- New Buffer object for binary data.
View
2  benchmark/http_simple.js
@@ -4,6 +4,8 @@ var puts = require("sys").puts;
var old = (process.argv[2] == 'old');
+puts('pid ' + process.pid);
+
http = require(old ? "http_old" : 'http');
if (old) puts('old version');
View
16 doc/api.markdown
@@ -907,7 +907,7 @@ Example:
grep.stdin.end();
-### child_process.exec(command, callback)
+### child_process.exec(command, [options, ] callback)
High-level way to execute a command as a child process, buffer the
output, and return it all in a callback.
@@ -928,6 +928,20 @@ The callback gets the arguments `(error, stdout, stderr)`. On success, `error`
will be `null`. On error, `error` will be an instance of `Error` and `err.code`
will be the exit code of the child process.
+There is a second optional argument to specify several options. The default options are
+
+ { encoding: 'utf8'
+ , timeout: 0
+ , maxBuffer: 200*1024
+ , killSignal: 'SIGKILL'
+ }
+
+If `timeout` is greater than 0, then it will kill the child process
+if it runs longer than `timeout` milliseconds. The child process is killed with
+`killSignal` (default: `'SIGKILL'`). `maxBuffer` specifies the largest
+amount of data allowed on stdout or stderr - if this value is exceeded then
+the child process is killed.
+
## File System
View
2  doc/api_header.html
@@ -130,7 +130,7 @@
</head>
<body>
<div id="toc">
- <div id="toctitle">Node v0.1.90</div>
+ <div id="toctitle">Node v0.1.91</div>
<noscript>JavaScript must be enabled in your browser to display the table of contents.</noscript>
</div>
<div id='man'>
View
4 doc/index.html
@@ -95,8 +95,8 @@ <h2 id="download">Download</h2>
<a href="http://github.com/ry/node/tree/master">git repo</a>
</p>
<p>
- 2010.04.09
- <a href="http://nodejs.org/dist/node-v0.1.90.tar.gz">node-v0.1.90.tar.gz</a>
+ 2010.04.15
+ <a href="http://nodejs.org/dist/node-v0.1.91.tar.gz">node-v0.1.91.tar.gz</a>
</p>
<h2 id="build">Build</h2>
View
62 lib/child_process.js
@@ -10,23 +10,73 @@ var spawn = exports.spawn = function (path, args, env) {
return child;
};
+exports.exec = function (command /*, options, callback */) {
+ if (arguments.length < 3) {
+ return exports.execFile("/bin/sh", ["-c", command], arguments[1]);
+ } else {
+ return exports.execFile("/bin/sh", ["-c", command], arguments[1], arguments[2]);
+ }
+};
+
+exports.execFile = function (file, args /*, options, callback */) {
+ var options = { encoding: 'utf8'
+ , timeout: 0
+ , maxBuffer: 200*1024
+ , killSignal: 'SIGKILL'
+ };
+
+ var callback = arguments[arguments.length-1];
+
+ if (typeof arguments[2] == 'object') {
+ var keys = Object.keys(options);
+ for (var i = 0; i < keys.length; i++) {
+ var k = keys[i];
+ if (arguments[2][k] !== undefined) options[k] = arguments[2][k];
+ }
+ }
-exports.exec = function (command, callback) {
- var child = spawn("/bin/sh", ["-c", command]);
+ var child = spawn(file, args);
var stdout = "";
var stderr = "";
+ var killed = false;
+
+ var timeoutId;
+ if (options.timeout > 0) {
+ timeoutId = setTimeout(function () {
+ if (!killed) {
+ child.kill(options.killSignal);
+ killed = true;
+ timeoutId = null;
+ }
+ }, options.timeout);
+ }
+
+ child.stdout.setEncoding(options.encoding);
+ child.stderr.setEncoding(options.encoding);
- child.stdout.setEncoding('utf8');
- child.stdout.addListener("data", function (chunk) { stdout += chunk; });
+ child.stdout.addListener("data", function (chunk) {
+ stdout += chunk;
+ if (!killed && stdout.length > options.maxBuffer) {
+ child.kill(options.killSignal);
+ killed = true;
+ }
+ });
- child.stderr.setEncoding('utf8');
- child.stderr.addListener("data", function (chunk) { stderr += chunk; });
+ child.stderr.addListener("data", function (chunk) {
+ stderr += chunk;
+ if (!killed && stderr.length > options.maxBuffer) {
+ child.kill(options.killSignal);
+ killed = true
+ }
+ });
child.addListener("exit", function (code) {
+ if (timeoutId) clearTimeout(timeoutId);
if (code == 0) {
if (callback) callback(null, stdout, stderr);
} else {
var e = new Error("Command failed: " + stderr);
+ e.killed = killed;
e.code = code;
if (callback) callback(e, stdout, stderr);
}
View
7 lib/net.js
@@ -429,13 +429,10 @@ Stream.prototype._writeOut = function (data, encoding) {
allocNewPool();
}
- if (encoding == 'utf8' || encoding == 'utf-8') {
+ if (!encoding || encoding == 'utf8' || encoding == 'utf-8') {
// default to utf8
bytesWritten = pool.write(data, 'utf8', pool.used);
- // XXX Hacky way to find out the number of characters written.
- // Waiting for a more optimal way: http://codereview.chromium.org/1539013
- var _s = pool.toString('utf8', pool.used, pool.used + bytesWritten);
- charsWritten = _s.length;
+ charsWritten = Buffer._charsWritten;
} else {
bytesWritten = pool.write(data, encoding, pool.used);
charsWritten = bytesWritten;
View
52 src/node.cc
@@ -102,8 +102,21 @@ static ev_tstamp last_active;
static ev_timer gc_timer;
static ev_check gc_check;
static ev_idle gc_idle;
-static bool needs_gc;
-#define GC_INTERVAL 2.0
+#define GC_INTERVAL 1.0
+
+static void gc_timer_start () {
+ if (!ev_is_active(&gc_timer)) {
+ ev_timer_start(EV_DEFAULT_UC_ &gc_timer);
+ ev_unref(EV_DEFAULT_UC);
+ }
+}
+
+static void gc_timer_stop () {
+ if (ev_is_active(&gc_timer)) {
+ ev_ref(EV_DEFAULT_UC);
+ ev_timer_stop(EV_DEFAULT_UC_ &gc_timer);
+ }
+}
static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
@@ -115,15 +128,10 @@ static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
ev_tstamp idle_time = ev_now(EV_DEFAULT_UC) - last_active;
if (idle_time > GC_INTERVAL) {
- if (needs_gc) {
- needs_gc = false;
- if (!V8::IdleNotification()) {
- ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
- }
+ if (!V8::IdleNotification()) {
+ ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
}
- // reset the timer
- gc_timer.repeat = GC_INTERVAL;
- ev_timer_again(EV_DEFAULT_UC_ watcher);
+ gc_timer_stop();
}
}
@@ -136,8 +144,8 @@ static void NotifyIdleness(EV_P_ ev_idle *watcher, int revents) {
if (V8::IdleNotification()) {
ev_idle_stop(EV_A_ watcher);
+ gc_timer_stop();
}
- needs_gc = false;
}
@@ -149,23 +157,18 @@ static void Activity(EV_P_ ev_check *watcher, int revents) {
// Don't count GC watchers as activity.
- pending -= ev_is_pending(&gc_timer);
- pending -= ev_is_pending(&gc_idle);
- pending -= ev_is_pending(&next_tick_watcher);
- //if (ev_is_pending(&gc_check)) pending--; // This probably never happens?
+ if (ev_is_pending(&gc_timer)) pending--;
+ if (ev_is_pending(&gc_idle)) pending--;
+ if (ev_is_pending(&gc_check)) pending--;
+
+ assert(pending >= 0);
//fprintf(stderr, "activity, pending: %d\n", pending);
if (pending) {
last_active = ev_now(EV_DEFAULT_UC);
ev_idle_stop(EV_DEFAULT_UC_ &gc_idle);
-
- if (!needs_gc) {
- gc_timer.repeat = GC_INTERVAL;
- ev_timer_again(EV_DEFAULT_UC_ &gc_timer);
- }
-
- needs_gc = true;
+ gc_timer_start();
}
}
@@ -1594,10 +1597,7 @@ int main(int argc, char *argv[]) {
ev_idle_init(&node::tick_spinner, node::Spin);
- ev_init(&node::gc_timer, node::CheckIdleness);
- node::gc_timer.repeat = GC_INTERVAL;
- ev_timer_again(EV_DEFAULT_UC_ &node::gc_timer);
- ev_unref(EV_DEFAULT_UC);
+ ev_timer_init(&node::gc_timer, node::CheckIdleness, 2*GC_INTERVAL, 2*GC_INTERVAL);
ev_check_init(&node::gc_check, node::Activity);
ev_check_start(EV_DEFAULT_UC_ &node::gc_check);
View
9 src/node_buffer.cc
@@ -38,6 +38,7 @@ using namespace v8;
static Persistent<String> length_symbol;
+static Persistent<String> chars_written_sym;
Persistent<FunctionTemplate> Buffer::constructor_template;
@@ -308,11 +309,16 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
const char *p = buffer->data() + offset;
+ int char_written;
+
int written = s->WriteUtf8((char*)p,
buffer->length_ - offset,
- NULL,
+ &char_written,
String::HINT_MANY_WRITES_EXPECTED);
+ constructor_template->GetFunction()->Set(chars_written_sym,
+ Integer::New(char_written));
+
if (written > 0 && p[written-1] == '\0') written--;
return scope.Close(Integer::New(written));
@@ -463,6 +469,7 @@ void Buffer::Initialize(Handle<Object> target) {
HandleScope scope;
length_symbol = Persistent<String>::New(String::NewSymbol("length"));
+ chars_written_sym = Persistent<String>::New(String::NewSymbol("_charsWritten"));
Local<FunctionTemplate> t = FunctionTemplate::New(Buffer::New);
constructor_template = Persistent<FunctionTemplate>::New(t);
View
0  test/pummel/test-http-big-proxy-responses.js → test/disabled/test-http-big-proxy-responses.js
File renamed without changes
View
0  test/simple/test-http-head-request.js → test/disabled/test-http-head-request.js
File renamed without changes
View
11 test/simple/test-exec.js
@@ -9,6 +9,7 @@ exec("ls /", function (err, stdout, stderr) {
puts("error!: " + err.code);
puts("stdout: " + JSON.stringify(stdout));
puts("stderr: " + JSON.stringify(stderr));
+ assert.equal(false, err.killed);
} else {
success_count++;
p(stdout);
@@ -21,6 +22,7 @@ exec("ls /DOES_NOT_EXIST", function (err, stdout, stderr) {
error_count++;
assert.equal("", stdout);
assert.equal(true, err.code != 0);
+ assert.equal(false, err.killed);
puts("error code: " + err.code);
puts("stdout: " + JSON.stringify(stdout));
puts("stderr: " + JSON.stringify(stderr));
@@ -31,6 +33,15 @@ exec("ls /DOES_NOT_EXIST", function (err, stdout, stderr) {
}
});
+exec("sleep 10", { timeout: 50 }, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.ok(err.killed);
+});
+
+exec('python -c "print 200000*\'C\'"', { maxBuffer: 1000 }, function (err, stdout, stderr) {
+ assert.ok(err);
+ assert.ok(err.killed);
+});
process.addListener("exit", function () {
assert.equal(1, success_count);
View
2  wscript
@@ -7,7 +7,7 @@ from os.path import join, dirname, abspath
from logging import fatal
cwd = os.getcwd()
-VERSION="0.1.90"
+VERSION="0.1.91"
APPNAME="node.js"
import js2c
Please sign in to comment.
Something went wrong with that request. Please try again.