diff options
author | Anna Henningsen <anna@addaleax.net> | 2018-07-27 14:35:39 +0200 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-08-05 13:46:13 +0200 |
commit | af7164ebccd21d9fc5b0782e0427257f7637a4db (patch) | |
tree | 589f506811cb65293b88fcd8984ae7ac0e5a80be | |
parent | a196aa2e24ef7069289fa4a9aa8c6862d82e6b5f (diff) | |
download | android-node-v8-af7164ebccd21d9fc5b0782e0427257f7637a4db.tar.gz android-node-v8-af7164ebccd21d9fc5b0782e0427257f7637a4db.tar.bz2 android-node-v8-af7164ebccd21d9fc5b0782e0427257f7637a4db.zip |
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>
-rw-r--r-- | lib/_tls_wrap.js | 23 | ||||
-rw-r--r-- | lib/dgram.js | 16 | ||||
-rw-r--r-- | lib/internal/async_hooks.js | 4 | ||||
-rw-r--r-- | lib/internal/child_process.js | 3 | ||||
-rw-r--r-- | lib/internal/cluster/child.js | 5 | ||||
-rw-r--r-- | lib/internal/fs/watchers.js | 20 | ||||
-rw-r--r-- | lib/internal/http2/core.js | 3 | ||||
-rw-r--r-- | lib/internal/wrap_js_stream.js | 13 | ||||
-rw-r--r-- | lib/net.js | 24 | ||||
-rw-r--r-- | src/async_wrap.cc | 4 | ||||
-rw-r--r-- | src/env.h | 2 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 2 |
12 files changed, 77 insertions, 42 deletions
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 225d65fee3..83da2721e8 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -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 diff --git a/lib/dgram.js b/lib/dgram.js index 292f7daf87..8ddd523237 100644 --- a/lib/dgram.js +++ b/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, diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index 90155fa3c7..9edb23f8a6 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -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 diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index d22009505a..558932d341 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -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) { diff --git a/lib/internal/cluster/child.js b/lib/internal/cluster/child.js index 40c1a12327..39e891214f 100644 --- a/lib/internal/cluster/child.js +++ b/lib/internal/cluster/child.js @@ -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); } diff --git a/lib/internal/fs/watchers.js b/lib/internal/fs/watchers.js index e7edc1c5ac..90ea3971aa 100644 --- a/lib/internal/fs/watchers.js +++ b/lib/internal/fs/watchers.js @@ -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 diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 18c0c4ce4c..568980c927 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -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'); diff --git a/lib/internal/wrap_js_stream.js b/lib/internal/wrap_js_stream.js index ec966028a0..e80716059e 100644 --- a/lib/internal/wrap_js_stream.js +++ b/lib/internal/wrap_js_stream.js @@ -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; diff --git a/lib/net.js b/lib/net.js index 889f28b0aa..8c05f2c07b 100644 --- a/lib/net.js +++ b/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.', diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 7ef3dafdf9..9d9d03b0fa 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -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") \ diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 805e566bfa..e817087d97 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -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())); |