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>
This commit is contained in:
parent
8f41db6104
commit
819690fd98
@ -29,6 +29,7 @@ var assert = require('assert');
|
||||
var util = require('util');
|
||||
|
||||
var Process = process.binding('process_wrap').Process;
|
||||
var WriteWrap = process.binding('stream_wrap').WriteWrap;
|
||||
var uv = process.binding('uv');
|
||||
|
||||
var spawn_sync; // Lazy-loaded process.binding('spawn_sync')
|
||||
@ -475,7 +476,8 @@ function setupChannel(target, channel) {
|
||||
return;
|
||||
}
|
||||
|
||||
var req = { oncomplete: nop };
|
||||
var req = new WriteWrap();
|
||||
req.oncomplete = nop;
|
||||
var string = JSON.stringify(message) + '\n';
|
||||
var err = channel.writeUtf8String(req, string, handle);
|
||||
|
||||
|
@ -27,6 +27,7 @@ var events = require('events');
|
||||
var constants = require('constants');
|
||||
|
||||
var UDP = process.binding('udp_wrap').UDP;
|
||||
var SendWrap = process.binding('udp_wrap').SendWrap;
|
||||
|
||||
var BIND_STATE_UNBOUND = 0;
|
||||
var BIND_STATE_BINDING = 1;
|
||||
@ -319,7 +320,9 @@ Socket.prototype.send = function(buffer,
|
||||
self.emit('error', ex);
|
||||
}
|
||||
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) {
|
||||
req.callback = callback;
|
||||
req.oncomplete = afterSend;
|
||||
|
26
lib/dns.js
26
lib/dns.js
@ -27,6 +27,9 @@ var util = require('util');
|
||||
var cares = process.binding('cares_wrap');
|
||||
var uv = process.binding('uv');
|
||||
|
||||
var GetAddrInfoReqWrap = cares.GetAddrInfoReqWrap;
|
||||
var GetNameInfoReqWrap = cares.GetNameInfoReqWrap;
|
||||
|
||||
var isIp = net.isIP;
|
||||
|
||||
|
||||
@ -144,12 +147,11 @@ exports.lookup = function lookup(hostname, options, callback) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var req = {
|
||||
callback: callback,
|
||||
family: family,
|
||||
hostname: hostname,
|
||||
oncomplete: onlookup
|
||||
};
|
||||
var req = new GetAddrInfoReqWrap();
|
||||
req.callback = callback;
|
||||
req.family = family;
|
||||
req.hostname = hostname;
|
||||
req.oncomplete = onlookup;
|
||||
|
||||
var err = cares.getaddrinfo(req, hostname, family, hints);
|
||||
if (err) {
|
||||
@ -180,12 +182,12 @@ exports.lookupService = function(host, port, callback) {
|
||||
|
||||
callback = makeAsync(callback);
|
||||
|
||||
var req = {
|
||||
callback: callback,
|
||||
host: host,
|
||||
port: port,
|
||||
oncomplete: onlookupservice
|
||||
};
|
||||
var req = new GetNameInfoReqWrap();
|
||||
req.callback = callback;
|
||||
req.host = host;
|
||||
req.port = port;
|
||||
req.oncomplete = onlookupservice;
|
||||
|
||||
var err = cares.getnameinfo(req, host, port);
|
||||
if (err) throw errnoException(err, 'getnameinfo', host);
|
||||
|
||||
|
142
lib/fs.js
142
lib/fs.js
@ -35,6 +35,7 @@ var constants = process.binding('constants');
|
||||
var fs = exports;
|
||||
var Stream = require('stream').Stream;
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var FSReqWrap = binding.FSReqWrap;
|
||||
|
||||
var Readable = Stream.Readable;
|
||||
var Writable = Stream.Writable;
|
||||
@ -184,7 +185,9 @@ fs.Stats.prototype.isSocket = function() {
|
||||
|
||||
fs.exists = function(path, callback) {
|
||||
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) {
|
||||
if (callback) callback(err ? false : true);
|
||||
}
|
||||
@ -423,7 +426,9 @@ Object.defineProperty(exports, '_stringToFlags', {
|
||||
// list to make the arguments clear.
|
||||
|
||||
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) {
|
||||
@ -445,10 +450,14 @@ fs.open = function(path, flags, mode, callback) {
|
||||
mode = modeNum(mode, 438 /*=0666*/);
|
||||
|
||||
if (!nullCheck(path, callback)) return;
|
||||
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
|
||||
binding.open(pathModule._makeLong(path),
|
||||
stringToFlags(flags),
|
||||
mode,
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -517,6 +529,16 @@ fs.readSync = function(fd, buffer, offset, length, position) {
|
||||
// OR
|
||||
// fs.write(fd, string[, position[, encoding]], 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 no position is passed then assume null
|
||||
if (util.isFunction(position)) {
|
||||
@ -524,11 +546,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
|
||||
position = null;
|
||||
}
|
||||
callback = maybeCallback(callback);
|
||||
var wrapper = function(err, written) {
|
||||
// Retain a reference to buffer so that it can't be GC'ed too soon.
|
||||
callback(err, written || 0, buffer);
|
||||
};
|
||||
return binding.writeBuffer(fd, buffer, offset, length, position, wrapper);
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = strWrapper;
|
||||
return binding.writeBuffer(fd, buffer, offset, length, position, req);
|
||||
}
|
||||
|
||||
if (util.isString(buffer))
|
||||
@ -543,11 +563,9 @@ fs.write = function(fd, buffer, offset, length, position, callback) {
|
||||
length = 'utf8';
|
||||
}
|
||||
callback = maybeCallback(position);
|
||||
position = function(err, written) {
|
||||
// retain reference to string in case it's external
|
||||
callback(err, written || 0, buffer);
|
||||
};
|
||||
return binding.writeString(fd, buffer, offset, length, position);
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = bufWrapper;
|
||||
return binding.writeString(fd, buffer, offset, length, req);
|
||||
};
|
||||
|
||||
// usage:
|
||||
@ -571,9 +589,11 @@ fs.rename = function(oldPath, newPath, callback) {
|
||||
callback = makeCallback(callback);
|
||||
if (!nullCheck(oldPath, callback)) return;
|
||||
if (!nullCheck(newPath, callback)) return;
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
binding.rename(pathModule._makeLong(oldPath),
|
||||
pathModule._makeLong(newPath),
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.renameSync = function(oldPath, newPath) {
|
||||
@ -585,8 +605,9 @@ fs.renameSync = function(oldPath, newPath) {
|
||||
|
||||
fs.truncate = function(path, len, callback) {
|
||||
if (util.isNumber(path)) {
|
||||
// legacy
|
||||
return fs.ftruncate(path, len, callback);
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
return fs.ftruncate(path, len, req);
|
||||
}
|
||||
if (util.isFunction(len)) {
|
||||
callback = len;
|
||||
@ -594,14 +615,17 @@ fs.truncate = function(path, len, callback) {
|
||||
} else if (util.isUndefined(len)) {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
callback = maybeCallback(callback);
|
||||
fs.open(path, 'r+', function(er, fd) {
|
||||
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) {
|
||||
callback(er || er2);
|
||||
});
|
||||
});
|
||||
};
|
||||
binding.ftruncate(fd, len, req);
|
||||
});
|
||||
};
|
||||
|
||||
@ -630,7 +654,9 @@ fs.ftruncate = function(fd, len, callback) {
|
||||
} else if (util.isUndefined(len)) {
|
||||
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) {
|
||||
@ -641,9 +667,11 @@ fs.ftruncateSync = function(fd, len) {
|
||||
};
|
||||
|
||||
fs.rmdir = function(path, callback) {
|
||||
callback = makeCallback(callback);
|
||||
callback = maybeCallback(callback);
|
||||
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) {
|
||||
@ -652,7 +680,9 @@ fs.rmdirSync = function(path) {
|
||||
};
|
||||
|
||||
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) {
|
||||
@ -660,7 +690,9 @@ fs.fdatasyncSync = function(fd) {
|
||||
};
|
||||
|
||||
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) {
|
||||
@ -671,9 +703,11 @@ fs.mkdir = function(path, mode, callback) {
|
||||
if (util.isFunction(mode)) callback = mode;
|
||||
callback = makeCallback(callback);
|
||||
if (!nullCheck(path, callback)) return;
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
binding.mkdir(pathModule._makeLong(path),
|
||||
modeNum(mode, 511 /*=0777*/),
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.mkdirSync = function(path, mode) {
|
||||
@ -685,7 +719,9 @@ fs.mkdirSync = function(path, mode) {
|
||||
fs.readdir = function(path, callback) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
@ -694,19 +730,25 @@ fs.readdirSync = function(path) {
|
||||
};
|
||||
|
||||
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) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
@ -726,7 +768,9 @@ fs.statSync = function(path) {
|
||||
fs.readlink = function(path, callback) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
@ -756,10 +800,13 @@ fs.symlink = function(destination, path, type_, callback) {
|
||||
if (!nullCheck(destination, callback)) return;
|
||||
if (!nullCheck(path, callback)) return;
|
||||
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
|
||||
binding.symlink(preprocessSymlinkDestination(destination, type, path),
|
||||
pathModule._makeLong(path),
|
||||
type,
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.symlinkSync = function(destination, path, type) {
|
||||
@ -778,9 +825,12 @@ fs.link = function(srcpath, dstpath, callback) {
|
||||
if (!nullCheck(srcpath, callback)) return;
|
||||
if (!nullCheck(dstpath, callback)) return;
|
||||
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
|
||||
binding.link(pathModule._makeLong(srcpath),
|
||||
pathModule._makeLong(dstpath),
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.linkSync = function(srcpath, dstpath) {
|
||||
@ -793,7 +843,9 @@ fs.linkSync = function(srcpath, dstpath) {
|
||||
fs.unlink = function(path, callback) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
@ -802,7 +854,9 @@ fs.unlinkSync = function(path) {
|
||||
};
|
||||
|
||||
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) {
|
||||
@ -852,9 +906,11 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
|
||||
fs.chmod = function(path, mode, callback) {
|
||||
callback = makeCallback(callback);
|
||||
if (!nullCheck(path, callback)) return;
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
binding.chmod(pathModule._makeLong(path),
|
||||
modeNum(mode),
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.chmodSync = function(path, mode) {
|
||||
@ -881,7 +937,9 @@ if (constants.hasOwnProperty('O_SYMLINK')) {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -891,7 +949,9 @@ fs.fchownSync = function(fd, uid, gid) {
|
||||
fs.chown = function(path, uid, gid, callback) {
|
||||
callback = makeCallback(callback);
|
||||
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) {
|
||||
@ -917,10 +977,12 @@ fs._toUnixTimestamp = toUnixTimestamp;
|
||||
fs.utimes = function(path, atime, mtime, callback) {
|
||||
callback = makeCallback(callback);
|
||||
if (!nullCheck(path, callback)) return;
|
||||
var req = new FSReqWrap();
|
||||
req.oncomplete = callback;
|
||||
binding.utimes(pathModule._makeLong(path),
|
||||
toUnixTimestamp(atime),
|
||||
toUnixTimestamp(mtime),
|
||||
callback);
|
||||
req);
|
||||
};
|
||||
|
||||
fs.utimesSync = function(path, atime, mtime) {
|
||||
@ -933,7 +995,9 @@ fs.utimesSync = function(path, atime, mtime) {
|
||||
fs.futimes = function(fd, atime, mtime, callback) {
|
||||
atime = toUnixTimestamp(atime);
|
||||
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) {
|
||||
|
23
lib/net.js
23
lib/net.js
@ -30,6 +30,11 @@ var cares = process.binding('cares_wrap');
|
||||
var uv = process.binding('uv');
|
||||
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 errnoException = util._errnoException;
|
||||
@ -239,7 +244,8 @@ function onSocketFinish() {
|
||||
if (!this._handle || !this._handle.shutdown)
|
||||
return this.destroy();
|
||||
|
||||
var req = { oncomplete: afterShutdown };
|
||||
var req = new ShutdownWrap();
|
||||
req.oncomplete = afterShutdown;
|
||||
var err = this._handle.shutdown(req);
|
||||
|
||||
if (err)
|
||||
@ -661,7 +667,9 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var req = { oncomplete: afterWrite, async: false };
|
||||
var req = new WriteWrap();
|
||||
req.oncomplete = afterWrite;
|
||||
req.async = false;
|
||||
var err;
|
||||
|
||||
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) {
|
||||
var req = new TCPConnectWrap();
|
||||
req.oncomplete = afterConnect;
|
||||
port = port | 0;
|
||||
if (port <= 0 || port > 65535)
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
var req = new PipeConnectWrap();
|
||||
req.address = address;
|
||||
req.oncomplete = afterConnect;
|
||||
err = self._handle.connect(req, address, afterConnect);
|
||||
}
|
||||
|
||||
|
@ -31,25 +31,28 @@ namespace node {
|
||||
class AsyncWrap : public BaseObject {
|
||||
public:
|
||||
enum ProviderType {
|
||||
PROVIDER_NONE = 1 << 0,
|
||||
PROVIDER_CARES = 1 << 1,
|
||||
PROVIDER_CONNECTWRAP = 1 << 2,
|
||||
PROVIDER_CRYPTO = 1 << 3,
|
||||
PROVIDER_FSEVENTWRAP = 1 << 4,
|
||||
PROVIDER_GETADDRINFOREQWRAP = 1 << 5,
|
||||
PROVIDER_PIPEWRAP = 1 << 6,
|
||||
PROVIDER_PROCESSWRAP = 1 << 7,
|
||||
PROVIDER_REQWRAP = 1 << 8,
|
||||
PROVIDER_SHUTDOWNWRAP = 1 << 9,
|
||||
PROVIDER_SIGNALWRAP = 1 << 10,
|
||||
PROVIDER_STATWATCHER = 1 << 11,
|
||||
PROVIDER_TCPWRAP = 1 << 12,
|
||||
PROVIDER_TIMERWRAP = 1 << 13,
|
||||
PROVIDER_TLSWRAP = 1 << 14,
|
||||
PROVIDER_TTYWRAP = 1 << 15,
|
||||
PROVIDER_UDPWRAP = 1 << 16,
|
||||
PROVIDER_ZLIB = 1 << 17,
|
||||
PROVIDER_GETNAMEINFOREQWRAP = 1 << 18
|
||||
PROVIDER_NONE,
|
||||
PROVIDER_CARES,
|
||||
PROVIDER_CONNECTWRAP,
|
||||
PROVIDER_CRYPTO,
|
||||
PROVIDER_FSEVENTWRAP,
|
||||
PROVIDER_FSREQWRAP,
|
||||
PROVIDER_GETADDRINFOREQWRAP,
|
||||
PROVIDER_GETNAMEINFOREQWRAP,
|
||||
PROVIDER_PIPEWRAP,
|
||||
PROVIDER_PROCESSWRAP,
|
||||
PROVIDER_QUERYWRAP,
|
||||
PROVIDER_REQWRAP,
|
||||
PROVIDER_SHUTDOWNWRAP,
|
||||
PROVIDER_SIGNALWRAP,
|
||||
PROVIDER_STATWATCHER,
|
||||
PROVIDER_TCPWRAP,
|
||||
PROVIDER_TIMERWRAP,
|
||||
PROVIDER_TLSWRAP,
|
||||
PROVIDER_TTYWRAP,
|
||||
PROVIDER_UDPWRAP,
|
||||
PROVIDER_WRITEWRAP,
|
||||
PROVIDER_ZLIB
|
||||
};
|
||||
|
||||
inline AsyncWrap(Environment* env,
|
||||
|
@ -54,6 +54,7 @@ using v8::Context;
|
||||
using v8::EscapableHandleScope;
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Handle;
|
||||
using v8::HandleScope;
|
||||
using v8::Integer;
|
||||
@ -63,8 +64,39 @@ using v8::Object;
|
||||
using v8::String;
|
||||
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) {
|
||||
@ -228,7 +260,7 @@ static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
|
||||
class QueryWrap : public AsyncWrap {
|
||||
public:
|
||||
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())
|
||||
req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0));
|
||||
}
|
||||
@ -1031,10 +1063,7 @@ static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
abort();
|
||||
}
|
||||
|
||||
GetAddrInfoReqWrap* req_wrap =
|
||||
new GetAddrInfoReqWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_GETADDRINFOREQWRAP);
|
||||
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(env, req_wrap_obj);
|
||||
|
||||
struct addrinfo hints;
|
||||
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 ||
|
||||
uv_ip6_addr(*ip, port, reinterpret_cast<sockaddr_in6*>(&addr)) == 0);
|
||||
|
||||
GetNameInfoReqWrap* req_wrap =
|
||||
new GetNameInfoReqWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_GETNAMEINFOREQWRAP);
|
||||
GetNameInfoReqWrap* req_wrap = new GetNameInfoReqWrap(env, req_wrap_obj);
|
||||
|
||||
int err = uv_getnameinfo(env->event_loop(),
|
||||
&req_wrap->req_,
|
||||
@ -1263,6 +1289,22 @@ static void Initialize(Handle<Object> target,
|
||||
Integer::New(env->isolate(), AI_ADDRCONFIG));
|
||||
target->Set(FIXED_ONE_BYTE_STRING(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
|
||||
|
117
src/node_file.cc
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, char* storage) { return storage; }
|
||||
|
||||
FSReqWrap(Environment* env, const char* syscall, char* data = nullptr)
|
||||
: ReqWrap<uv_fs_t>(env, Object::New(env->isolate())),
|
||||
FSReqWrap(Environment* env,
|
||||
Local<Object> req,
|
||||
const char* syscall,
|
||||
char* data = nullptr)
|
||||
: ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP),
|
||||
syscall_(syscall),
|
||||
data_(data),
|
||||
dest_len_(0) {
|
||||
Wrap<FSReqWrap>(object(), this);
|
||||
}
|
||||
|
||||
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) \
|
||||
if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
|
||||
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); \
|
||||
FSReqWrap* req_wrap; \
|
||||
char* dest_str = (dest_path); \
|
||||
int dest_len = dest_str == nullptr ? 0 : strlen(dest_str); \
|
||||
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); \
|
||||
if (dest_str != nullptr) { \
|
||||
memcpy(const_cast<char*>(req_wrap->dest()), \
|
||||
dest_str, \
|
||||
dest_len + 1); \
|
||||
} \
|
||||
int err = uv_fs_ ## func(env->event_loop() , \
|
||||
int err = uv_fs_ ## func(env->event_loop(), \
|
||||
&req_wrap->req_, \
|
||||
__VA_ARGS__, \
|
||||
After); \
|
||||
req_wrap->object()->Set(env->oncomplete_string(), callback); \
|
||||
req_wrap->Dispatched(); \
|
||||
if (err < 0) { \
|
||||
uv_fs_t* req = &req_wrap->req_; \
|
||||
req->result = err; \
|
||||
req->path = nullptr; \
|
||||
After(req); \
|
||||
uv_fs_t* uv_req = &req_wrap->req_; \
|
||||
uv_req->result = err; \
|
||||
uv_req->path = nullptr; \
|
||||
After(uv_req); \
|
||||
} \
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
|
||||
#define ASYNC_CALL(func, callback, ...) \
|
||||
ASYNC_DEST_CALL(func, callback, nullptr, __VA_ARGS__) \
|
||||
#define ASYNC_CALL(func, req, ...) \
|
||||
ASYNC_DEST_CALL(func, req, nullptr, __VA_ARGS__) \
|
||||
|
||||
#define SYNC_DEST_CALL(func, path, dest, ...) \
|
||||
fs_req_wrap req_wrap; \
|
||||
@ -317,7 +326,7 @@ static void Close(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
int fd = args[0]->Int32Value();
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(close, args[1], fd)
|
||||
} else {
|
||||
SYNC_CALL(close, 0, fd)
|
||||
@ -432,7 +441,7 @@ static void Stat(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
node::Utf8Value path(args[0]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(stat, args[1], *path)
|
||||
} else {
|
||||
SYNC_CALL(stat, *path, *path)
|
||||
@ -451,7 +460,7 @@ static void LStat(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
node::Utf8Value path(args[0]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(lstat, args[1], *path)
|
||||
} else {
|
||||
SYNC_CALL(lstat, *path, *path)
|
||||
@ -469,7 +478,7 @@ static void FStat(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
int fd = args[0]->Int32Value();
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(fstat, args[1], fd)
|
||||
} else {
|
||||
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)
|
||||
} else {
|
||||
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 new_path(args[1]);
|
||||
|
||||
if (args[2]->IsFunction()) {
|
||||
if (args[2]->IsObject()) {
|
||||
ASYNC_DEST_CALL(link, args[2], *new_path, *orig_path, *new_path)
|
||||
} else {
|
||||
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]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(readlink, args[1], *path)
|
||||
} else {
|
||||
SYNC_CALL(readlink, *path, *path)
|
||||
@ -572,7 +581,7 @@ static void Rename(const FunctionCallbackInfo<Value>& args) {
|
||||
node::Utf8Value old_path(args[0]);
|
||||
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)
|
||||
} else {
|
||||
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]);
|
||||
int64_t len = GET_TRUNCATE_LENGTH(args[1]);
|
||||
|
||||
if (args[2]->IsFunction()) {
|
||||
if (args[2]->IsObject()) {
|
||||
ASYNC_CALL(ftruncate, args[2], fd, len)
|
||||
} else {
|
||||
SYNC_CALL(ftruncate, 0, fd, len)
|
||||
@ -607,7 +616,7 @@ static void Fdatasync(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
int fd = args[0]->Int32Value();
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(fdatasync, args[1], fd)
|
||||
} else {
|
||||
SYNC_CALL(fdatasync, 0, fd)
|
||||
@ -623,7 +632,7 @@ static void Fsync(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
int fd = args[0]->Int32Value();
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(fsync, args[1], fd)
|
||||
} else {
|
||||
SYNC_CALL(fsync, 0, fd)
|
||||
@ -640,7 +649,7 @@ static void Unlink(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
node::Utf8Value path(args[0]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(unlink, args[1], *path)
|
||||
} else {
|
||||
SYNC_CALL(unlink, *path, *path)
|
||||
@ -657,7 +666,7 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
node::Utf8Value path(args[0]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(rmdir, args[1], *path)
|
||||
} else {
|
||||
SYNC_CALL(rmdir, *path, *path)
|
||||
@ -674,7 +683,7 @@ static void MKDir(const FunctionCallbackInfo<Value>& args) {
|
||||
node::Utf8Value path(args[0]);
|
||||
int mode = static_cast<int>(args[1]->Int32Value());
|
||||
|
||||
if (args[2]->IsFunction()) {
|
||||
if (args[2]->IsObject()) {
|
||||
ASYNC_CALL(mkdir, args[2], *path, mode)
|
||||
} else {
|
||||
SYNC_CALL(mkdir, *path, *path, mode)
|
||||
@ -691,7 +700,7 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
node::Utf8Value path(args[0]);
|
||||
|
||||
if (args[1]->IsFunction()) {
|
||||
if (args[1]->IsObject()) {
|
||||
ASYNC_CALL(scandir, args[1], *path, 0 /*flags*/)
|
||||
} else {
|
||||
SYNC_CALL(scandir, *path, *path, 0 /*flags*/)
|
||||
@ -739,7 +748,7 @@ static void Open(const FunctionCallbackInfo<Value>& args) {
|
||||
int flags = args[1]->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)
|
||||
} else {
|
||||
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 len = args[3]->Uint32Value();
|
||||
int64_t pos = GET_OFFSET(args[4]);
|
||||
Local<Value> cb = args[5];
|
||||
Local<Value> req = args[5];
|
||||
|
||||
if (off > buffer_length)
|
||||
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);
|
||||
|
||||
if (cb->IsFunction()) {
|
||||
ASYNC_CALL(write, cb, fd, &uvbuf, 1, pos)
|
||||
if (req->IsObject()) {
|
||||
ASYNC_CALL(write, req, fd, &uvbuf, 1, pos)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -809,7 +818,7 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
if (!args[0]->IsInt32())
|
||||
return env->ThrowTypeError("First argument must be file descriptor");
|
||||
|
||||
Local<Value> cb;
|
||||
Local<Value> req;
|
||||
Local<Value> string = args[1];
|
||||
int fd = args[0]->Int32Value();
|
||||
char* buf = nullptr;
|
||||
@ -831,18 +840,19 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
must_free = true;
|
||||
}
|
||||
pos = GET_OFFSET(args[2]);
|
||||
cb = args[4];
|
||||
req = args[4];
|
||||
|
||||
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)
|
||||
if (must_free)
|
||||
delete[] buf;
|
||||
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(),
|
||||
&req_wrap->req_,
|
||||
fd,
|
||||
@ -850,13 +860,12 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
1,
|
||||
pos,
|
||||
After);
|
||||
req_wrap->object()->Set(env->oncomplete_string(), cb);
|
||||
req_wrap->Dispatched();
|
||||
if (err < 0) {
|
||||
uv_fs_t* req = &req_wrap->req_;
|
||||
req->result = err;
|
||||
req->path = nullptr;
|
||||
After(req);
|
||||
uv_fs_t* uv_req = &req_wrap->req_;
|
||||
uv_req->result = err;
|
||||
uv_req->path = nullptr;
|
||||
After(uv_req);
|
||||
}
|
||||
|
||||
return args.GetReturnValue().Set(req_wrap->persistent());
|
||||
@ -884,7 +893,7 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
int fd = args[0]->Int32Value();
|
||||
|
||||
Local<Value> cb;
|
||||
Local<Value> req;
|
||||
|
||||
size_t len;
|
||||
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);
|
||||
|
||||
cb = args[5];
|
||||
req = args[5];
|
||||
|
||||
if (cb->IsFunction()) {
|
||||
ASYNC_CALL(read, cb, fd, &uvbuf, 1, pos);
|
||||
if (req->IsObject()) {
|
||||
ASYNC_CALL(read, req, fd, &uvbuf, 1, pos);
|
||||
} else {
|
||||
SYNC_CALL(read, 0, fd, &uvbuf, 1, pos)
|
||||
args.GetReturnValue().Set(SYNC_RESULT);
|
||||
@ -937,7 +946,7 @@ static void Chmod(const FunctionCallbackInfo<Value>& args) {
|
||||
node::Utf8Value path(args[0]);
|
||||
int mode = static_cast<int>(args[1]->Int32Value());
|
||||
|
||||
if (args[2]->IsFunction()) {
|
||||
if (args[2]->IsObject()) {
|
||||
ASYNC_CALL(chmod, args[2], *path, mode);
|
||||
} else {
|
||||
SYNC_CALL(chmod, *path, *path, mode);
|
||||
@ -957,7 +966,7 @@ static void FChmod(const FunctionCallbackInfo<Value>& args) {
|
||||
int fd = args[0]->Int32Value();
|
||||
int mode = static_cast<int>(args[1]->Int32Value());
|
||||
|
||||
if (args[2]->IsFunction()) {
|
||||
if (args[2]->IsObject()) {
|
||||
ASYNC_CALL(fchmod, args[2], fd, mode);
|
||||
} else {
|
||||
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_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);
|
||||
} else {
|
||||
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_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);
|
||||
} else {
|
||||
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 mtime = static_cast<double>(args[2]->NumberValue());
|
||||
|
||||
if (args[3]->IsFunction()) {
|
||||
if (args[3]->IsObject()) {
|
||||
ASYNC_CALL(utime, args[3], *path, atime, mtime);
|
||||
} else {
|
||||
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 mtime = static_cast<double>(args[2]->NumberValue());
|
||||
|
||||
if (args[3]->IsFunction()) {
|
||||
if (args[3]->IsObject()) {
|
||||
ASYNC_CALL(futime, args[3], fd, atime, mtime);
|
||||
} else {
|
||||
SYNC_CALL(futime, 0, fd, atime, mtime);
|
||||
@ -1135,6 +1144,14 @@ void InitFs(Handle<Object> target,
|
||||
env->SetMethod(target, "futimes", FUTimes);
|
||||
|
||||
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
|
||||
|
@ -50,8 +50,23 @@ using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
|
||||
// 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() {
|
||||
@ -115,6 +130,14 @@ void PipeWrap::Initialize(Handle<Object> target,
|
||||
|
||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction());
|
||||
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?
|
||||
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);
|
||||
CHECK_EQ(req_wrap->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>();
|
||||
node::Utf8Value name(args[1]);
|
||||
|
||||
ConnectWrap* req_wrap = new ConnectWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_CONNECTWRAP);
|
||||
PipeConnectWrap* req_wrap = new PipeConnectWrap(env, req_wrap_obj);
|
||||
uv_pipe_connect(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
*name,
|
||||
|
@ -36,8 +36,8 @@ class ReqWrap : public AsyncWrap {
|
||||
public:
|
||||
ReqWrap(Environment* env,
|
||||
v8::Handle<v8::Object> object,
|
||||
AsyncWrap::ProviderType provider = AsyncWrap::PROVIDER_REQWRAP)
|
||||
: AsyncWrap(env, object, AsyncWrap::PROVIDER_REQWRAP) {
|
||||
AsyncWrap::ProviderType provider)
|
||||
: AsyncWrap(env, object, provider) {
|
||||
if (env->in_domain())
|
||||
object->Set(env->domain_string(), env->domain_array()->Get(0));
|
||||
|
||||
|
@ -43,6 +43,7 @@ using v8::Array;
|
||||
using v8::Context;
|
||||
using v8::EscapableHandleScope;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Handle;
|
||||
using v8::HandleScope;
|
||||
using v8::Integer;
|
||||
@ -56,6 +57,27 @@ using v8::Undefined;
|
||||
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,
|
||||
Local<Object> object,
|
||||
uv_stream_t* stream,
|
||||
@ -88,6 +110,7 @@ void StreamWrap::UpdateWriteQueueSize() {
|
||||
object()->Set(env()->write_queue_size_string(), write_queue_size);
|
||||
}
|
||||
|
||||
|
||||
void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
|
||||
StreamWrap* wrap = Unwrap<StreamWrap>(args.Holder());
|
||||
if (!IsAlive(wrap))
|
||||
@ -564,9 +587,7 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
|
||||
CHECK(args[0]->IsObject());
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
|
||||
ShutdownWrap* req_wrap = new ShutdownWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_SHUTDOWNWRAP);
|
||||
ShutdownWrap* req_wrap = new ShutdownWrap(env, req_wrap_obj);
|
||||
int err = wrap->callbacks()->DoShutdown(req_wrap, AfterShutdown);
|
||||
req_wrap->Dispatched();
|
||||
if (err)
|
||||
@ -752,3 +773,5 @@ int StreamWrapCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(stream_wrap, node::StreamWrap::Initialize)
|
||||
|
@ -33,15 +33,26 @@ namespace node {
|
||||
// Forward declaration
|
||||
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> {
|
||||
public:
|
||||
// TODO(trevnorris): WrapWrap inherits from ReqWrap, which I've globbed
|
||||
// into the same provider. How should these be broken apart?
|
||||
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<WriteWrap>(obj, this);
|
||||
}
|
||||
|
||||
void* operator new(size_t size, char* storage) { return storage; }
|
||||
@ -54,6 +65,10 @@ class WriteWrap: public ReqWrap<uv_write_t> {
|
||||
return wrap_;
|
||||
}
|
||||
|
||||
static void NewWriteWrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
CHECK(args.IsConstructCall());
|
||||
}
|
||||
|
||||
private:
|
||||
// People should not be using the non-placement new and delete operator on a
|
||||
// WriteWrap. Ensure this never happens.
|
||||
@ -105,6 +120,10 @@ class StreamWrapCallbacks {
|
||||
|
||||
class StreamWrap : public HandleWrap {
|
||||
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) {
|
||||
StreamWrapCallbacks* old = callbacks_;
|
||||
callbacks_ = callbacks;
|
||||
|
@ -52,7 +52,22 @@ using v8::String;
|
||||
using v8::Undefined;
|
||||
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) {
|
||||
@ -129,6 +144,14 @@ void TCPWrap::Initialize(Handle<Object> target,
|
||||
|
||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"), t->GetFunction());
|
||||
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) {
|
||||
ConnectWrap* req_wrap = static_cast<ConnectWrap*>(req->data);
|
||||
TCPConnectWrap* req_wrap = static_cast<TCPConnectWrap*>(req->data);
|
||||
TCPWrap* wrap = static_cast<TCPWrap*>(req->handle->data);
|
||||
CHECK_EQ(req_wrap->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);
|
||||
|
||||
if (err == 0) {
|
||||
ConnectWrap* req_wrap = new ConnectWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_CONNECTWRAP);
|
||||
TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj);
|
||||
err = uv_tcp_connect(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
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);
|
||||
|
||||
if (err == 0) {
|
||||
ConnectWrap* req_wrap = new ConnectWrap(env,
|
||||
req_wrap_obj,
|
||||
AsyncWrap::PROVIDER_CONNECTWRAP);
|
||||
TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj);
|
||||
err = uv_tcp_connect(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
reinterpret_cast<const sockaddr*>(&addr),
|
||||
|
@ -62,8 +62,9 @@ class SendWrap : public ReqWrap<uv_udp_send_t> {
|
||||
SendWrap::SendWrap(Environment* env,
|
||||
Local<Object> req_wrap_obj,
|
||||
bool have_callback)
|
||||
: ReqWrap<uv_udp_send_t>(env, req_wrap_obj),
|
||||
: ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_UDPWRAP),
|
||||
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)
|
||||
: HandleWrap(env,
|
||||
object,
|
||||
@ -120,6 +126,14 @@ void UDPWrap::Initialize(Handle<Object> target,
|
||||
|
||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), 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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -632,8 +632,9 @@ var getaddrinfoCallbackCalled = false;
|
||||
|
||||
console.log('looking up nodejs.org...');
|
||||
|
||||
var req = {};
|
||||
var err = process.binding('cares_wrap').getaddrinfo(req, 'nodejs.org', 4);
|
||||
var cares = process.binding('cares_wrap');
|
||||
var req = new cares.GetAddrInfoReqWrap();
|
||||
var err = cares.getaddrinfo(req, 'nodejs.org', 4);
|
||||
|
||||
req.oncomplete = function(err, domains) {
|
||||
assert.strictEqual(err, 0);
|
||||
|
@ -22,11 +22,13 @@
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var TCP = process.binding('tcp_wrap').TCP;
|
||||
var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap;
|
||||
var ShutdownWrap = process.binding('stream_wrap').ShutdownWrap;
|
||||
|
||||
function makeConnection() {
|
||||
var client = new TCP();
|
||||
|
||||
var req = {};
|
||||
var req = new TCPConnectWrap();
|
||||
var err = client.connect(req, '127.0.0.1', common.PORT);
|
||||
assert.equal(err, 0);
|
||||
|
||||
@ -36,7 +38,7 @@ function makeConnection() {
|
||||
assert.equal(req, req_);
|
||||
|
||||
console.log('connected');
|
||||
var shutdownReq = {};
|
||||
var shutdownReq = new ShutdownWrap();
|
||||
var err = client.shutdown(shutdownReq);
|
||||
assert.equal(err, 0);
|
||||
|
||||
|
@ -23,6 +23,7 @@ var common = require('../common');
|
||||
var assert = require('assert');
|
||||
|
||||
var TCP = process.binding('tcp_wrap').TCP;
|
||||
var WriteWrap = process.binding('stream_wrap').WriteWrap;
|
||||
|
||||
var server = new TCP();
|
||||
|
||||
@ -55,7 +56,8 @@ server.onconnection = function(err, client) {
|
||||
|
||||
assert.equal(0, client.writeQueueSize);
|
||||
|
||||
var req = { async: false };
|
||||
var req = new WriteWrap();
|
||||
req.async = false;
|
||||
var err = client.writeBuffer(req, buffer);
|
||||
assert.equal(err, 0);
|
||||
client.pendingWrites.push(req);
|
||||
|
Loading…
x
Reference in New Issue
Block a user