-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
Begin AsyncWrap maintenance #3139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -221,6 +221,13 @@ inline Environment::Environment(v8::Local<v8::Context> context, | |
set_as_external(v8::External::New(isolate(), this)); | ||
set_binding_cache_object(v8::Object::New(isolate())); | ||
set_module_load_list_array(v8::Array::New(isolate())); | ||
|
||
v8::Local<v8::FunctionTemplate> fn_t = v8::FunctionTemplate::New(isolate()); | ||
fn_t->SetClassName(FIXED_ONE_BYTE_STRING(isolate(), "InternalFieldObject")); | ||
v8::Local<v8::ObjectTemplate> obj_t = fn_t->InstanceTemplate(); | ||
obj_t->SetInternalFieldCount(1); | ||
set_generic_internal_field_template(obj_t); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mild cognitive dissonance here, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgot that convention. Was using it as shorthand for template. Will change. |
||
|
||
RB_INIT(&cares_task_list_); | ||
handle_cleanup_waiting_ = 0; | ||
} | ||
|
@@ -513,6 +520,12 @@ inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that, | |
function->SetName(name_string); // NODE_SET_METHOD() compatibility. | ||
} | ||
|
||
inline v8::Local<v8::Object> Environment::NewInternalFieldObject() { | ||
v8::MaybeLocal<v8::Object> m_obj = | ||
generic_internal_field_template()->NewInstance(this->context()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope it's not. Must not have mentally context switched from JS. |
||
return m_obj.ToLocalChecked(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought we need to check if the MayBe objects are empty before using them. What does ToLocalChecked do? Couldn't find much info on v8 docs. Edit: I guess it internally checks if it is empty and returns the Local object. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It aborts if an empty object is returned. There's no point in checking before because there's no recourse if it is. |
||
} | ||
|
||
#define V(PropertyName, StringValue) \ | ||
inline \ | ||
v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const crypto = require('crypto'); | ||
const dgram = require('dgram'); | ||
const dns = require('dns'); | ||
const fs = require('fs'); | ||
const net = require('net'); | ||
const tls = require('tls'); | ||
const zlib = require('zlib'); | ||
const ChildProcess = require('child_process').ChildProcess; | ||
const StreamWrap = require('_stream_wrap').StreamWrap; | ||
const async_wrap = process.binding('async_wrap'); | ||
const pkeys = Object.keys(async_wrap.Providers); | ||
|
||
const keyList = pkeys.slice(); | ||
// Drop NONE | ||
keyList.splice(0, 1); | ||
|
||
|
||
function init(id) { | ||
const idx = keyList.indexOf(pkeys[id]); | ||
if (idx === -1) | ||
return; | ||
keyList.splice(idx, 1); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd simplify this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm fine with the change, but also curious why you find it preferable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, I don't understand this change. it does a numeric comparison against a string comparison. For it to work similarly to how it should work before the change would have to be: function init(id) {
keyList = keyList.filter(e => e != pkeys[id]);
} Though still curious to why this approach is preferred. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The functional approach is generally easier to read than the imperative one, IMO. |
||
|
||
function noop() { } | ||
|
||
async_wrap.setupHooks(init, noop, noop); | ||
|
||
async_wrap.enable(); | ||
|
||
|
||
setTimeout(function() { }); | ||
|
||
fs.stat(__filename, noop); | ||
fs.watchFile(__filename, noop); | ||
fs.unwatchFile(__filename); | ||
fs.watch(__filename).close(); | ||
|
||
dns.lookup('localhost', noop); | ||
dns.lookupService('::', 0, noop); | ||
dns.resolve('localhost', noop); | ||
|
||
new StreamWrap(new net.Socket()); | ||
|
||
new (process.binding('tty_wrap').TTY)(); | ||
|
||
crypto.randomBytes(1, noop); | ||
|
||
try { | ||
fs.unlinkSync(common.PIPE); | ||
} catch(e) { } | ||
|
||
net.createServer(function(c) { | ||
c.end(); | ||
this.close(); | ||
}).listen(common.PIPE, function() { | ||
net.connect(common.PIPE, noop); | ||
}); | ||
|
||
net.createServer(function(c) { | ||
c.end(); | ||
this.close(checkTLS); | ||
}).listen(common.PORT, function() { | ||
net.connect(common.PORT, noop); | ||
}); | ||
|
||
dgram.createSocket('udp4').bind(common.PORT, function() { | ||
this.send(new Buffer(2), 0, 2, common.PORT, '::', () => { | ||
this.close(); | ||
}); | ||
}); | ||
|
||
process.on('SIGINT', () => process.exit()); | ||
|
||
// Run from closed net server above. | ||
function checkTLS() { | ||
let options = { | ||
key: fs.readFileSync(common.fixturesDir + '/keys/ec-key.pem'), | ||
cert: fs.readFileSync(common.fixturesDir + '/keys/ec-cert.pem') | ||
}; | ||
let server = tls.createServer(options, noop).listen(common.PORT, function() { | ||
tls.connect(common.PORT, { rejectUnauthorized: false }, function() { | ||
this.destroy(); | ||
server.close(); | ||
}); | ||
}); | ||
} | ||
|
||
zlib.createGzip(); | ||
|
||
new ChildProcess(); | ||
|
||
process.on('exit', function() { | ||
if (keyList.length !== 0) { | ||
process._rawDebug('Not all keys have been used:'); | ||
process._rawDebug(keyList); | ||
assert.equal(keyList.length, 0); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two will throw errors. Doesn't it make it major change? If this is an internal function, do we really need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't throw an error. It aborts. The first couldn't have happened anyway because of how the function signature works. It's there as a sanity check for future development. The latter should never have been happening as it would have caused issues when iterating the heap.