lib,src: standardize owner_symbol
for handles
Instead of somtimes using an `owner` string to link from a native handle object to the corresponding JS object, standardize on a single symbol that fulfills this role. PR-URL: https://github.com/nodejs/node/pull/22002 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jon Moss <me@jonathanmoss.me> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
This commit is contained in:
parent
a196aa2e24
commit
af7164ebcc
@ -35,6 +35,7 @@ const debug = util.debuglog('tls');
|
||||
const tls_wrap = process.binding('tls_wrap');
|
||||
const { TCP, constants: TCPConstants } = process.binding('tcp_wrap');
|
||||
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap');
|
||||
const { owner_symbol } = require('internal/async_hooks').symbols;
|
||||
const {
|
||||
SecureContext: NativeSecureContext
|
||||
} = process.binding('crypto');
|
||||
@ -76,7 +77,7 @@ function onhandshakestart(now) {
|
||||
else
|
||||
this.handshakes++;
|
||||
|
||||
const { owner } = this;
|
||||
const owner = this[owner_symbol];
|
||||
if (this.handshakes > tls.CLIENT_RENEG_LIMIT) {
|
||||
owner._emitTLSError(new ERR_TLS_SESSION_ATTACK());
|
||||
return;
|
||||
@ -89,7 +90,7 @@ function onhandshakestart(now) {
|
||||
function onhandshakedone() {
|
||||
debug('onhandshakedone');
|
||||
|
||||
const owner = this.owner;
|
||||
const owner = this[owner_symbol];
|
||||
|
||||
// `newSession` callback wasn't called yet
|
||||
if (owner._newSessionPending) {
|
||||
@ -102,7 +103,7 @@ function onhandshakedone() {
|
||||
|
||||
|
||||
function loadSession(hello) {
|
||||
const owner = this.owner;
|
||||
const owner = this[owner_symbol];
|
||||
|
||||
var once = false;
|
||||
function onSession(err, session) {
|
||||
@ -130,7 +131,7 @@ function loadSession(hello) {
|
||||
|
||||
|
||||
function loadSNI(info) {
|
||||
const owner = this.owner;
|
||||
const owner = this[owner_symbol];
|
||||
const servername = info.servername;
|
||||
if (!servername || !owner._SNICallback)
|
||||
return requestOCSP(owner, info);
|
||||
@ -212,7 +213,7 @@ function requestOCSPDone(socket) {
|
||||
|
||||
|
||||
function onnewsession(key, session) {
|
||||
const owner = this.owner;
|
||||
const owner = this[owner_symbol];
|
||||
|
||||
if (!owner.server)
|
||||
return;
|
||||
@ -241,11 +242,11 @@ function onnewsession(key, session) {
|
||||
|
||||
|
||||
function onocspresponse(resp) {
|
||||
this.owner.emit('OCSPResponse', resp);
|
||||
this[owner_symbol].emit('OCSPResponse', resp);
|
||||
}
|
||||
|
||||
function onerror(err) {
|
||||
const owner = this.owner;
|
||||
const owner = this[owner_symbol];
|
||||
|
||||
if (owner._writableState.errorEmitted)
|
||||
return;
|
||||
@ -364,9 +365,9 @@ for (var n = 0; n < proxiedMethods.length; n++) {
|
||||
|
||||
tls_wrap.TLSWrap.prototype.close = function close(cb) {
|
||||
let ssl;
|
||||
if (this.owner) {
|
||||
ssl = this.owner.ssl;
|
||||
this.owner.ssl = null;
|
||||
if (this[owner_symbol]) {
|
||||
ssl = this[owner_symbol].ssl;
|
||||
this[owner_symbol].ssl = null;
|
||||
}
|
||||
|
||||
// Invoke `destroySSL` on close to clean up possibly pending write requests
|
||||
@ -405,7 +406,7 @@ TLSSocket.prototype._wrapHandle = function(wrap) {
|
||||
handle = options.pipe ?
|
||||
new Pipe(PipeConstants.SOCKET) :
|
||||
new TCP(TCPConstants.SOCKET);
|
||||
handle.owner = this;
|
||||
handle[owner_symbol] = this;
|
||||
}
|
||||
|
||||
// Wrap socket's handle
|
||||
|
16
lib/dgram.js
16
lib/dgram.js
@ -43,7 +43,7 @@ const { isUint8Array } = require('internal/util/types');
|
||||
const EventEmitter = require('events');
|
||||
const {
|
||||
defaultTriggerAsyncIdScope,
|
||||
symbols: { async_id_symbol }
|
||||
symbols: { async_id_symbol, owner_symbol }
|
||||
} = require('internal/async_hooks');
|
||||
const { UV_UDP_REUSEADDR } = process.binding('constants').os;
|
||||
|
||||
@ -78,7 +78,7 @@ function Socket(type, listener) {
|
||||
}
|
||||
|
||||
var handle = newHandle(type, lookup);
|
||||
handle.owner = this;
|
||||
handle[owner_symbol] = this;
|
||||
|
||||
this[async_id_symbol] = handle.getAsyncId();
|
||||
this.type = type;
|
||||
@ -132,7 +132,7 @@ function replaceHandle(self, newHandle) {
|
||||
newHandle.lookup = oldHandle.lookup;
|
||||
newHandle.bind = oldHandle.bind;
|
||||
newHandle.send = oldHandle.send;
|
||||
newHandle.owner = self;
|
||||
newHandle[owner_symbol] = self;
|
||||
|
||||
// Replace the existing handle by the handle we got from master.
|
||||
oldHandle.close();
|
||||
@ -635,7 +635,7 @@ function stopReceiving(socket) {
|
||||
|
||||
|
||||
function onMessage(nread, handle, buf, rinfo) {
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
if (nread < 0) {
|
||||
return self.emit('error', errnoException(nread, 'recvmsg'));
|
||||
}
|
||||
@ -745,6 +745,14 @@ Socket.prototype._stopReceiving = function() {
|
||||
};
|
||||
|
||||
|
||||
// Legacy alias on the C++ wrapper object. This is not public API, so we may
|
||||
// want to runtime-deprecate it at some point. There's no hurry, though.
|
||||
Object.defineProperty(UDP.prototype, 'owner', {
|
||||
get() { return this[owner_symbol]; },
|
||||
set(v) { return this[owner_symbol] = v; }
|
||||
});
|
||||
|
||||
|
||||
module.exports = {
|
||||
_createSocketHandle,
|
||||
createSocket,
|
||||
|
@ -30,7 +30,7 @@ const async_wrap = process.binding('async_wrap');
|
||||
* It has a fixed size, so if that is exceeded, calls to the native
|
||||
* side are used instead in pushAsyncIds() and popAsyncIds().
|
||||
*/
|
||||
const { async_hook_fields, async_id_fields } = async_wrap;
|
||||
const { async_hook_fields, async_id_fields, owner_symbol } = async_wrap;
|
||||
// Store the pair executionAsyncId and triggerAsyncId in a std::stack on
|
||||
// Environment::AsyncHooks::async_ids_stack_ tracks the resource responsible for
|
||||
// the current execution stack. This is unwound as each resource exits. In the
|
||||
@ -434,7 +434,7 @@ module.exports = {
|
||||
symbols: {
|
||||
async_id_symbol, trigger_async_id_symbol,
|
||||
init_symbol, before_symbol, after_symbol, destroy_symbol,
|
||||
promise_resolve_symbol
|
||||
promise_resolve_symbol, owner_symbol
|
||||
},
|
||||
constants: {
|
||||
kInit, kBefore, kAfter, kDestroy, kTotals, kPromiseResolve
|
||||
|
@ -27,6 +27,7 @@ const { TTY } = process.binding('tty_wrap');
|
||||
const { TCP } = process.binding('tcp_wrap');
|
||||
const { UDP } = process.binding('udp_wrap');
|
||||
const SocketList = require('internal/socket_list');
|
||||
const { owner_symbol } = require('internal/async_hooks').symbols;
|
||||
const { convertToValidSignal } = require('internal/util');
|
||||
const { isUint8Array } = require('internal/util/types');
|
||||
const spawn_sync = process.binding('spawn_sync');
|
||||
@ -209,7 +210,7 @@ function ChildProcess() {
|
||||
this.spawnfile = null;
|
||||
|
||||
this._handle = new Process();
|
||||
this._handle.owner = this;
|
||||
this._handle[owner_symbol] = this;
|
||||
|
||||
this._handle.onexit = (exitCode, signalCode) => {
|
||||
if (signalCode) {
|
||||
|
@ -3,6 +3,7 @@ const assert = require('assert');
|
||||
const util = require('util');
|
||||
const path = require('path');
|
||||
const EventEmitter = require('events');
|
||||
const { owner_symbol } = require('internal/async_hooks').symbols;
|
||||
const Worker = require('internal/cluster/worker');
|
||||
const { internal, sendHelper } = require('internal/cluster/utils');
|
||||
const cluster = new EventEmitter();
|
||||
@ -207,8 +208,8 @@ function _disconnect(masterInitiated) {
|
||||
delete handles[key];
|
||||
waitingCount++;
|
||||
|
||||
if (handle.owner)
|
||||
handle.owner.close(checkWaitingCount);
|
||||
if (handle[owner_symbol])
|
||||
handle[owner_symbol].close(checkWaitingCount);
|
||||
else
|
||||
handle.close(checkWaitingCount);
|
||||
}
|
||||
|
@ -11,7 +11,10 @@ const {
|
||||
getStatsFromBinding,
|
||||
validatePath
|
||||
} = require('internal/fs/utils');
|
||||
const { defaultTriggerAsyncIdScope } = require('internal/async_hooks');
|
||||
const {
|
||||
defaultTriggerAsyncIdScope,
|
||||
symbols: { owner_symbol }
|
||||
} = require('internal/async_hooks');
|
||||
const { toNamespacedPath } = require('path');
|
||||
const { validateUint32 } = require('internal/validators');
|
||||
const { getPathFromURL } = require('internal/url');
|
||||
@ -20,7 +23,6 @@ const assert = require('assert');
|
||||
|
||||
const kOldStatus = Symbol('kOldStatus');
|
||||
const kUseBigint = Symbol('kUseBigint');
|
||||
const kOwner = Symbol('kOwner');
|
||||
|
||||
function emitStop(self) {
|
||||
self.emit('stop');
|
||||
@ -36,7 +38,7 @@ function StatWatcher(bigint) {
|
||||
util.inherits(StatWatcher, EventEmitter);
|
||||
|
||||
function onchange(newStatus, stats) {
|
||||
const self = this[kOwner];
|
||||
const self = this[owner_symbol];
|
||||
if (self[kOldStatus] === -1 &&
|
||||
newStatus === -1 &&
|
||||
stats[2/* new nlink */] === stats[16/* old nlink */]) {
|
||||
@ -59,7 +61,7 @@ StatWatcher.prototype.start = function(filename, persistent, interval) {
|
||||
return;
|
||||
|
||||
this._handle = new _StatWatcher(this[kUseBigint]);
|
||||
this._handle[kOwner] = this;
|
||||
this._handle[owner_symbol] = this;
|
||||
this._handle.onchange = onchange;
|
||||
if (!persistent)
|
||||
this._handle.unref();
|
||||
@ -104,7 +106,7 @@ function FSWatcher() {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this._handle = new FSEvent();
|
||||
this._handle.owner = this;
|
||||
this._handle[owner_symbol] = this;
|
||||
|
||||
this._handle.onchange = (status, eventType, filename) => {
|
||||
// TODO(joyeecheung): we may check self._handle.initialized here
|
||||
@ -131,6 +133,7 @@ function FSWatcher() {
|
||||
}
|
||||
util.inherits(FSWatcher, EventEmitter);
|
||||
|
||||
|
||||
// FIXME(joyeecheung): this method is not documented.
|
||||
// At the moment if filename is undefined, we
|
||||
// 1. Throw an Error if it's the first time .start() is called
|
||||
@ -187,6 +190,13 @@ function emitCloseNT(self) {
|
||||
self.emit('close');
|
||||
}
|
||||
|
||||
// Legacy alias on the C++ wrapper object. This is not public API, so we may
|
||||
// want to runtime-deprecate it at some point. There's no hurry, though.
|
||||
Object.defineProperty(FSEvent.prototype, 'owner', {
|
||||
get() { return this[owner_symbol]; },
|
||||
set(v) { return this[owner_symbol] = v; }
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
FSWatcher,
|
||||
StatWatcher
|
||||
|
@ -28,6 +28,7 @@ const {
|
||||
defaultTriggerAsyncIdScope,
|
||||
symbols: {
|
||||
async_id_symbol,
|
||||
owner_symbol,
|
||||
},
|
||||
} = require('internal/async_hooks');
|
||||
const { internalBinding } = require('internal/bootstrap/loaders');
|
||||
@ -141,7 +142,7 @@ const kInfoHeaders = Symbol('sent-info-headers');
|
||||
const kMaybeDestroy = Symbol('maybe-destroy');
|
||||
const kLocalSettings = Symbol('local-settings');
|
||||
const kOptions = Symbol('options');
|
||||
const kOwner = Symbol('owner');
|
||||
const kOwner = owner_symbol;
|
||||
const kProceed = Symbol('proceed');
|
||||
const kProtocol = Symbol('protocol');
|
||||
const kProxySocket = Symbol('proxy-socket');
|
||||
|
@ -6,16 +6,17 @@ const { Socket } = require('net');
|
||||
const { JSStream } = process.binding('js_stream');
|
||||
const uv = process.binding('uv');
|
||||
const debug = util.debuglog('stream_wrap');
|
||||
const { owner_symbol } = require('internal/async_hooks').symbols;
|
||||
const { ERR_STREAM_WRAP } = require('internal/errors').codes;
|
||||
|
||||
const kCurrentWriteRequest = Symbol('kCurrentWriteRequest');
|
||||
const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest');
|
||||
|
||||
function isClosing() { return this.owner.isClosing(); }
|
||||
function onreadstart() { return this.owner.readStart(); }
|
||||
function onreadstop() { return this.owner.readStop(); }
|
||||
function onshutdown(req) { return this.owner.doShutdown(req); }
|
||||
function onwrite(req, bufs) { return this.owner.doWrite(req, bufs); }
|
||||
function isClosing() { return this[owner_symbol].isClosing(); }
|
||||
function onreadstart() { return this[owner_symbol].readStart(); }
|
||||
function onreadstop() { return this[owner_symbol].readStop(); }
|
||||
function onshutdown(req) { return this[owner_symbol].doShutdown(req); }
|
||||
function onwrite(req, bufs) { return this[owner_symbol].doWrite(req, bufs); }
|
||||
|
||||
/* This class serves as a wrapper for when the C++ side of Node wants access
|
||||
* to a standard JS stream. For example, TLS or HTTP do not operate on network
|
||||
@ -37,7 +38,7 @@ class JSStreamWrap extends Socket {
|
||||
this.doClose(cb);
|
||||
};
|
||||
// Inside of the following functions, `this` refers to the handle
|
||||
// and `this.owner` refers to this JSStreamWrap instance.
|
||||
// and `this[owner_symbol]` refers to this JSStreamWrap instance.
|
||||
handle.isClosing = isClosing;
|
||||
handle.onreadstart = onreadstart;
|
||||
handle.onreadstop = onreadstop;
|
||||
|
24
lib/net.js
24
lib/net.js
@ -56,7 +56,7 @@ const {
|
||||
const {
|
||||
newAsyncId,
|
||||
defaultTriggerAsyncIdScope,
|
||||
symbols: { async_id_symbol }
|
||||
symbols: { async_id_symbol, owner_symbol }
|
||||
} = require('internal/async_hooks');
|
||||
const {
|
||||
createWriteWrap,
|
||||
@ -207,7 +207,7 @@ function initSocketHandle(self) {
|
||||
|
||||
// Handle creation may be deferred to bind() or connect() time.
|
||||
if (self._handle) {
|
||||
self._handle.owner = self;
|
||||
self._handle[owner_symbol] = self;
|
||||
self._handle.onread = onread;
|
||||
self[async_id_symbol] = getNewAsyncId(self._handle);
|
||||
}
|
||||
@ -371,7 +371,7 @@ Socket.prototype._final = function(cb) {
|
||||
|
||||
|
||||
function afterShutdown(status, handle) {
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
|
||||
debug('afterShutdown destroyed=%j', self.destroyed,
|
||||
self._readableState);
|
||||
@ -620,7 +620,7 @@ Socket.prototype._destroy = function(exception, cb) {
|
||||
// buffer, or when there's an error reading.
|
||||
function onread(nread, buffer) {
|
||||
var handle = this;
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
assert(handle === self._handle, 'handle != self._handle');
|
||||
|
||||
self._unrefTimer();
|
||||
@ -819,7 +819,7 @@ protoGetter('bytesWritten', function bytesWritten() {
|
||||
|
||||
|
||||
function afterWrite(status, handle, err) {
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
if (self !== process.stderr && self !== process.stdout)
|
||||
debug('afterWrite', status);
|
||||
|
||||
@ -1123,7 +1123,7 @@ Socket.prototype.unref = function() {
|
||||
|
||||
|
||||
function afterConnect(status, handle, req, readable, writable) {
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
|
||||
// callback may come after call to destroy
|
||||
if (self.destroyed) {
|
||||
@ -1325,7 +1325,7 @@ function setupListenHandle(address, port, addressType, backlog, fd) {
|
||||
|
||||
this[async_id_symbol] = getNewAsyncId(this._handle);
|
||||
this._handle.onconnection = onconnection;
|
||||
this._handle.owner = this;
|
||||
this._handle[owner_symbol] = this;
|
||||
|
||||
// Use a backlog of 512 entries. We pass 511 to the listen() call because
|
||||
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
|
||||
@ -1538,7 +1538,7 @@ Server.prototype.address = function() {
|
||||
|
||||
function onconnection(err, clientHandle) {
|
||||
var handle = this;
|
||||
var self = handle.owner;
|
||||
var self = handle[owner_symbol];
|
||||
|
||||
debug('onconnection');
|
||||
|
||||
@ -1669,6 +1669,14 @@ function emitCloseNT(self) {
|
||||
}
|
||||
|
||||
|
||||
// Legacy alias on the C++ wrapper object. This is not public API, so we may
|
||||
// want to runtime-deprecate it at some point. There's no hurry, though.
|
||||
Object.defineProperty(TCP.prototype, 'owner', {
|
||||
get() { return this[owner_symbol]; },
|
||||
set(v) { return this[owner_symbol] = v; }
|
||||
});
|
||||
|
||||
|
||||
Server.prototype.listenFD = internalUtil.deprecate(function(fd, type) {
|
||||
return this.listen({ fd: fd });
|
||||
}, 'Server.listenFD is deprecated. Use Server.listen({fd: <number>}) instead.',
|
||||
|
@ -481,6 +481,10 @@ void AsyncWrap::Initialize(Local<Object> target,
|
||||
env->async_ids_stack_string(),
|
||||
env->async_hooks()->async_ids_stack().GetJSArray()).FromJust();
|
||||
|
||||
target->Set(context,
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), "owner_symbol"),
|
||||
env->owner_symbol()).FromJust();
|
||||
|
||||
Local<Object> constants = Object::New(isolate);
|
||||
#define SET_HOOKS_CONSTANT(name) \
|
||||
FORCE_SET_TARGET_FIELD( \
|
||||
|
@ -111,6 +111,7 @@ struct PackageConfig {
|
||||
// for the sake of convenience.
|
||||
#define PER_ISOLATE_SYMBOL_PROPERTIES(V) \
|
||||
V(handle_onclose_symbol, "handle_onclose") \
|
||||
V(owner_symbol, "owner") \
|
||||
|
||||
// Strings are per-isolate primitives but Environment proxies them
|
||||
// for the sake of convenience. Strings should be ASCII-only.
|
||||
@ -234,7 +235,6 @@ struct PackageConfig {
|
||||
V(openssl_error_stack, "opensslErrorStack") \
|
||||
V(output_string, "output") \
|
||||
V(order_string, "order") \
|
||||
V(owner_string, "owner") \
|
||||
V(parse_error_string, "Parse Error") \
|
||||
V(password_string, "password") \
|
||||
V(path_string, "path") \
|
||||
|
@ -81,7 +81,7 @@ void TCPWrap::Initialize(Local<Object> target,
|
||||
// Init properties
|
||||
t->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "reading"),
|
||||
Boolean::New(env->isolate(), false));
|
||||
t->InstanceTemplate()->Set(env->owner_string(), Null(env->isolate()));
|
||||
t->InstanceTemplate()->Set(env->owner_symbol(), Null(env->isolate()));
|
||||
t->InstanceTemplate()->Set(env->onread_string(), Null(env->isolate()));
|
||||
t->InstanceTemplate()->Set(env->onconnection_string(), Null(env->isolate()));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user