1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-10 13:23:41 +00:00

1. Merged GC optimization for promise.js

2. Fixed crash that can occur if dgram is GC'ed during event dispatch
3. Fixed compiler warning in ILibWebClient.c
4. Updated GC for dhcp.js
This commit is contained in:
Bryan Roe
2021-07-17 11:32:25 -07:00
parent 980005b40b
commit c7a4356dac
5 changed files with 152 additions and 96 deletions

View File

@@ -103,8 +103,9 @@ void ILibDuktape_Dgram_Socket_OnData(ILibAsyncUDPSocket_SocketModule socketModul
duk_push_int(ptrs->ctx, bufferLength);
duk_put_prop_string(ptrs->ctx, -2, "size");
duk_context *X = ptrs->ctx;
if (duk_pcall_method(ptrs->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "dgram.message() dispatch error"); }
duk_pop(ptrs->ctx); // ...
duk_pop(X); // ...
}
}
void ILibDuktape_Dgram_Socket_OnSendOK(ILibAsyncUDPSocket_SocketModule socketModule, void *user1, void *user2)

File diff suppressed because one or more lines are too long

View File

@@ -2328,8 +2328,8 @@ void ILibWebClient_PreProcess(void* WebClientModule, fd_set *readset, fd_set *wr
NULL,
wcdo->proxy_remoteHostAndPort,
(struct sockaddr*)&wcdo->proxy,
wcdo->proxy_username[0]==NULL?NULL:wcdo->proxy_username,
wcdo->proxy_password[0]==NULL?NULL:wcdo->proxy_password,
wcdo->proxy_username[0]==0?NULL:wcdo->proxy_username,
wcdo->proxy_password[0]==0?NULL:wcdo->proxy_password,
ILibWebClient_OnInterrupt,
wcdo);
}

View File

@@ -193,9 +193,7 @@ function createPacket(messageType, data)
function raw(localAddress, port, buffer, handler)
{
var ret = new promise(promise_default);
ret.handler = handler;
ret.socket = require('dgram').createSocket({ type: 'udp4' });
ret.socket.promise = ret;
try
{
ret.socket.bind({ address: localAddress, port: (port != null && port != 0) ? port : null });
@@ -205,6 +203,7 @@ function raw(localAddress, port, buffer, handler)
ret._rej('Unable to bind to ' + localAddress);
return (ret);
}
ret.socket.setBroadcast(true);
ret.socket.setMulticastInterface(localAddress);
ret.socket.setMulticastTTL(1);
@@ -213,6 +212,7 @@ function raw(localAddress, port, buffer, handler)
ret.socket.send(buffer, 67, '255.255.255.255');
return (ret);
}
function info(interfaceName, port)
{
var f = require('os').networkInterfaces();
@@ -226,18 +226,23 @@ function info(interfaceName, port)
try
{
var b = createPacket(8, { ciaddress: f[interfaceName][i].address, chaddress: f[interfaceName][i].mac });
var p = raw(f[interfaceName][i].address, port, b, function infoHandler(msg)
_hide(raw(f[interfaceName][i].address, port, b, function infoHandler(msg)
{
var res = parseDHCP(msg);
if (res.chaddr.toUpperCase() == this.hwaddr.toUpperCase() && res.options != null && res.options.lease != null)
{
clearTimeout(this.timeout);
setImmediate(function (s) { s.removeAllListeners('message'); }, this.socket); // Works around bug in older dgram.js
this._res(res);
}
});
p.hwaddr = f[interfaceName][i].mac;
p.timeout = setTimeout(function (x) { x._rej('timeout'); }, 2000, p);
return (p);
}));
_hide().hwaddr = f[interfaceName][i].mac;
_hide().timeout = setTimeout(function (x)
{
x.socket.removeAllListeners('message');
x._rej('timeout');
}, 2000, _hide());
return (_hide(true));
}
catch(e)
{

View File

@@ -16,6 +16,12 @@ limitations under the License.
var refTable = {};
function promiseInitializer(r,j)
{
this._res = r;
this._rej = j;
}
function getRootPromise(obj)
{
while(obj.parentPromise)
@@ -25,39 +31,39 @@ function getRootPromise(obj)
return (obj);
}
function event_switcher_helper(desired_callee, target, forward)
{
this._ObjectID = 'event_switcher';
this.func = function func()
{
var args = [];
if (func.forward != null) { args.push(func.forward); }
for(var i in arguments)
{
args.push(arguments[i]);
}
return (func.target.apply(func.desired, args));
};
this.func.desired = desired_callee;
this.func.target = target;
this.func.forward = forward;
this.func.self = this;
}
function event_switcher(desired_callee, target)
{
return (new event_switcher_helper(desired_callee, target));
return ({ _ObjectID: 'event_switcher', func: target.bind(desired_callee) });
}
function event_forwarder(sourceObj, sourceName, targetObj, targetName)
{
sourceObj.on(sourceName, (new event_switcher_helper(targetObj, targetObj.emit, targetName)).func);
sourceObj.on(sourceName, targetObj.emit.bind(targetObj));
}
function return_resolved()
{
var parms = ['resolved'];
for (var ai in arguments)
{
parms.push(arguments[ai]);
}
this._XSLF.emit.apply(this._XSLF, parms);
}
function return_rejected()
{
this._XSLF.promise.__childPromise._rej(e);
}
function emitreject(a)
{
process.emit('uncaughtException', 'promise.uncaughtRejection: ' + JSON.stringify(a));
}
function Promise(promiseFunc)
{
this._ObjectID = 'promise';
this.promise = this;
this._internal = { _ObjectID: 'promise.internal', promise: this, func: promiseFunc, completed: false, errors: false, completedArgs: [], internalCount: 0, _up: null };
this._internal = { _ObjectID: 'promise.internal', promise: this, completed: false, errors: false, completedArgs: [], internalCount: 0, _up: null };
require('events').EventEmitter.call(this._internal);
Object.defineProperty(this, "parentPromise",
{
@@ -76,10 +82,22 @@ function Promise(promiseFunc)
this._up = value;
}
});
this._internal.on('newListener', function (eventName, eventCallback)
Object.defineProperty(this, "descriptorMetadata",
{
get: function ()
{
return (require('events').getProperty.call(this._internal, '?_FinalizerDebugMessage'));
},
set: function (value)
{
require('events').setProperty.call(this._internal, '?_FinalizerDebugMessage', value);
}
});
this._internal.on('~', function ()
{
this.completedArgs = [];
});
this._internal.on('newListener2', (function (eventName, eventCallback)
{
//console.log('newListener', eventName, 'errors/' + this.errors + ' completed/' + this.completed);
var r = null;
@@ -91,9 +109,12 @@ function Promise(promiseFunc)
{
this.emit_returnValue('resolved', r);
}
this.removeAllListeners('resolved');
this.removeAllListeners('rejected');
}
if (eventName == 'rejected' && (eventCallback.internal == null || eventCallback.internal == false))
//if (eventName == 'rejected' && (eventCallback.internal == null || eventCallback.internal == false))
if (eventName == 'rejected')
{
var rp = getRootPromise(this.promise);
rp._internal.external = true;
@@ -112,101 +133,100 @@ function Promise(promiseFunc)
if (eventName == 'rejected' && this.errors && this.completed)
{
eventCallback.apply(this, this.completedArgs);
this.removeAllListeners('resolved');
this.removeAllListeners('rejected');
}
if (eventName == 'settled' && this.completed)
{
eventCallback.apply(this, []);
}
});
}).internal);
this._internal.resolver = function _resolver()
{
if (_resolver._self.completed) { return; }
_resolver._self.errors = false;
_resolver._self.completed = true;
_resolver._self.completedArgs = [];
if (this.completed) { return; }
this.errors = false;
this.completed = true;
this.completedArgs = [];
var args = ['resolved'];
if (this.emit_returnValue && this.emit_returnValue('resolved') != null)
{
_resolver._self.completedArgs.push(this.emit_returnValue('resolved'));
this.completedArgs.push(this.emit_returnValue('resolved'));
args.push(this.emit_returnValue('resolved'));
}
else
{
for (var a in arguments)
{
_resolver._self.completedArgs.push(arguments[a]);
this.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
}
if (args.length == 2 && args[1]!=null && typeof(args[1]) == 'object' && args[1]._ObjectID == 'promise')
{
var pr = getRootPromise(_resolver._self.promise);
args[1]._XSLF = _resolver._self;
args[1].then(function _returnResolved()
{
var parms = ['resolved'];
for (var ai in arguments)
{
parms.push(arguments[ai]);
}
this._XSLF.emit.apply(this._XSLF, parms);
},
function _returnRejected(e)
{
this._XSLF.promise.__childPromise._rej(e);
});
var pr = getRootPromise(this.promise);
args[1]._XSLF = this;
args[1].then(return_resolved, return_rejected);
}
else
{
_resolver._self.emit.apply(_resolver._self, args);
_resolver._self.emit('settled');
this.emit.apply(this, args);
this.emit('settled');
}
};
this._internal.rejector = function _rejector()
{
if (_rejector._self.completed) { return; }
_rejector._self.errors = true;
_rejector._self.completed = true;
_rejector._self.completedArgs = [];
if (this.completed) { return; }
this.errors = true;
this.completed = true;
this.completedArgs = [];
var args = ['rejected'];
for (var a in arguments)
{
_rejector._self.completedArgs.push(arguments[a]);
this.completedArgs.push(arguments[a]);
args.push(arguments[a]);
}
var r = getRootPromise(_rejector._self.promise);
var r = getRootPromise(this.promise);
if ((r._internal.external == null || r._internal.external == false) && r._internal.uncaught == null)
{
r._internal.uncaught = setImmediate(function (a)
{
process.emit('uncaughtException', 'promise.uncaughtRejection: ' + JSON.stringify(a));
}, arguments[0]);
r._internal.uncaught = setImmediate(emitreject, arguments[0]);
}
_rejector._self.emit.apply(_rejector._self, args);
_rejector._self.emit('settled');
this.emit.apply(this, args);
this.emit('settled');
};
this._internal.rejector.internal = true;
this.catch = function(func)
{
var rt = getRootPromise(this);
this._internal.once('rejected', event_switcher(this, func).func);
if (rt._internal.uncaught != null) { clearImmediate(rt._internal.uncaught); }
this._internal.once('rejected', event_switcher(this, func).func.internal);
}
this.finally = function (func)
{
this._internal.once('settled', event_switcher(this, func).func);
this._internal.once('settled', event_switcher(this, func).func.internal);
};
this.then = function (resolved, rejected)
{
if (resolved) { this._internal.once('resolved', event_switcher(this, resolved).func); }
if (resolved)
{
this._internal.once('resolved', event_switcher(this, resolved).func.internal);
}
if (rejected)
{
this._internal.once('rejected', event_switcher(this, rejected).func);
if (this._internal.completed)
{
var r = getRootPromise(this);
if(r._internal.uncaught != null)
{
clearImmediate(r._internal.uncaught);
}
}
this._internal.once('rejected', event_switcher(this, rejected).func.internal);
}
var retVal = new Promise(function (r, j) { this._rej = j; });
var retVal = new Promise(promiseInitializer);
retVal.parentPromise = this;
if (this._internal.completed)
@@ -218,37 +238,35 @@ function Promise(promiseFunc)
if(rv._ObjectID == 'promise')
{
rv.parentPromise = this;
rv._internal.once('resolved', retVal._internal.resolver);
rv._internal.once('rejected', retVal._internal.rejector);
rv._internal.once('resolved', retVal._internal.resolver.bind(retVal._internal).internal);
rv._internal.once('rejected', retVal._internal.rejector.bind(retVal._internal).internal);
}
else
{
retVal._internal.resolver(rv);
retVal._internal.resolver.call(retVal._internal, rv);
}
}
else
{
this._internal.once('resolved', retVal._internal.resolver);
this._internal.once('rejected', retVal._internal.rejector);
this._internal.once('resolved', retVal._internal.resolver.bind(retVal._internal).internal);
this._internal.once('rejected', retVal._internal.rejector.bind(retVal._internal).internal);
}
}
else
{
this._internal.once('resolved', retVal._internal.resolver);
this._internal.once('rejected', retVal._internal.rejector);
this._internal.once('resolved', retVal._internal.resolver.bind(retVal._internal).internal);
this._internal.once('rejected', retVal._internal.rejector.bind(retVal._internal).internal);
}
this.__childPromise = retVal;
return (retVal);
};
this._internal.resolver._self = this._internal;
this._internal.rejector._self = this._internal;;
this.__childPromise = retVal;
return(retVal);
};
try
{
promiseFunc.call(this, this._internal.resolver, this._internal.rejector);
promiseFunc.call(this, this._internal.resolver.bind(this._internal), this._internal.rejector.bind(this._internal));
}
catch(e)
catch (e)
{
this._internal.errors = true;
this._internal.completed = true;
@@ -261,7 +279,10 @@ function Promise(promiseFunc)
{
// Save reference of this object
refTable[this._internal._hashCode()] = this._internal;
this._internal.once('settled', function () { delete refTable[this._hashCode()]; });
this._internal.once('settled', function ()
{
delete refTable[this._hashCode()];
});
}
Object.defineProperty(this, "completed", {
get: function ()
@@ -269,6 +290,19 @@ function Promise(promiseFunc)
return (this._internal.completed);
}
});
this._internal.once('settled', (function ()
{
delete this.promise._up;
delete this.promise.__childPromise;
delete this.promise.promise;
delete this._up;
delete this.__childPromise;
delete this.promise;
this.removeAllListeners('resolved');
this.removeAllListeners('rejected');
}).internal);
}
Promise.resolve = function resolve()
@@ -331,4 +365,5 @@ Promise.all = function all(promiseList)
module.exports = Promise;
module.exports.event_switcher = event_switcher;
module.exports.event_forwarder = event_forwarder;
module.exports.event_forwarder = event_forwarder;
module.exports.defaultInit = function defaultInit(res, rej) { this.resolve = res; this.reject = rej; }