Browse Source

src: all wraps now use actual FunctionTemplate

Instead of simply creating a new v8::Object to contain the connection
information, instantiate a new instance of a FunctionTemplate. This will
allow future improvements for debugging and performance probes.

Additionally, the "provider" argument in the ReqWrap constructor is no
longer optional.

PR-URL: https://github.com/joyent/node/pull/8110
Signed-off-by: Trevor Norris <trev.norris@gmail.com>
Reviewed-by: Fedor Indutny <fedor@indutny.com>
Reviewed-by: Alexis Campailla <alexis@janeasystems.com>
Reviewed-by: Julien Gilli <julien.gilli@joyent.com>
archived-io.js-v0.12
Trevor Norris 10 years ago
committed by Bert Belder
parent
commit
819690fd98
  1. 4
      lib/child_process.js
  2. 5
      lib/dgram.js
  3. 26
      lib/dns.js
  4. 142
      lib/fs.js
  5. 23
      lib/net.js
  6. 41
      src/async-wrap.h
  7. 64
      src/cares_wrap.cc
  8. 117
      src/node_file.cc
  9. 31
      src/pipe_wrap.cc
  10. 4
      src/req_wrap.h
  11. 29
      src/stream_wrap.cc
  12. 23
      src/stream_wrap.h
  13. 35
      src/tcp_wrap.cc
  14. 16
      src/udp_wrap.cc
  15. 5
      test/internet/test-dns.js
  16. 6
      test/simple/test-tcp-wrap-connect.js
  17. 4
      test/simple/test-tcp-wrap-listen.js

4
lib/child_process.js

@ -29,6 +29,7 @@ var assert = require('assert');
var util = require('util'); var util = require('util');
var Process = process.binding('process_wrap').Process; var Process = process.binding('process_wrap').Process;
var WriteWrap = process.binding('stream_wrap').WriteWrap;
var uv = process.binding('uv'); var uv = process.binding('uv');
var spawn_sync; // Lazy-loaded process.binding('spawn_sync') var spawn_sync; // Lazy-loaded process.binding('spawn_sync')
@ -475,7 +476,8 @@ function setupChannel(target, channel) {
return; return;
} }
var req = { oncomplete: nop }; var req = new WriteWrap();
req.oncomplete = nop;
var string = JSON.stringify(message) + '\n'; var string = JSON.stringify(message) + '\n';
var err = channel.writeUtf8String(req, string, handle); var err = channel.writeUtf8String(req, string, handle);

5
lib/dgram.js

@ -27,6 +27,7 @@ var events = require('events');
var constants = require('constants'); var constants = require('constants');
var UDP = process.binding('udp_wrap').UDP; var UDP = process.binding('udp_wrap').UDP;
var SendWrap = process.binding('udp_wrap').SendWrap;
var BIND_STATE_UNBOUND = 0; var BIND_STATE_UNBOUND = 0;
var BIND_STATE_BINDING = 1; var BIND_STATE_BINDING = 1;
@ -319,7 +320,9 @@ Socket.prototype.send = function(buffer,
self.emit('error', ex); self.emit('error', ex);
} }
else if (self._handle) { else if (self._handle) {
var req = { buffer: buffer, length: length }; // Keep reference alive. var req = new SendWrap();
req.buffer = buffer; // Keep reference alive.
req.length = length;
if (callback) { if (callback) {
req.callback = callback; req.callback = callback;
req.oncomplete = afterSend; req.oncomplete = afterSend;

26
lib/dns.js

@ -27,6 +27,9 @@ var util = require('util');
var cares = process.binding('cares_wrap'); var cares = process.binding('cares_wrap');
var uv = process.binding('uv'); var uv = process.binding('uv');
var GetAddrInfoReqWrap = cares.GetAddrInfoReqWrap;
var GetNameInfoReqWrap = cares.GetNameInfoReqWrap;
var isIp = net.isIP; var isIp = net.isIP;
@ -144,12 +147,11 @@ exports.lookup = function lookup(hostname, options, callback) {
return {}; return {};
} }
var req = { var req = new GetAddrInfoReqWrap();
callback: callback, req.callback = callback;
family: family, req.family = family;
hostname: hostname, req.hostname = hostname;
oncomplete: onlookup req.oncomplete = onlookup;
};
var err = cares.getaddrinfo(req, hostname, family, hints); var err = cares.getaddrinfo(req, hostname, family, hints);
if (err) { if (err) {
@ -180,12 +182,12 @@ exports.lookupService = function(host, port, callback) {
callback = makeAsync(callback); callback = makeAsync(callback);
var req = { var req = new GetNameInfoReqWrap();
callback: callback, req.callback = callback;
host: host, req.host = host;
port: port, req.port = port;
oncomplete: onlookupservice req.oncomplete = onlookupservice;
};
var err = cares.getnameinfo(req, host, port); var err = cares.getnameinfo(req, host, port);
if (err) throw errnoException(err, 'getnameinfo', host); if (err) throw errnoException(err, 'getnameinfo', host);

142
lib/fs.js

@ -35,6 +35,7 @@ var constants = process.binding('constants');
var fs = exports; var fs = exports;
var Stream = require('stream').Stream; var Stream = require('stream').Stream;
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var FSReqWrap = binding.FSReqWrap;
var Readable = Stream.Readable; var Readable = Stream.Readable;
var Writable = Stream.Writable; var Writable = Stream.Writable;
@ -184,7 +185,9 @@ fs.Stats.prototype.isSocket = function() {
fs.exists = function(path, callback) { fs.exists = function(path, callback) {
if (!nullCheck(path, cb)) return; if (!nullCheck(path, cb)) return;
binding.stat(pathModule._makeLong(path), cb); var req = new FSReqWrap();
req.oncomplete = cb;
binding.stat(pathModule._makeLong(path), req);
function cb(err, stats) { function cb(err, stats) {
if (callback) callback(err ? false : true); if (callback) callback(err ? false : true);
} }
@ -423,7 +426,9 @@ Object.defineProperty(exports, '_stringToFlags', {
// list to make the arguments clear. // list to make the arguments clear.
fs.close = function(fd, callback) { fs.close = function(fd, callback) {
binding.close(fd, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.close(fd, req);
}; };
fs.closeSync = function(fd) { fs.closeSync = function(fd) {
@ -445,10 +450,14 @@ fs.open = function(path, flags, mode, callback) {
mode = modeNum(mode, 438 /*=0666*/); mode = modeNum(mode, 438 /*=0666*/);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.open(pathModule._makeLong(path), binding.open(pathModule._makeLong(path),
stringToFlags(flags), stringToFlags(flags),
mode, mode,
callback); req);
}; };
fs.openSync = function(path, flags, mode) { fs.openSync = function(path, flags, mode) {
@ -484,7 +493,10 @@ fs.read = function(fd, buffer, offset, length, position, callback) {
callback && callback(err, bytesRead || 0, buffer); callback && callback(err, bytesRead || 0, buffer);
} }
binding.read(fd, buffer, offset, length, position, wrapper); var req = new FSReqWrap();
req.oncomplete = wrapper;
binding.read(fd, buffer, offset, length, position, req);
}; };
fs.readSync = function(fd, buffer, offset, length, position) { fs.readSync = function(fd, buffer, offset, length, position) {
@ -517,6 +529,16 @@ fs.readSync = function(fd, buffer, offset, length, position) {
// OR // OR
// fs.write(fd, string[, position[, encoding]], callback); // fs.write(fd, string[, position[, encoding]], callback);
fs.write = function(fd, buffer, offset, length, position, callback) { fs.write = function(fd, buffer, offset, length, position, callback) {
function strWrapper(err, written) {
// Retain a reference to buffer so that it can't be GC'ed too soon.
callback(err, written || 0, buffer);
}
function bufWrapper(err, written) {
// retain reference to string in case it's external
callback(err, written || 0, buffer);
}
if (util.isBuffer(buffer)) { if (util.isBuffer(buffer)) {
// if no position is passed then assume null // if no position is passed then assume null
if (util.isFunction(position)) { if (util.isFunction(position)) {
@ -524,11 +546,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
position = null; position = null;
} }
callback = maybeCallback(callback); callback = maybeCallback(callback);
var wrapper = function(err, written) { var req = new FSReqWrap();
// Retain a reference to buffer so that it can't be GC'ed too soon. req.oncomplete = strWrapper;
callback(err, written || 0, buffer); return binding.writeBuffer(fd, buffer, offset, length, position, req);
};
return binding.writeBuffer(fd, buffer, offset, length, position, wrapper);
} }
if (util.isString(buffer)) if (util.isString(buffer))
@ -543,11 +563,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
length = 'utf8'; length = 'utf8';
} }
callback = maybeCallback(position); callback = maybeCallback(position);
position = function(err, written) { var req = new FSReqWrap();
// retain reference to string in case it's external req.oncomplete = bufWrapper;
callback(err, written || 0, buffer); return binding.writeString(fd, buffer, offset, length, req);
};
return binding.writeString(fd, buffer, offset, length, position);
}; };
// usage: // usage:
@ -571,9 +589,11 @@ fs.rename = function(oldPath, newPath, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(oldPath, callback)) return; if (!nullCheck(oldPath, callback)) return;
if (!nullCheck(newPath, callback)) return; if (!nullCheck(newPath, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.rename(pathModule._makeLong(oldPath), binding.rename(pathModule._makeLong(oldPath),
pathModule._makeLong(newPath), pathModule._makeLong(newPath),
callback); req);
}; };
fs.renameSync = function(oldPath, newPath) { fs.renameSync = function(oldPath, newPath) {
@ -585,8 +605,9 @@ fs.renameSync = function(oldPath, newPath) {
fs.truncate = function(path, len, callback) { fs.truncate = function(path, len, callback) {
if (util.isNumber(path)) { if (util.isNumber(path)) {
// legacy var req = new FSReqWrap();
return fs.ftruncate(path, len, callback); req.oncomplete = callback;
return fs.ftruncate(path, len, req);
} }
if (util.isFunction(len)) { if (util.isFunction(len)) {
callback = len; callback = len;
@ -594,14 +615,17 @@ fs.truncate = function(path, len, callback) {
} else if (util.isUndefined(len)) { } else if (util.isUndefined(len)) {
len = 0; len = 0;
} }
callback = maybeCallback(callback); callback = maybeCallback(callback);
fs.open(path, 'r+', function(er, fd) { fs.open(path, 'r+', function(er, fd) {
if (er) return callback(er); if (er) return callback(er);
binding.ftruncate(fd, len, function(er) { var req = new FSReqWrap();
req.oncomplete = function ftruncateCb(er) {
fs.close(fd, function(er2) { fs.close(fd, function(er2) {
callback(er || er2); callback(er || er2);
}); });
}); };
binding.ftruncate(fd, len, req);
}); });
}; };
@ -630,7 +654,9 @@ fs.ftruncate = function(fd, len, callback) {
} else if (util.isUndefined(len)) { } else if (util.isUndefined(len)) {
len = 0; len = 0;
} }
binding.ftruncate(fd, len, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.ftruncate(fd, len, req);
}; };
fs.ftruncateSync = function(fd, len) { fs.ftruncateSync = function(fd, len) {
@ -641,9 +667,11 @@ fs.ftruncateSync = function(fd, len) {
}; };
fs.rmdir = function(path, callback) { fs.rmdir = function(path, callback) {
callback = makeCallback(callback); callback = maybeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.rmdir(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.rmdir(pathModule._makeLong(path), req);
}; };
fs.rmdirSync = function(path) { fs.rmdirSync = function(path) {
@ -652,7 +680,9 @@ fs.rmdirSync = function(path) {
}; };
fs.fdatasync = function(fd, callback) { fs.fdatasync = function(fd, callback) {
binding.fdatasync(fd, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fdatasync(fd, req);
}; };
fs.fdatasyncSync = function(fd) { fs.fdatasyncSync = function(fd) {
@ -660,7 +690,9 @@ fs.fdatasyncSync = function(fd) {
}; };
fs.fsync = function(fd, callback) { fs.fsync = function(fd, callback) {
binding.fsync(fd, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fsync(fd, req);
}; };
fs.fsyncSync = function(fd) { fs.fsyncSync = function(fd) {
@ -671,9 +703,11 @@ fs.mkdir = function(path, mode, callback) {
if (util.isFunction(mode)) callback = mode; if (util.isFunction(mode)) callback = mode;
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.mkdir(pathModule._makeLong(path), binding.mkdir(pathModule._makeLong(path),
modeNum(mode, 511 /*=0777*/), modeNum(mode, 511 /*=0777*/),
callback); req);
}; };
fs.mkdirSync = function(path, mode) { fs.mkdirSync = function(path, mode) {
@ -685,7 +719,9 @@ fs.mkdirSync = function(path, mode) {
fs.readdir = function(path, callback) { fs.readdir = function(path, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.readdir(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.readdir(pathModule._makeLong(path), req);
}; };
fs.readdirSync = function(path) { fs.readdirSync = function(path) {
@ -694,19 +730,25 @@ fs.readdirSync = function(path) {
}; };
fs.fstat = function(fd, callback) { fs.fstat = function(fd, callback) {
binding.fstat(fd, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fstat(fd, req);
}; };
fs.lstat = function(path, callback) { fs.lstat = function(path, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.lstat(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.lstat(pathModule._makeLong(path), req);
}; };
fs.stat = function(path, callback) { fs.stat = function(path, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.stat(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.stat(pathModule._makeLong(path), req);
}; };
fs.fstatSync = function(fd) { fs.fstatSync = function(fd) {
@ -726,7 +768,9 @@ fs.statSync = function(path) {
fs.readlink = function(path, callback) { fs.readlink = function(path, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.readlink(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.readlink(pathModule._makeLong(path), req);
}; };
fs.readlinkSync = function(path) { fs.readlinkSync = function(path) {
@ -756,10 +800,13 @@ fs.symlink = function(destination, path, type_, callback) {
if (!nullCheck(destination, callback)) return; if (!nullCheck(destination, callback)) return;
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.symlink(preprocessSymlinkDestination(destination, type, path), binding.symlink(preprocessSymlinkDestination(destination, type, path),
pathModule._makeLong(path), pathModule._makeLong(path),
type, type,
callback); req);
}; };
fs.symlinkSync = function(destination, path, type) { fs.symlinkSync = function(destination, path, type) {
@ -778,9 +825,12 @@ fs.link = function(srcpath, dstpath, callback) {
if (!nullCheck(srcpath, callback)) return; if (!nullCheck(srcpath, callback)) return;
if (!nullCheck(dstpath, callback)) return; if (!nullCheck(dstpath, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.link(pathModule._makeLong(srcpath), binding.link(pathModule._makeLong(srcpath),
pathModule._makeLong(dstpath), pathModule._makeLong(dstpath),
callback); req);
}; };
fs.linkSync = function(srcpath, dstpath) { fs.linkSync = function(srcpath, dstpath) {
@ -793,7 +843,9 @@ fs.linkSync = function(srcpath, dstpath) {
fs.unlink = function(path, callback) { fs.unlink = function(path, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.unlink(pathModule._makeLong(path), callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.unlink(pathModule._makeLong(path), req);
}; };
fs.unlinkSync = function(path) { fs.unlinkSync = function(path) {
@ -802,7 +854,9 @@ fs.unlinkSync = function(path) {
}; };
fs.fchmod = function(fd, mode, callback) { fs.fchmod = function(fd, mode, callback) {
binding.fchmod(fd, modeNum(mode), makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fchmod(fd, modeNum(mode), req);
}; };
fs.fchmodSync = function(fd, mode) { fs.fchmodSync = function(fd, mode) {
@ -852,9 +906,11 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
fs.chmod = function(path, mode, callback) { fs.chmod = function(path, mode, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.chmod(pathModule._makeLong(path), binding.chmod(pathModule._makeLong(path),
modeNum(mode), modeNum(mode),
callback); req);
}; };
fs.chmodSync = function(path, mode) { fs.chmodSync = function(path, mode) {
@ -881,7 +937,9 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
} }
fs.fchown = function(fd, uid, gid, callback) { fs.fchown = function(fd, uid, gid, callback) {
binding.fchown(fd, uid, gid, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.fchown(fd, uid, gid, req);
}; };
fs.fchownSync = function(fd, uid, gid) { fs.fchownSync = function(fd, uid, gid) {
@ -891,7 +949,9 @@ fs.fchownSync = function(fd, uid, gid) {
fs.chown = function(path, uid, gid, callback) { fs.chown = function(path, uid, gid, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
binding.chown(pathModule._makeLong(path), uid, gid, callback); var req = new FSReqWrap();
req.oncomplete = callback;
binding.chown(pathModule._makeLong(path), uid, gid, req);
}; };
fs.chownSync = function(path, uid, gid) { fs.chownSync = function(path, uid, gid) {
@ -917,10 +977,12 @@ fs._toUnixTimestamp = toUnixTimestamp;
fs.utimes = function(path, atime, mtime, callback) { fs.utimes = function(path, atime, mtime, callback) {
callback = makeCallback(callback); callback = makeCallback(callback);
if (!nullCheck(path, callback)) return; if (!nullCheck(path, callback)) return;
var req = new FSReqWrap();
req.oncomplete = callback;
binding.utimes(pathModule._makeLong(path), binding.utimes(pathModule._makeLong(path),
toUnixTimestamp(atime), toUnixTimestamp(atime),
toUnixTimestamp(mtime), toUnixTimestamp(mtime),
callback); req);
}; };
fs.utimesSync = function(path, atime, mtime) { fs.utimesSync = function(path, atime, mtime) {
@ -933,7 +995,9 @@ fs.utimesSync = function(path, atime, mtime) {
fs.futimes = function(fd, atime, mtime, callback) { fs.futimes = function(fd, atime, mtime, callback) {
atime = toUnixTimestamp(atime); atime = toUnixTimestamp(atime);
mtime = toUnixTimestamp(mtime); mtime = toUnixTimestamp(mtime);
binding.futimes(fd, atime, mtime, makeCallback(callback)); var req = new FSReqWrap();
req.oncomplete = makeCallback(callback);
binding.futimes(fd, atime, mtime, req);
}; };
fs.futimesSync = function(fd, atime, mtime) { fs.futimesSync = function(fd, atime, mtime) {

23
lib/net.js

@ -30,6 +30,11 @@ var cares = process.binding('cares_wrap');
var uv = process.binding('uv'); var uv = process.binding('uv');
var Pipe = process.binding('pipe_wrap').Pipe; var Pipe = process.binding('pipe_wrap').Pipe;
var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap;
var PipeConnectWrap = process.binding('pipe_wrap').PipeConnectWrap;
var ShutdownWrap = process.binding('stream_wrap').ShutdownWrap;
var WriteWrap = process.binding('stream_wrap').WriteWrap;
var cluster; var cluster;
var errnoException = util._errnoException; var errnoException = util._errnoException;
@ -239,7 +244,8 @@ function onSocketFinish() {
if (!this._handle || !this._handle.shutdown) if (!this._handle || !this._handle.shutdown)
return this.destroy(); return this.destroy();
var req = { oncomplete: afterShutdown }; var req = new ShutdownWrap();
req.oncomplete = afterShutdown;
var err = this._handle.shutdown(req); var err = this._handle.shutdown(req);
if (err) if (err)
@ -661,7 +667,9 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
return false; return false;
} }
var req = { oncomplete: afterWrite, async: false }; var req = new WriteWrap();
req.oncomplete = afterWrite;
req.async = false;
var err; var err;
if (writev) { if (writev) {
@ -842,14 +850,9 @@ function connect(self, address, port, addressType, localAddress, localPort) {
} }
} }
var req = {
oncomplete: afterConnect,
port: undefined,
address: undefined,
localAddress: undefined,
localPort: undefined
};
if (addressType === 6 || addressType === 4) { if (addressType === 6 || addressType === 4) {
var req = new TCPConnectWrap();
req.oncomplete = afterConnect;
port = port | 0; port = port | 0;
if (port <= 0 || port > 65535) if (port <= 0 || port > 65535)
throw new RangeError('Port should be > 0 and < 65536'); throw new RangeError('Port should be > 0 and < 65536');
@ -862,7 +865,9 @@ function connect(self, address, port, addressType, localAddress, localPort) {
err = self._handle.connect(req, address, port); err = self._handle.connect(req, address, port);
} }
} else { } else {
var req = new PipeConnectWrap();
req.address = address; req.address = address;
req.oncomplete = afterConnect;
err = self._handle.connect(req, address, afterConnect); err = self._handle.connect(req, address, afterConnect);
} }

41
src/async-wrap.h

@ -31,25 +31,28 @@ namespace node {
class AsyncWrap : public BaseObject { class AsyncWrap : public BaseObject {
public: public:
enum ProviderType { enum ProviderType {
PROVIDER_NONE = 1 << 0, PROVIDER_NONE,
PROVIDER_CARES = 1 << 1, PROVIDER_CARES,
PROVIDER_CONNECTWRAP = 1 << 2, PROVIDER_CONNECTWRAP,
PROVIDER_CRYPTO = 1 << 3, PROVIDER_CRYPTO,
PROVIDER_FSEVENTWRAP = 1 << 4, PROVIDER_FSEVENTWRAP,
PROVIDER_GETADDRINFOREQWRAP = 1 << 5, PROVIDER_FSREQWRAP,
PROVIDER_PIPEWRAP = 1 << 6, PROVIDER_GETADDRINFOREQWRAP,
PROVIDER_PROCESSWRAP = 1 << 7, PROVIDER_GETNAMEINFOREQWRAP,
PROVIDER_REQWRAP = 1 << 8, PROVIDER_PIPEWRAP,
PROVIDER_SHUTDOWNWRAP = 1 << 9, PROVIDER_PROCESSWRAP,
PROVIDER_SIGNALWRAP = 1 << 10, PROVIDER_QUERYWRAP,
PROVIDER_STATWATCHER = 1 << 11, PROVIDER_REQWRAP,
PROVIDER_TCPWRAP = 1 << 12, PROVIDER_SHUTDOWNWRAP,
PROVIDER_TIMERWRAP = 1 << 13, PROVIDER_SIGNALWRAP,
PROVIDER_TLSWRAP = 1 << 14, PROVIDER_STATWATCHER,
PROVIDER_TTYWRAP = 1 << 15, PROVIDER_TCPWRAP,
PROVIDER_UDPWRAP = 1 << 16, PROVIDER_TIMERWRAP,
PROVIDER_ZLIB = 1 << 17, PROVIDER_TLSWRAP,
PROVIDER_GETNAMEINFOREQWRAP = 1 << 18 PROVIDER_TTYWRAP,
PROVIDER_UDPWRAP,
PROVIDER_WRITEWRAP,
PROVIDER_ZLIB
}; };
inline AsyncWrap(Environment* env, inline AsyncWrap(Environment* env,

64
src/cares_wrap.cc

@ -54,6 +54,7 @@ using v8::Context;
using v8::EscapableHandleScope; using v8::EscapableHandleScope;
using v8::Function; using v8::Function;
using v8::FunctionCallbackInfo; using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Handle; using v8::Handle;
using v8::HandleScope; using v8::HandleScope;
using v8::Integer; using v8::Integer;
@ -63,8 +64,39 @@ using v8::Object;
using v8::String; using v8::String;
using v8::Value; using v8::Value;
typedef class ReqWrap<uv_getaddrinfo_t> GetAddrInfoReqWrap;
typedef class ReqWrap<uv_getnameinfo_t> GetNameInfoReqWrap; class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> {
public:
GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
};
GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env,
Local<Object> req_wrap_obj)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETADDRINFOREQWRAP) {
Wrap<GetAddrInfoReqWrap>(req_wrap_obj, this);
}
static void NewGetAddrInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> {
public:
GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj);
};
GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env,
Local<Object> req_wrap_obj)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP) {
Wrap<GetNameInfoReqWrap>(req_wrap_obj, this);
}
static void NewGetNameInfoReqWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) { static int cmp_ares_tasks(const ares_task_t* a, const ares_task_t* b) {
@ -228,7 +260,7 @@ static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
class QueryWrap : public AsyncWrap { class QueryWrap : public AsyncWrap {
public: public:
QueryWrap(Environment* env, Local<Object> req_wrap_obj) QueryWrap(Environment* env, Local<Object> req_wrap_obj)
: AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_CARES) { : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP) {
if (env->in_domain()) if (env->in_domain())
req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0)); req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0));
} }
@ -1031,10 +1063,7 @@ static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
abort(); abort();
} }
GetAddrInfoReqWrap* req_wrap = GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
new GetAddrInfoReqWrap(env,
req_wrap_obj,
AsyncWrap::PROVIDER_GETADDRINFOREQWRAP);
struct addrinfo hints; struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
@ -1070,10 +1099,7 @@ static void GetNameInfo(const FunctionCallbackInfo<Value>& args) {
CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 || CHECK(uv_ip4_addr(*ip, port, reinterpret_cast<sockaddr_in*>(&addr)) == 0 ||
uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0); uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);
GetNameInfoReqWrap* req_wrap = GetNameInfoReqWrap* req_wrap = new GetNameInfoReqWrap(env, req_wrap_obj);
new GetNameInfoReqWrap(env,
req_wrap_obj,
AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP);
int err = uv_getnameinfo(env->event_loop(), int err = uv_getnameinfo(env->event_loop(),
&req_wrap->req_, &req_wrap->req_,
@ -1263,6 +1289,22 @@ static void Initialize(Handle<Object> target,
Integer::New(env->isolate(), AI_ADDRCONFIG)); Integer::New(env->isolate(), AI_ADDRCONFIG));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_V4MAPPED"), target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AI_V4MAPPED"),
Integer::New(env->isolate(), AI_V4MAPPED)); Integer::New(env->isolate(), AI_V4MAPPED));
Local<FunctionTemplate> aiw =
FunctionTemplate::New(env->isolate(), NewGetAddrInfoReqWrap);
aiw->InstanceTemplate()->SetInternalFieldCount(1);
aiw->SetClassName(
FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"),
aiw->GetFunction());
Local<FunctionTemplate> niw =
FunctionTemplate::New(env->isolate(), NewGetNameInfoReqWrap);
niw->InstanceTemplate()->SetInternalFieldCount(1);
niw->SetClassName(
FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"),
niw->GetFunction());
} }
} // namespace cares_wrap } // namespace cares_wrap

117
src/node_file.cc

@ -70,11 +70,15 @@ class FSReqWrap: public ReqWrap<uv_fs_t> {
void* operator new(size_t size) { return new char[size]; } void* operator new(size_t size) { return new char[size]; }
void* operator new(size_t size, char* storage) { return storage; } void* operator new(size_t size, char* storage) { return storage; }
FSReqWrap(Environment* env, const char* syscall, char* data = nullptr) FSReqWrap(Environment* env,
: ReqWrap<uv_fs_t>(env, Object::New(env->isolate())), Local<Object> req,
const char* syscall,
char* data = nullptr)
: ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP),
syscall_(syscall), syscall_(syscall),
data_(data), data_(data),
dest_len_(0) { dest_len_(0) {
Wrap<FSReqWrap>(object(), this);
} }
void ReleaseEarly() { void ReleaseEarly() {
@ -97,6 +101,11 @@ class FSReqWrap: public ReqWrap<uv_fs_t> {
}; };
static void NewFSReqWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
#define ASSERT_OFFSET(a) \ #define ASSERT_OFFSET(a) \
if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
return env->ThrowTypeError("Not an integer"); \ return env->ThrowTypeError("Not an integer"); \
@ -253,35 +262,35 @@ struct fs_req_wrap {
}; };
#define ASYNC_DEST_CALL(func, callback, dest_path, ...) \ #define ASYNC_DEST_CALL(func, req, dest_path, ...) \
Environment* env = Environment::GetCurrent(args); \ Environment* env = Environment::GetCurrent(args); \
FSReqWrap* req_wrap; \ FSReqWrap* req_wrap; \
char* dest_str = (dest_path); \ char* dest_str = (dest_path); \
int dest_len = dest_str == nullptr ? 0 : strlen(dest_str); \ int dest_len = dest_str == nullptr ? 0 : strlen(dest_str); \
char* storage = new char[sizeof(*req_wrap) + dest_len]; \ char* storage = new char[sizeof(*req_wrap) + dest_len]; \
req_wrap = new(storage) FSReqWrap(env, #func); \ CHECK(req->IsObject()); \
req_wrap = new(storage) FSReqWrap(env, req.As<Object>(), #func); \
req_wrap->dest_len(dest_len); \ req_wrap->dest_len(dest_len); \
if (dest_str != nullptr) { \ if (dest_str != nullptr) { \
memcpy(const_cast<char*>(req_wrap->dest()), \ memcpy(const_cast<char*>(req_wrap->dest()), \
dest_str, \ dest_str, \
dest_len + 1); \ dest_len + 1); \
} \ } \
int err = uv_fs_ ## func(env->event_loop() , \ int err = uv_fs_ ## func(env->event_loop(), \
&req_wrap->req_, \ &req_wrap->req_, \
__VA_ARGS__, \ __VA_ARGS__, \
After); \ After); \
req_wrap->object()->Set(env->oncomplete_string(), callback); \
req_wrap->Dispatched(); \ req_wrap->Dispatched(); \
if (err < 0) { \ if (err < 0) { \
uv_fs_t* req = &req_wrap->req_; \ uv_fs_t* uv_req = &req_wrap->req_; \
req->result = err; \ uv_req->result = err; \
req->path = nullptr; \ uv_req->path = nullptr; \
After(req); \ After(uv_req); \
} \ } \
args.GetReturnValue().Set(req_wrap->persistent()); args.GetReturnValue().Set(req_wrap->persistent());
#define ASYNC_CALL(func, callback, ...) \ #define ASYNC_CALL(func, req, ...) \
ASYNC_DEST_CALL(func, callback, nullptr, __VA_ARGS__) \ ASYNC_DEST_CALL(func, req, nullptr, __VA_ARGS__) \
#define SYNC_DEST_CALL(func, path, dest, ...) \ #define SYNC_DEST_CALL(func, path, dest, ...) \
fs_req_wrap req_wrap; \ fs_req_wrap req_wrap; \
@ -317,7 +326,7 @@ static void Close(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(close, args[1], fd) ASYNC_CALL(close, args[1], fd)
} else { } else {
SYNC_CALL(close, 0, fd) SYNC_CALL(close, 0, fd)
@ -432,7 +441,7 @@ static void Stat(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(stat, args[1], *path) ASYNC_CALL(stat, args[1], *path)
} else { } else {
SYNC_CALL(stat, *path, *path) SYNC_CALL(stat, *path, *path)
@ -451,7 +460,7 @@ static void LStat(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(lstat, args[1], *path) ASYNC_CALL(lstat, args[1], *path)
} else { } else {
SYNC_CALL(lstat, *path, *path) SYNC_CALL(lstat, *path, *path)
@ -469,7 +478,7 @@ static void FStat(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(fstat, args[1], fd) ASYNC_CALL(fstat, args[1], fd)
} else { } else {
SYNC_CALL(fstat, 0, fd) SYNC_CALL(fstat, 0, fd)
@ -506,7 +515,7 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) {
} }
} }
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_DEST_CALL(symlink, args[3], *path, *dest, *path, flags) ASYNC_DEST_CALL(symlink, args[3], *path, *dest, *path, flags)
} else { } else {
SYNC_DEST_CALL(symlink, *dest, *path, *dest, *path, flags) SYNC_DEST_CALL(symlink, *dest, *path, *dest, *path, flags)
@ -529,7 +538,7 @@ static void Link(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value orig_path(args[0]); node::Utf8Value orig_path(args[0]);
node::Utf8Value new_path(args[1]); node::Utf8Value new_path(args[1]);
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_DEST_CALL(link, args[2], *new_path, *orig_path, *new_path) ASYNC_DEST_CALL(link, args[2], *new_path, *orig_path, *new_path)
} else { } else {
SYNC_DEST_CALL(link, *orig_path, *new_path, *orig_path, *new_path) SYNC_DEST_CALL(link, *orig_path, *new_path, *orig_path, *new_path)
@ -546,7 +555,7 @@ static void ReadLink(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(readlink, args[1], *path) ASYNC_CALL(readlink, args[1], *path)
} else { } else {
SYNC_CALL(readlink, *path, *path) SYNC_CALL(readlink, *path, *path)
@ -572,7 +581,7 @@ static void Rename(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value old_path(args[0]); node::Utf8Value old_path(args[0]);
node::Utf8Value new_path(args[1]); node::Utf8Value new_path(args[1]);
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_DEST_CALL(rename, args[2], *new_path, *old_path, *new_path) ASYNC_DEST_CALL(rename, args[2], *new_path, *old_path, *new_path)
} else { } else {
SYNC_DEST_CALL(rename, *old_path, *new_path, *old_path, *new_path) SYNC_DEST_CALL(rename, *old_path, *new_path, *old_path, *new_path)
@ -591,7 +600,7 @@ static void FTruncate(const FunctionCallbackInfo<Value>& args) {
ASSERT_TRUNCATE_LENGTH(args[1]); ASSERT_TRUNCATE_LENGTH(args[1]);
int64_t len = GET_TRUNCATE_LENGTH(args[1]); int64_t len = GET_TRUNCATE_LENGTH(args[1]);
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_CALL(ftruncate, args[2], fd, len) ASYNC_CALL(ftruncate, args[2], fd, len)
} else { } else {
SYNC_CALL(ftruncate, 0, fd, len) SYNC_CALL(ftruncate, 0, fd, len)
@ -607,7 +616,7 @@ static void Fdatasync(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(fdatasync, args[1], fd) ASYNC_CALL(fdatasync, args[1], fd)
} else { } else {
SYNC_CALL(fdatasync, 0, fd) SYNC_CALL(fdatasync, 0, fd)
@ -623,7 +632,7 @@ static void Fsync(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(fsync, args[1], fd) ASYNC_CALL(fsync, args[1], fd)
} else { } else {
SYNC_CALL(fsync, 0, fd) SYNC_CALL(fsync, 0, fd)
@ -640,7 +649,7 @@ static void Unlink(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(unlink, args[1], *path) ASYNC_CALL(unlink, args[1], *path)
} else { } else {
SYNC_CALL(unlink, *path, *path) SYNC_CALL(unlink, *path, *path)
@ -657,7 +666,7 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(rmdir, args[1], *path) ASYNC_CALL(rmdir, args[1], *path)
} else { } else {
SYNC_CALL(rmdir, *path, *path) SYNC_CALL(rmdir, *path, *path)
@ -674,7 +683,7 @@ static void MKDir(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
int mode = static_cast<int>(args[1]->Int32Value()); int mode = static_cast<int>(args[1]->Int32Value());
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_CALL(mkdir, args[2], *path, mode) ASYNC_CALL(mkdir, args[2], *path, mode)
} else { } else {
SYNC_CALL(mkdir, *path, *path, mode) SYNC_CALL(mkdir, *path, *path, mode)
@ -691,7 +700,7 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
if (args[1]->IsFunction()) { if (args[1]->IsObject()) {
ASYNC_CALL(scandir, args[1], *path, 0 /*flags*/) ASYNC_CALL(scandir, args[1], *path, 0 /*flags*/)
} else { } else {
SYNC_CALL(scandir, *path, *path, 0 /*flags*/) SYNC_CALL(scandir, *path, *path, 0 /*flags*/)
@ -739,7 +748,7 @@ static void Open(const FunctionCallbackInfo<Value>& args) {
int flags = args[1]->Int32Value(); int flags = args[1]->Int32Value();
int mode = static_cast<int>(args[2]->Int32Value()); int mode = static_cast<int>(args[2]->Int32Value());
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_CALL(open, args[3], *path, flags, mode) ASYNC_CALL(open, args[3], *path, flags, mode)
} else { } else {
SYNC_CALL(open, *path, *path, flags, mode) SYNC_CALL(open, *path, *path, flags, mode)
@ -770,7 +779,7 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
size_t off = args[2]->Uint32Value(); size_t off = args[2]->Uint32Value();
size_t len = args[3]->Uint32Value(); size_t len = args[3]->Uint32Value();
int64_t pos = GET_OFFSET(args[4]); int64_t pos = GET_OFFSET(args[4]);
Local<Value> cb = args[5]; Local<Value> req = args[5];
if (off > buffer_length) if (off > buffer_length)
return env->ThrowRangeError("offset out of bounds"); return env->ThrowRangeError("offset out of bounds");
@ -785,8 +794,8 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len); uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len);
if (cb->IsFunction()) { if (req->IsObject()) {
ASYNC_CALL(write, cb, fd, &uvbuf, 1, pos) ASYNC_CALL(write, req, fd, &uvbuf, 1, pos)
return; return;
} }
@ -809,7 +818,7 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
if (!args[0]->IsInt32()) if (!args[0]->IsInt32())
return env->ThrowTypeError("First argument must be file descriptor"); return env->ThrowTypeError("First argument must be file descriptor");
Local<Value> cb; Local<Value> req;
Local<Value> string = args[1]; Local<Value> string = args[1];
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
char* buf = nullptr; char* buf = nullptr;
@ -831,18 +840,19 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
must_free = true; must_free = true;
} }
pos = GET_OFFSET(args[2]); pos = GET_OFFSET(args[2]);
cb = args[4]; req = args[4];
uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len); uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len);
if (!cb->IsFunction()) { if (!req->IsObject()) {
SYNC_CALL(write, nullptr, fd, &uvbuf, 1, pos) SYNC_CALL(write, nullptr, fd, &uvbuf, 1, pos)
if (must_free) if (must_free)
delete[] buf; delete[] buf;
return args.GetReturnValue().Set(SYNC_RESULT); return args.GetReturnValue().Set(SYNC_RESULT);
} }
FSReqWrap* req_wrap = new FSReqWrap(env, "write", must_free ? buf : nullptr); FSReqWrap* req_wrap =
new FSReqWrap(env, req.As<Object>(), "write", must_free ? buf : nullptr);
int err = uv_fs_write(env->event_loop(), int err = uv_fs_write(env->event_loop(),
&req_wrap->req_, &req_wrap->req_,
fd, fd,
@ -850,13 +860,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
1, 1,
pos, pos,
After); After);
req_wrap->object()->Set(env->oncomplete_string(), cb);
req_wrap->Dispatched(); req_wrap->Dispatched();
if (err < 0) { if (err < 0) {
uv_fs_t* req = &req_wrap->req_; uv_fs_t* uv_req = &req_wrap->req_;
req->result = err; uv_req->result = err;
req->path = nullptr; uv_req->path = nullptr;
After(req); After(uv_req);
} }
return args.GetReturnValue().Set(req_wrap->persistent()); return args.GetReturnValue().Set(req_wrap->persistent());
@ -884,7 +893,7 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
Local<Value> cb; Local<Value> req;
size_t len; size_t len;
int64_t pos; int64_t pos;
@ -914,10 +923,10 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len); uv_buf_t uvbuf = uv_buf_init(const_cast<char*>(buf), len);
cb = args[5]; req = args[5];
if (cb->IsFunction()) { if (req->IsObject()) {
ASYNC_CALL(read, cb, fd, &uvbuf, 1, pos); ASYNC_CALL(read, req, fd, &uvbuf, 1, pos);
} else { } else {
SYNC_CALL(read, 0, fd, &uvbuf, 1, pos) SYNC_CALL(read, 0, fd, &uvbuf, 1, pos)
args.GetReturnValue().Set(SYNC_RESULT); args.GetReturnValue().Set(SYNC_RESULT);
@ -937,7 +946,7 @@ static void Chmod(const FunctionCallbackInfo<Value>& args) {
node::Utf8Value path(args[0]); node::Utf8Value path(args[0]);
int mode = static_cast<int>(args[1]->Int32Value()); int mode = static_cast<int>(args[1]->Int32Value());
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_CALL(chmod, args[2], *path, mode); ASYNC_CALL(chmod, args[2], *path, mode);
} else { } else {
SYNC_CALL(chmod, *path, *path, mode); SYNC_CALL(chmod, *path, *path, mode);
@ -957,7 +966,7 @@ static void FChmod(const FunctionCallbackInfo<Value>& args) {
int fd = args[0]->Int32Value(); int fd = args[0]->Int32Value();
int mode = static_cast<int>(args[1]->Int32Value()); int mode = static_cast<int>(args[1]->Int32Value());
if (args[2]->IsFunction()) { if (args[2]->IsObject()) {
ASYNC_CALL(fchmod, args[2], fd, mode); ASYNC_CALL(fchmod, args[2], fd, mode);
} else { } else {
SYNC_CALL(fchmod, 0, fd, mode); SYNC_CALL(fchmod, 0, fd, mode);
@ -989,7 +998,7 @@ static void Chown(const FunctionCallbackInfo<Value>& args) {
uv_uid_t uid = static_cast<uv_uid_t>(args[1]->Uint32Value()); uv_uid_t uid = static_cast<uv_uid_t>(args[1]->Uint32Value());
uv_gid_t gid = static_cast<uv_gid_t>(args[2]->Uint32Value()); uv_gid_t gid = static_cast<uv_gid_t>(args[2]->Uint32Value());
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_CALL(chown, args[3], *path, uid, gid); ASYNC_CALL(chown, args[3], *path, uid, gid);
} else { } else {
SYNC_CALL(chown, *path, *path, uid, gid); SYNC_CALL(chown, *path, *path, uid, gid);
@ -1021,7 +1030,7 @@ static void FChown(const FunctionCallbackInfo<Value>& args) {
uv_uid_t uid = static_cast<uv_uid_t>(args[1]->Uint32Value()); uv_uid_t uid = static_cast<uv_uid_t>(args[1]->Uint32Value());
uv_gid_t gid = static_cast<uv_gid_t>(args[2]->Uint32Value()); uv_gid_t gid = static_cast<uv_gid_t>(args[2]->Uint32Value());
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_CALL(fchown, args[3], fd, uid, gid); ASYNC_CALL(fchown, args[3], fd, uid, gid);
} else { } else {
SYNC_CALL(fchown, 0, fd, uid, gid); SYNC_CALL(fchown, 0, fd, uid, gid);
@ -1050,7 +1059,7 @@ static void UTimes(const FunctionCallbackInfo<Value>& args) {
const double atime = static_cast<double>(args[1]->NumberValue()); const double atime = static_cast<double>(args[1]->NumberValue());
const double mtime = static_cast<double>(args[2]->NumberValue()); const double mtime = static_cast<double>(args[2]->NumberValue());
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_CALL(utime, args[3], *path, atime, mtime); ASYNC_CALL(utime, args[3], *path, atime, mtime);
} else { } else {
SYNC_CALL(utime, *path, *path, atime, mtime); SYNC_CALL(utime, *path, *path, atime, mtime);
@ -1078,7 +1087,7 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) {
const double atime = static_cast<double>(args[1]->NumberValue()); const double atime = static_cast<double>(args[1]->NumberValue());
const double mtime = static_cast<double>(args[2]->NumberValue()); const double mtime = static_cast<double>(args[2]->NumberValue());
if (args[3]->IsFunction()) { if (args[3]->IsObject()) {
ASYNC_CALL(futime, args[3], fd, atime, mtime); ASYNC_CALL(futime, args[3], fd, atime, mtime);
} else { } else {
SYNC_CALL(futime, 0, fd, atime, mtime); SYNC_CALL(futime, 0, fd, atime, mtime);
@ -1135,6 +1144,14 @@ void InitFs(Handle<Object> target,
env->SetMethod(target, "futimes", FUTimes); env->SetMethod(target, "futimes", FUTimes);
StatWatcher::Initialize(env, target); StatWatcher::Initialize(env, target);
// Create FunctionTemplate for FSReqWrap
Local<FunctionTemplate> fst =
FunctionTemplate::New(env->isolate(), NewFSReqWrap);
fst->InstanceTemplate()->SetInternalFieldCount(1);
fst->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap"),
fst->GetFunction());
} }
} // end namespace node } // end namespace node

31
src/pipe_wrap.cc

@ -50,8 +50,23 @@ using v8::String;
using v8::Undefined; using v8::Undefined;
using v8::Value; using v8::Value;
// TODO(bnoordhuis) share with TCPWrap? // TODO(bnoordhuis) share with TCPWrap?
typedef class ReqWrap<uv_connect_t> ConnectWrap; class PipeConnectWrap : public ReqWrap<uv_connect_t> {
public:
PipeConnectWrap(Environment* env, Local<Object> req_wrap_obj);
};
PipeConnectWrap::PipeConnectWrap(Environment* env, Local<Object> req_wrap_obj)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPEWRAP) {
Wrap<PipeConnectWrap>(req_wrap_obj, this);
}
static void NewPipeConnectWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
uv_pipe_t* PipeWrap::UVHandle() { uv_pipe_t* PipeWrap::UVHandle() {
@ -115,6 +130,14 @@ void PipeWrap::Initialize(Handle<Object> target,
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction()); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction());
env->set_pipe_constructor_template(t); env->set_pipe_constructor_template(t);
// Create FunctionTemplate for PipeConnectWrap.
Local<FunctionTemplate> cwt =
FunctionTemplate::New(env->isolate(), NewPipeConnectWrap);
cwt->InstanceTemplate()->SetInternalFieldCount(1);
cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"),
cwt->GetFunction());
} }
@ -206,7 +229,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
// TODO(bnoordhuis) Maybe share this with TCPWrap? // TODO(bnoordhuis) Maybe share this with TCPWrap?
void PipeWrap::AfterConnect(uv_connect_t* req, int status) { void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
ConnectWrap* req_wrap = static_cast<ConnectWrap*>(req->data); PipeConnectWrap* req_wrap = static_cast<PipeConnectWrap*>(req->data);
PipeWrap* wrap = static_cast<PipeWrap*>(req->handle->data); PipeWrap* wrap = static_cast<PipeWrap*>(req->handle->data);
CHECK_EQ(req_wrap->env(), wrap->env()); CHECK_EQ(req_wrap->env(), wrap->env());
Environment* env = wrap->env(); Environment* env = wrap->env();
@ -267,9 +290,7 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
Local<Object> req_wrap_obj = args[0].As<Object>(); Local<Object> req_wrap_obj = args[0].As<Object>();
node::Utf8Value name(args[1]); node::Utf8Value name(args[1]);
ConnectWrap* req_wrap = new ConnectWrap(env, PipeConnectWrap* req_wrap = new PipeConnectWrap(env, req_wrap_obj);
req_wrap_obj,
AsyncWrap::PROVIDER_CONNECTWRAP);
uv_pipe_connect(&req_wrap->req_, uv_pipe_connect(&req_wrap->req_,
&wrap->handle_, &wrap->handle_,
*name, *name,

4
src/req_wrap.h

@ -36,8 +36,8 @@ class ReqWrap : public AsyncWrap {
public: public:
ReqWrap(Environment* env, ReqWrap(Environment* env,
v8::Handle<v8::Object> object, v8::Handle<v8::Object> object,
AsyncWrap::ProviderType provider = AsyncWrap::PROVIDER_REQWRAP) AsyncWrap::ProviderType provider)
: AsyncWrap(env, object, AsyncWrap::PROVIDER_REQWRAP) { : AsyncWrap(env, object, provider) {
if (env->in_domain()) if (env->in_domain())
object->Set(env->domain_string(), env->domain_array()->Get(0)); object->Set(env->domain_string(), env->domain_array()->Get(0));

29
src/stream_wrap.cc

@ -43,6 +43,7 @@ using v8::Array;
using v8::Context; using v8::Context;
using v8::EscapableHandleScope; using v8::EscapableHandleScope;
using v8::FunctionCallbackInfo; using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Handle; using v8::Handle;
using v8::HandleScope; using v8::HandleScope;
using v8::Integer; using v8::Integer;
@ -56,6 +57,27 @@ using v8::Undefined;
using v8::Value; using v8::Value;
void StreamWrap::Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> sw =
FunctionTemplate::New(env->isolate(), ShutdownWrap::NewShutdownWrap);
sw->InstanceTemplate()->SetInternalFieldCount(1);
sw->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"),
sw->GetFunction());
Local<FunctionTemplate> ww =
FunctionTemplate::New(env->isolate(), WriteWrap::NewWriteWrap);
ww->InstanceTemplate()->SetInternalFieldCount(1);
ww->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"),
ww->GetFunction());
}
StreamWrap::StreamWrap(Environment* env, StreamWrap::StreamWrap(Environment* env,
Local<Object> object, Local<Object> object,
uv_stream_t* stream, uv_stream_t* stream,
@ -88,6 +110,7 @@ void StreamWrap::UpdateWriteQueueSize() {
object()->Set(env()->write_queue_size_string(), write_queue_size); object()->Set(env()->write_queue_size_string(), write_queue_size);
} }
void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) { void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder()); StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
if (!IsAlive(wrap)) if (!IsAlive(wrap))
@ -564,9 +587,7 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsObject()); CHECK(args[0]->IsObject());
Local<Object> req_wrap_obj = args[0].As<Object>(); Local<Object> req_wrap_obj = args[0].As<Object>();
ShutdownWrap* req_wrap = new ShutdownWrap(env, ShutdownWrap* req_wrap = new ShutdownWrap(env, req_wrap_obj);
req_wrap_obj,
AsyncWrap::PROVIDER_SHUTDOWNWRAP);
int err = wrap->callbacks()->DoShutdown(req_wrap, AfterShutdown); int err = wrap->callbacks()->DoShutdown(req_wrap, AfterShutdown);
req_wrap->Dispatched(); req_wrap->Dispatched();
if (err) if (err)
@ -752,3 +773,5 @@ int StreamWrapCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {
} }
} // namespace node } // namespace node
NODE_MODULE_CONTEXT_AWARE_BUILTIN(stream_wrap, node::StreamWrap::Initialize)

23
src/stream_wrap.h

@ -33,15 +33,26 @@ namespace node {
// Forward declaration // Forward declaration
class StreamWrap; class StreamWrap;
typedef class ReqWrap<uv_shutdown_t> ShutdownWrap; class ShutdownWrap : public ReqWrap<uv_shutdown_t> {
public:
ShutdownWrap(Environment* env, v8::Local<v8::Object> req_wrap_obj)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_SHUTDOWNWRAP) {
Wrap<ShutdownWrap>(req_wrap_obj, this);
}
static void NewShutdownWrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(args.IsConstructCall());
}
};
class WriteWrap: public ReqWrap<uv_write_t> { class WriteWrap: public ReqWrap<uv_write_t> {
public: public:
// TODO(trevnorris): WrapWrap inherits from ReqWrap, which I've globbed // TODO(trevnorris): WrapWrap inherits from ReqWrap, which I've globbed
// into the same provider. How should these be broken apart? // into the same provider. How should these be broken apart?
WriteWrap(Environment* env, v8::Local<v8::Object> obj, StreamWrap* wrap) WriteWrap(Environment* env, v8::Local<v8::Object> obj, StreamWrap* wrap)
: ReqWrap<uv_write_t>(env, obj), : ReqWrap(env, obj, AsyncWrap::PROVIDER_WRITEWRAP),
wrap_(wrap) { wrap_(wrap) {
Wrap<WriteWrap>(obj, this);
} }
void* operator new(size_t size, char* storage) { return storage; } void* operator new(size_t size, char* storage) { return storage; }
@ -54,6 +65,10 @@ class WriteWrap: public ReqWrap<uv_write_t> {
return wrap_; return wrap_;
} }
static void NewWriteWrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(args.IsConstructCall());
}
private: private:
// People should not be using the non-placement new and delete operator on a // People should not be using the non-placement new and delete operator on a
// WriteWrap. Ensure this never happens. // WriteWrap. Ensure this never happens.
@ -105,6 +120,10 @@ class StreamWrapCallbacks {
class StreamWrap : public HandleWrap { class StreamWrap : public HandleWrap {
public: public:
static void Initialize(v8::Handle<v8::Object> target,
v8::Handle<v8::Value> unused,
v8::Handle<v8::Context> context);
void OverrideCallbacks(StreamWrapCallbacks* callbacks, bool gc) { void OverrideCallbacks(StreamWrapCallbacks* callbacks, bool gc) {
StreamWrapCallbacks* old = callbacks_; StreamWrapCallbacks* old = callbacks_;
callbacks_ = callbacks; callbacks_ = callbacks;

35
src/tcp_wrap.cc

@ -52,7 +52,22 @@ using v8::String;
using v8::Undefined; using v8::Undefined;
using v8::Value; using v8::Value;
typedef class ReqWrap<uv_connect_t> ConnectWrap;
class TCPConnectWrap : public ReqWrap<uv_connect_t> {
public:
TCPConnectWrap(Environment* env, Local<Object> req_wrap_obj);
};
TCPConnectWrap::TCPConnectWrap(Environment* env, Local<Object> req_wrap_obj)
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPWRAP) {
Wrap<TCPConnectWrap>(req_wrap_obj, this);
}
static void NewTCPConnectWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
Local<Object> TCPWrap::Instantiate(Environment* env) { Local<Object> TCPWrap::Instantiate(Environment* env) {
@ -129,6 +144,14 @@ void TCPWrap::Initialize(Handle<Object> target,
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"), t->GetFunction()); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"), t->GetFunction());
env->set_tcp_constructor_template(t); env->set_tcp_constructor_template(t);
// Create FunctionTemplate for TCPConnectWrap.
Local<FunctionTemplate> cwt =
FunctionTemplate::New(env->isolate(), NewTCPConnectWrap);
cwt->InstanceTemplate()->SetInternalFieldCount(1);
cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"),
cwt->GetFunction());
} }
@ -319,7 +342,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
void TCPWrap::AfterConnect(uv_connect_t* req, int status) { void TCPWrap::AfterConnect(uv_connect_t* req, int status) {
ConnectWrap* req_wrap = static_cast<ConnectWrap*>(req->data); TCPConnectWrap* req_wrap = static_cast<TCPConnectWrap*>(req->data);
TCPWrap* wrap = static_cast<TCPWrap*>(req->handle->data); TCPWrap* wrap = static_cast<TCPWrap*>(req->handle->data);
CHECK_EQ(req_wrap->env(), wrap->env()); CHECK_EQ(req_wrap->env(), wrap->env());
Environment* env = wrap->env(); Environment* env = wrap->env();
@ -363,9 +386,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
int err = uv_ip4_addr(*ip_address, port, &addr); int err = uv_ip4_addr(*ip_address, port, &addr);
if (err == 0) { if (err == 0) {
ConnectWrap* req_wrap = new ConnectWrap(env, TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj);
req_wrap_obj,
AsyncWrap::PROVIDER_CONNECTWRAP);
err = uv_tcp_connect(&req_wrap->req_, err = uv_tcp_connect(&req_wrap->req_,
&wrap->handle_, &wrap->handle_,
reinterpret_cast<const sockaddr*>(&addr), reinterpret_cast<const sockaddr*>(&addr),
@ -396,9 +417,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
int err = uv_ip6_addr(*ip_address, port, &addr); int err = uv_ip6_addr(*ip_address, port, &addr);
if (err == 0) { if (err == 0) {
ConnectWrap* req_wrap = new ConnectWrap(env, TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj);
req_wrap_obj,
AsyncWrap::PROVIDER_CONNECTWRAP);
err = uv_tcp_connect(&req_wrap->req_, err = uv_tcp_connect(&req_wrap->req_,
&wrap->handle_, &wrap->handle_,
reinterpret_cast<const sockaddr*>(&addr), reinterpret_cast<const sockaddr*>(&addr),

16
src/udp_wrap.cc

@ -62,8 +62,9 @@ class SendWrap : public ReqWrap<uv_udp_send_t> {
SendWrap::SendWrap(Environment* env, SendWrap::SendWrap(Environment* env,
Local<Object> req_wrap_obj, Local<Object> req_wrap_obj,
bool have_callback) bool have_callback)
: ReqWrap<uv_udp_send_t>(env, req_wrap_obj), : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_UDPWRAP),
have_callback_(have_callback) { have_callback_(have_callback) {
Wrap<SendWrap>(req_wrap_obj, this);
} }
@ -72,6 +73,11 @@ inline bool SendWrap::have_callback() const {
} }
static void NewSendWrap(const FunctionCallbackInfo<Value>& args) {
CHECK(args.IsConstructCall());
}
UDPWrap::UDPWrap(Environment* env, Handle<Object> object) UDPWrap::UDPWrap(Environment* env, Handle<Object> object)
: HandleWrap(env, : HandleWrap(env,
object, object,
@ -120,6 +126,14 @@ void UDPWrap::Initialize(Handle<Object> target,
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction()); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction());
env->set_udp_constructor_function(t->GetFunction()); env->set_udp_constructor_function(t->GetFunction());
// Create FunctionTemplate for SendWrap
Local<FunctionTemplate> swt =
FunctionTemplate::New(env->isolate(), NewSendWrap);
swt->InstanceTemplate()->SetInternalFieldCount(1);
swt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap"));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap"),
swt->GetFunction());
} }

5
test/internet/test-dns.js

@ -632,8 +632,9 @@ var getaddrinfoCallbackCalled = false;
console.log('looking up nodejs.org...'); console.log('looking up nodejs.org...');
var req = {}; var cares = process.binding('cares_wrap');
var err = process.binding('cares_wrap').getaddrinfo(req, 'nodejs.org', 4); var req = new cares.GetAddrInfoReqWrap();
var err = cares.getaddrinfo(req, 'nodejs.org', 4);
req.oncomplete = function(err, domains) { req.oncomplete = function(err, domains) {
assert.strictEqual(err, 0); assert.strictEqual(err, 0);

6
test/simple/test-tcp-wrap-connect.js

@ -22,11 +22,13 @@
var common = require('../common'); var common = require('../common');
var assert = require('assert'); var assert = require('assert');
var TCP = process.binding('tcp_wrap').TCP; var TCP = process.binding('tcp_wrap').TCP;
var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap;
var ShutdownWrap = process.binding('stream_wrap').ShutdownWrap;
function makeConnection() { function makeConnection() {
var client = new TCP(); var client = new TCP();
var req = {}; var req = new TCPConnectWrap();
var err = client.connect(req, '127.0.0.1', common.PORT); var err = client.connect(req, '127.0.0.1', common.PORT);
assert.equal(err, 0); assert.equal(err, 0);
@ -36,7 +38,7 @@ function makeConnection() {
assert.equal(req, req_); assert.equal(req, req_);
console.log('connected'); console.log('connected');
var shutdownReq = {}; var shutdownReq = new ShutdownWrap();
var err = client.shutdown(shutdownReq); var err = client.shutdown(shutdownReq);
assert.equal(err, 0); assert.equal(err, 0);

4
test/simple/test-tcp-wrap-listen.js

@ -23,6 +23,7 @@ var common = require('../common');
var assert = require('assert'); var assert = require('assert');
var TCP = process.binding('tcp_wrap').TCP; var TCP = process.binding('tcp_wrap').TCP;
var WriteWrap = process.binding('stream_wrap').WriteWrap;
var server = new TCP(); var server = new TCP();
@ -55,7 +56,8 @@ server.onconnection = function(err, client) {
assert.equal(0, client.writeQueueSize); assert.equal(0, client.writeQueueSize);
var req = { async: false }; var req = new WriteWrap();
req.async = false;
var err = client.writeBuffer(req, buffer); var err = client.writeBuffer(req, buffer);
assert.equal(err, 0); assert.equal(err, 0);
client.pendingWrites.push(req); client.pendingWrites.push(req);

Loading…
Cancel
Save