Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Merge branch 'master' into v0.6-merge
Browse files Browse the repository at this point in the history
Conflicts:
	src/node.cc
  • Loading branch information
isaacs committed May 15, 2012
2 parents faa4d9f + c9676c9 commit 643f00d
Show file tree
Hide file tree
Showing 28 changed files with 1,232 additions and 191 deletions.
28 changes: 28 additions & 0 deletions LICENSE
Expand Up @@ -550,3 +550,31 @@ maintained libraries. The externally maintained libraries used by Node are:
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

- src/ngx-queue.h ngx-queue.h is taken from the nginx source tree. nginx's
license follows
"""
Copyright (C) 2002-2012 Igor Sysoev
Copyright (C) 2011,2012 Nginx, Inc.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
"""
24 changes: 14 additions & 10 deletions configure
Expand Up @@ -224,18 +224,22 @@ def host_arch():
def target_arch():
return host_arch()


def gcc_version():
def cc_version():
try:
proc = subprocess.Popen([CC, '-v'], stderr=subprocess.PIPE)
except OSError:
return None
# TODO parse clang output
version = proc.communicate()[1].split('\n')[-2]
match = re.match('gcc version (\d+)\.(\d+)\.(\d+)', version)
if not match: return None
return ['LLVM' in version] + map(int, match.groups())

lines = proc.communicate()[1].split('\n')
version_line = None
for i, line in enumerate(lines):
if 'version' in line:
version_line = line
if not version_line:
return None
version = version_line.split("version")[1].strip().split()[0].split(".")
if not version:
return None
return ['LLVM' in version_line] + version

def configure_node(o):
# TODO add gdb
Expand All @@ -250,10 +254,10 @@ def configure_node(o):
# see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45883
# see http://code.google.com/p/v8/issues/detail?id=884
o['variables']['strict_aliasing'] = b(
'clang' in CC or gcc_version() >= [False, 4, 6, 0])
'clang' in CC or cc_version() >= [False, 4, 6, 0])

# clang has always supported -fvisibility=hidden, right?
if 'clang' not in CC and gcc_version() < [False, 4, 0, 0]:
if 'clang' not in CC and cc_version() < [False, 4, 0, 0]:
o['variables']['visibility'] = ''

# By default, enable DTrace on SunOS systems. Don't allow it on other
Expand Down
181 changes: 118 additions & 63 deletions doc/api/child_process.markdown
Expand Up @@ -52,6 +52,14 @@ in the child. After disconnecting it is no longer possible to send messages.
An alternative way to check if you can send messages is to see if the
`child.connected` property is `true`.

### Event: 'message'

* `message` {Object} a parsed JSON object or primitive value
* `sendHandle` {Handle object} a Socket or Server object

Messages send by `.send(message, [sendHandle])` are obtained using the
`message` event.

### child.stdin

* {Stream object}
Expand Down Expand Up @@ -116,15 +124,120 @@ process may not actually kill it. `kill` really just sends a signal to a proces

See `kill(2)`


### child.send(message, [sendHandle])

* `message` {Object}
* `sendHandle` {Handle object}

Send a message (and, optionally, a handle object) to a child process.
When using `child_process.fork()` you can write to the child using
`child.send(message, [sendHandle])` and messages are received by
a `'message'` event on the child.

For example:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, `'sub.js'` might look like this:

process.on('message', function(m) {
console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

In the child the `process` object will have a `send()` method, and `process`
will emit objects each time it receives a message on its channel.

There is a special case when sending a `{cmd: 'NODE_foo'}` message. All messages
containing a `NODE_` prefix in its `cmd` property will not be emitted in
the `message` event, since they are internal messages used by node core.
Messages containing the prefix are emitted in the `internalMessage` event, you
should by all means avoid using this feature, it is subject to change without notice.

The `sendHandle` option to `child.send()` is for sending a TCP server or
socket object to another process. The child will receive the object as its
second argument to the `message` event.

**send server object**

Here is an example of sending a server:

var child = require('child_process').fork('child.js');

// Open up the server object and send the handle.
var server = require('net').createServer();
server.on('connection', function (socket) {
socket.end('handled by parent');
});
server.listen(1337, function() {
child.send('server', server);
});

And the child would the recive the server object as:

process.on('message', function(m, server) {
if (m === 'server') {
server.on('connection', function (socket) {
socket.end('handled by child');
});
}
});

Note that the server is now shared between the parent and child, this means
that some connections will be handled by the parent and some by the child.

**send socket object**

Here is an example of sending a socket. It will spawn two childs and handle
connections with the remote address `74.125.127.100` as VIP by sending the
socket to a "special" child process. Other sockets will go to a "normal" process.

var normal = require('child_process').fork('child.js', ['normal']);
var special = require('child_process').fork('child.js', ['special']);

// Open up the server and send sockets to child
var server = require('net').createServer();
server.on('connection', function (socket) {

// if this is a VIP
if (socket.remoteAddress === '74.125.127.100') {
special.send('socket', socket);
return;
}
// just the usual dudes
normal.send('socket', socket);
});
server.listen(1337);

The `child.js` could look like this:

See `child_process.fork()` for details.
process.on('message', function(m, socket) {
if (m === 'socket') {
socket.end('You where handled as a ' + process.argv[2] + ' person');
}
});

Note that once a single socket has been sent to a child the parent can no
longer keep track of when the socket is destroyed. To indicate this condition
the `.connections` property becomes `null`.
It is also recomended not to use `.maxConnections` in this condition.

### child.disconnect()

To close the IPC connection between parent and child use the
`child.disconnect()` method. This allows the child to exit gracefully since
there is no IPC channel keeping it alive. When calling this method the
`disconnect` event will be emitted in both parent and child, and the
`connected` flag will be set to `false`. Please note that you can also call
`process.disconnect()` in the child process.

## child_process.spawn(command, [args], [options])

Expand Down Expand Up @@ -333,38 +446,8 @@ leaner than `child_process.exec`. It has the same options.

This is a special case of the `spawn()` functionality for spawning Node
processes. In addition to having all the methods in a normal ChildProcess
instance, the returned object has a communication channel built-in. The
channel is written to with `child.send(message, [sendHandle])` and messages
are received by a `'message'` event on the child.

For example:

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, `'sub.js'` might look like this:

process.on('message', function(m) {
console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

In the child the `process` object will have a `send()` method, and `process`
will emit objects each time it receives a message on its channel.

There is a special case when sending a `{cmd: 'NODE_foo'}` message. All messages
containing a `NODE_` prefix in its `cmd` property will not be emitted in
the `message` event, since they are internal messages used by node core.
Messages containing the prefix are emitted in the `internalMessage` event, you
should by all means avoid using this feature, it may change without warranty.
instance, the returned object has a communication channel built-in. See
`child.send(message, [sendHandle])` for details.

By default the spawned Node process will have the stdout, stderr associated
with the parent's. To change this behavior set the `silent` property in the
Expand All @@ -373,31 +456,3 @@ with the parent's. To change this behavior set the `silent` property in the
These child Nodes are still whole new instances of V8. Assume at least 30ms
startup and 10mb memory for each new Node. That is, you cannot create many
thousands of them.

The `sendHandle` option to `child.send()` is for sending a handle object to
another process. Child will receive the handle as as second argument to the
`message` event. Here is an example of sending a handle:

var server = require('net').createServer();
var child = require('child_process').fork(__dirname + '/child.js');
// Open up the server object and send the handle.
server.listen(1337, function() {
child.send({ server: true }, server._handle);
});

Here is an example of receiving the server handle and sharing it between
processes:

process.on('message', function(m, serverHandle) {
if (serverHandle) {
var server = require('net').createServer();
server.listen(serverHandle);
}
});

To close the IPC connection between parent and child use the
`child.disconnect()` method. This allows the child to exit gracefully since
there is no IPC channel keeping it alive. When calling this method the
`disconnect` event will be emitted in both parent and child, and the
`connected` flag will be set to `false`. Please note that you can also call
`process.disconnect()` in the child process.
4 changes: 4 additions & 0 deletions doc/api/net.markdown
Expand Up @@ -198,10 +198,14 @@ Don't call `server.address()` until the `'listening'` event has been emitted.
Set this property to reject connections when the server's connection count gets
high.

It is not recommended to use this option once a socket has been sent to a child
with `child_process.fork()`.

### server.connections

The number of concurrent connections on the server.

This becomes `null` when sending a socket to a child with `child_process.fork()`.

`net.Server` is an `EventEmitter` with the following events:

Expand Down
56 changes: 9 additions & 47 deletions lib/buffer.js
Expand Up @@ -33,27 +33,17 @@ function binaryWarn() {

exports.INSPECT_MAX_BYTES = 50;

// Make SlowBuffer inherit from Buffer.
// This is an exception to the rule that __proto__ is not allowed in core.
SlowBuffer.prototype.__proto__ = Buffer.prototype;


function toHex(n) {
if (n < 16) return '0' + n.toString(16);
return n.toString(16);
}


SlowBuffer.prototype.inspect = function() {
var out = [],
len = this.length;
for (var i = 0; i < len; i++) {
out[i] = toHex(this[i]);
if (i == exports.INSPECT_MAX_BYTES) {
out[i + 1] = '...';
break;
}
}
return '<SlowBuffer ' + out.join(' ') + '>';
};


SlowBuffer.prototype.hexSlice = function(start, end) {
var len = this.length;

Expand Down Expand Up @@ -302,24 +292,25 @@ function allocPool() {

// Static methods
Buffer.isBuffer = function isBuffer(b) {
return b instanceof Buffer || b instanceof SlowBuffer;
return b instanceof Buffer;
};


// Inspect
Buffer.prototype.inspect = function inspect() {
var out = [],
len = this.length;
len = this.length,
name = this.constructor.name;

for (var i = 0; i < len; i++) {
out[i] = toHex(this.parent[i + this.offset]);
out[i] = toHex(this[i]);
if (i == exports.INSPECT_MAX_BYTES) {
out[i + 1] = '...';
break;
}
}

return '<Buffer ' + out.join(' ') + '>';
return '<' + name + ' ' + out.join(' ') + '>';
};


Expand Down Expand Up @@ -1143,32 +1134,3 @@ Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) {
Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) {
writeDouble(this, value, offset, true, noAssert);
};

SlowBuffer.prototype.readUInt8 = Buffer.prototype.readUInt8;
SlowBuffer.prototype.readUInt16LE = Buffer.prototype.readUInt16LE;
SlowBuffer.prototype.readUInt16BE = Buffer.prototype.readUInt16BE;
SlowBuffer.prototype.readUInt32LE = Buffer.prototype.readUInt32LE;
SlowBuffer.prototype.readUInt32BE = Buffer.prototype.readUInt32BE;
SlowBuffer.prototype.readInt8 = Buffer.prototype.readInt8;
SlowBuffer.prototype.readInt16LE = Buffer.prototype.readInt16LE;
SlowBuffer.prototype.readInt16BE = Buffer.prototype.readInt16BE;
SlowBuffer.prototype.readInt32LE = Buffer.prototype.readInt32LE;
SlowBuffer.prototype.readInt32BE = Buffer.prototype.readInt32BE;
SlowBuffer.prototype.readFloatLE = Buffer.prototype.readFloatLE;
SlowBuffer.prototype.readFloatBE = Buffer.prototype.readFloatBE;
SlowBuffer.prototype.readDoubleLE = Buffer.prototype.readDoubleLE;
SlowBuffer.prototype.readDoubleBE = Buffer.prototype.readDoubleBE;
SlowBuffer.prototype.writeUInt8 = Buffer.prototype.writeUInt8;
SlowBuffer.prototype.writeUInt16LE = Buffer.prototype.writeUInt16LE;
SlowBuffer.prototype.writeUInt16BE = Buffer.prototype.writeUInt16BE;
SlowBuffer.prototype.writeUInt32LE = Buffer.prototype.writeUInt32LE;
SlowBuffer.prototype.writeUInt32BE = Buffer.prototype.writeUInt32BE;
SlowBuffer.prototype.writeInt8 = Buffer.prototype.writeInt8;
SlowBuffer.prototype.writeInt16LE = Buffer.prototype.writeInt16LE;
SlowBuffer.prototype.writeInt16BE = Buffer.prototype.writeInt16BE;
SlowBuffer.prototype.writeInt32LE = Buffer.prototype.writeInt32LE;
SlowBuffer.prototype.writeInt32BE = Buffer.prototype.writeInt32BE;
SlowBuffer.prototype.writeFloatLE = Buffer.prototype.writeFloatLE;
SlowBuffer.prototype.writeFloatBE = Buffer.prototype.writeFloatBE;
SlowBuffer.prototype.writeDoubleLE = Buffer.prototype.writeDoubleLE;
SlowBuffer.prototype.writeDoubleBE = Buffer.prototype.writeDoubleBE;

0 comments on commit 643f00d

Please sign in to comment.