Comparing version 0.2.2 to 0.2.3
@@ -0,1 +1,5 @@ | ||
# v0.2.3 (2016-12-22) | ||
- support for asynchronous `dispose()` method of `Disposabe` | ||
# v0.2.2 (2016-12-16) | ||
@@ -2,0 +6,0 @@ |
@@ -42,3 +42,3 @@ /* | ||
value: function dispose() { | ||
doDispose(this); | ||
return doDispose(this); | ||
} | ||
@@ -66,3 +66,3 @@ }, { | ||
LegacyDisposable.prototype.dispose = function () { | ||
doDispose(this); | ||
return doDispose(this); | ||
}; | ||
@@ -85,4 +85,5 @@ | ||
} | ||
var result = void 0; | ||
if (disposeFunction) { | ||
disposeFunction(); | ||
result = disposeFunction(); | ||
if (approxExternalMemoryUse > 0) { | ||
@@ -93,2 +94,3 @@ weak.adjustExternalMemory(-approxExternalMemoryUse); | ||
disposed = true; | ||
return result; | ||
}; | ||
@@ -110,6 +112,8 @@ weak.watch(obj, weakCallback); | ||
} | ||
var result = void 0; | ||
if (obj._dispose) { | ||
obj._dispose(); | ||
result = obj._dispose(); | ||
} | ||
obj._disposed = true; | ||
return result; | ||
} | ||
@@ -116,0 +120,0 @@ |
@@ -57,4 +57,4 @@ /* | ||
var match = void 0; | ||
if (match = rex.matchFunction(part)) { | ||
var match = rex.matchFunction(part); | ||
if (match) { | ||
if (match.isCallback) { | ||
@@ -61,0 +61,0 @@ lib.callback(part); |
@@ -0,1 +1,17 @@ | ||
/* | ||
Copyright 2016 Gábor Mező (gabor.mezo@outlook.com) | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
'use strict'; | ||
@@ -2,0 +18,0 @@ |
@@ -39,7 +39,9 @@ /* | ||
escape(asyncResult, true); | ||
end(); | ||
return asyncResult; | ||
return Promise.try(end).then(function () { | ||
return asyncResult; | ||
}); | ||
}, function (asyncError) { | ||
end(); | ||
throw asyncError; | ||
return Promise.try(end).then(function () { | ||
throw asyncError; | ||
}); | ||
}); | ||
@@ -49,3 +51,4 @@ } | ||
} | ||
end(); | ||
var endSyncResult = end(); | ||
verifyEndSyncResult(endSyncResult); | ||
return result; | ||
@@ -56,2 +59,11 @@ } catch (err) { | ||
} | ||
function verifyEndSyncResult(endSyncResult) { | ||
if (endSyncResult) { | ||
if (_.isFunction(endSyncResult.then)) { | ||
throw new Error('disposeFunction should be synchronous in a synchronous scope.'); | ||
} | ||
throw new Error('disposeFunction should not return anything in a synchronous scope.'); | ||
} | ||
} | ||
} | ||
@@ -83,2 +95,3 @@ | ||
var last = layers.pop(); | ||
var promises = null; | ||
if (last) { | ||
@@ -93,3 +106,9 @@ var _iteratorNormalCompletion = true; | ||
disposable.dispose(); | ||
var result = disposable.dispose(); | ||
if (result && _.isFunction(result.then)) { | ||
if (!promises) { | ||
promises = []; | ||
} | ||
promises.push(Promise.resolve(result)); | ||
} | ||
} | ||
@@ -111,2 +130,6 @@ } catch (err) { | ||
} | ||
if (promises) { | ||
return Promise.all(promises); | ||
} | ||
return null; | ||
} | ||
@@ -113,0 +136,0 @@ |
@@ -45,6 +45,2 @@ /* | ||
function doAsync(f) { | ||
return async(f)(); | ||
} | ||
describe('RAII scope', function () { | ||
@@ -141,71 +137,157 @@ before(function () { | ||
}); | ||
it('should throw when disposeFunction is asynchronous', function () { | ||
var disposed = false; | ||
var dispose = function dispose() { | ||
return Promise.delay(1).then(function () { | ||
return disposed = true; | ||
}); | ||
}; | ||
assert.throws(function () { | ||
scope(function () { | ||
scope(function () { | ||
assert(!disposed); | ||
var value = new Tester(dispose); | ||
assert(!disposed); | ||
return [{ value: value }, { value: value }]; | ||
}); | ||
assert(!disposed); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('async', function () { | ||
it('should propagate value to parent scope', function () { | ||
return doAsync(regeneratorRuntime.mark(function _callee3() { | ||
var disposed, dispose; | ||
return regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
disposed = false; | ||
it('should propagate value to parent scope', async(regeneratorRuntime.mark(function _callee3() { | ||
var disposed, dispose; | ||
return regeneratorRuntime.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
disposed = false; | ||
dispose = function dispose() { | ||
return disposed = true; | ||
}; | ||
dispose = function dispose() { | ||
return disposed = true; | ||
}; | ||
_context3.next = 4; | ||
return scope.async(regeneratorRuntime.mark(function _callee2() { | ||
return regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.next = 2; | ||
return scope.async(regeneratorRuntime.mark(function _callee() { | ||
var value; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
assert(!disposed); | ||
value = new Tester(dispose); | ||
_context3.next = 4; | ||
return scope.async(regeneratorRuntime.mark(function _callee2() { | ||
return regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.next = 2; | ||
return scope.async(regeneratorRuntime.mark(function _callee() { | ||
var value; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
assert(!disposed); | ||
value = new Tester(dispose); | ||
assert(!disposed); | ||
_context.next = 5; | ||
return Promise.delay(1); | ||
assert(!disposed); | ||
_context.next = 5; | ||
return Promise.delay(1); | ||
case 5: | ||
return _context.abrupt('return', value); | ||
case 5: | ||
return _context.abrupt('return', value); | ||
case 6: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
case 6: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
}, _callee, this); | ||
})); | ||
} | ||
}, _callee, this); | ||
})); | ||
case 2: | ||
assert(!disposed); | ||
case 2: | ||
assert(!disposed); | ||
case 3: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
case 3: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
}, _callee2, this); | ||
})); | ||
} | ||
}, _callee2, this); | ||
})); | ||
case 4: | ||
assert(disposed); | ||
case 4: | ||
assert(disposed); | ||
case 5: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
case 5: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
}, _callee3, this); | ||
})); | ||
}); | ||
} | ||
}, _callee3, this); | ||
}))); | ||
it('should support asynchronous dispose function', async(regeneratorRuntime.mark(function _callee6() { | ||
var counter, dispose; | ||
return regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
counter = 0; | ||
dispose = function dispose() { | ||
return Promise.delay(10).then(function () { | ||
return counter++; | ||
}); | ||
}; | ||
_context6.next = 4; | ||
return scope.async(regeneratorRuntime.mark(function _callee5() { | ||
return regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
_context5.next = 2; | ||
return scope.async(regeneratorRuntime.mark(function _callee4() { | ||
var value1, value2; | ||
return regeneratorRuntime.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
assert(!counter); | ||
value1 = new Tester(dispose); | ||
value2 = new Tester(dispose); | ||
assert(!counter); | ||
_context4.next = 6; | ||
return Promise.delay(1); | ||
case 6: | ||
return _context4.abrupt('return', value1); | ||
case 7: | ||
case 'end': | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee4, this); | ||
})); | ||
case 2: | ||
assert.equal(counter, 1); | ||
case 3: | ||
case 'end': | ||
return _context5.stop(); | ||
} | ||
} | ||
}, _callee5, this); | ||
})); | ||
case 4: | ||
assert.equal(counter, 2); | ||
case 5: | ||
case 'end': | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6, this); | ||
}))); | ||
}); | ||
@@ -212,0 +294,0 @@ |
@@ -127,2 +127,12 @@ /* | ||
it("should pass null in place of pointers", function () { | ||
lib.function({ writeString: ['void', ['char*']] }); | ||
testPassNullSync('void writeString(char* arg0)'); | ||
}); | ||
it("should fail on non pointer argument in place of pointer", function () { | ||
lib.function({ writeString: ['void', ['char*']] }); | ||
testPassNonPointerSync('void writeString(char* arg0)'); | ||
}); | ||
it('should read natvie memory', function () { | ||
@@ -168,2 +178,12 @@ lib.function({ getString: ['char*', []] }); | ||
it("should pass null in place of pointers", function () { | ||
lib.function('void writeString(char*ch)'); | ||
testPassNullSync('void writeString(char* ch)'); | ||
}); | ||
it("should fail on non pointer argument in place of pointer", function () { | ||
lib.function('void writeString(char * ch )'); | ||
testPassNonPointerSync('void writeString(char* ch)'); | ||
}); | ||
it('should read natvie memory', function () { | ||
@@ -240,2 +260,25 @@ lib.function('char *getString()'); | ||
function testPassNullSync(declaration) { | ||
var writeString = lib.interface.writeString; | ||
assert(_.isFunction(writeString)); | ||
assert(writeString.function); | ||
assert.equal(writeString.function.toString(), declaration); | ||
// should not crash: | ||
writeString(null); | ||
writeString(ref.NULL); | ||
} | ||
function testPassNonPointerSync(declaration) { | ||
var writeString = lib.interface.writeString; | ||
assert(_.isFunction(writeString)); | ||
assert(writeString.function); | ||
assert.equal(writeString.function.toString(), declaration); | ||
assert.throws(function () { | ||
writeString(42); | ||
}); | ||
assert.throws(function () { | ||
writeString(); | ||
}); | ||
} | ||
function testGetStringSync(declaration) { | ||
@@ -329,2 +372,12 @@ var getString = lib.interface.getString; | ||
it("should pass null in place of pointers", function () { | ||
lib.function({ writeString: ['void', ['char*']] }); | ||
return testPassNullAsync('void writeString(char* arg0)'); | ||
}); | ||
it("should fail on non pointer argument in place of pointer", function () { | ||
lib.function({ writeString: ['void', ['char*']] }); | ||
return testPassNonPointerAsync('void writeString(char* arg0)'); | ||
}); | ||
it('should read natvie memory', function () { | ||
@@ -370,2 +423,12 @@ lib.function({ getString: ['char*', []] }); | ||
it("should pass null in place of pointers", function () { | ||
lib.function('void writeString(char*ch)'); | ||
return testPassNullAsync('void writeString(char* ch)'); | ||
}); | ||
it("should fail on non pointer argument in place of pointer", function () { | ||
lib.function('void writeString(char * ch )'); | ||
return testPassNonPointerAsync('void writeString(char* ch)'); | ||
}); | ||
it('should read natvie memory', function () { | ||
@@ -564,4 +627,4 @@ lib.function('char *getString()'); | ||
var testGetStringAsync = async(regeneratorRuntime.mark(function _callee5(declaration) { | ||
var getString, string; | ||
var testPassNullAsync = async(regeneratorRuntime.mark(function _callee5(declaration) { | ||
var writeString; | ||
return regeneratorRuntime.wrap(function _callee5$(_context5) { | ||
@@ -571,2 +634,75 @@ while (1) { | ||
case 0: | ||
writeString = lib.interface.writeString; | ||
assert(_.isFunction(writeString)); | ||
assert(writeString.function); | ||
assert.equal(writeString.function.toString(), declaration); | ||
// should not crash: | ||
_context5.next = 6; | ||
return writeString(null); | ||
case 6: | ||
_context5.next = 8; | ||
return writeString(ref.NULL); | ||
case 8: | ||
case 'end': | ||
return _context5.stop(); | ||
} | ||
} | ||
}, _callee5, this); | ||
})); | ||
var testPassNonPointerAsync = async(regeneratorRuntime.mark(function _callee6(declaration) { | ||
var writeString; | ||
return regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
writeString = lib.interface.writeString; | ||
assert(_.isFunction(writeString)); | ||
assert(writeString.function); | ||
assert.equal(writeString.function.toString(), declaration); | ||
_context6.prev = 4; | ||
_context6.next = 7; | ||
return writeString(42); | ||
case 7: | ||
assert(false); | ||
_context6.next = 12; | ||
break; | ||
case 10: | ||
_context6.prev = 10; | ||
_context6.t0 = _context6['catch'](4); | ||
case 12: | ||
_context6.prev = 12; | ||
_context6.next = 15; | ||
return writeString(); | ||
case 15: | ||
assert(false); | ||
_context6.next = 20; | ||
break; | ||
case 18: | ||
_context6.prev = 18; | ||
_context6.t1 = _context6['catch'](12); | ||
case 20: | ||
case 'end': | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee6, this, [[4, 10], [12, 18]]); | ||
})); | ||
var testGetStringAsync = async(regeneratorRuntime.mark(function _callee7(declaration) { | ||
var getString, string; | ||
return regeneratorRuntime.wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
getString = lib.interface.getString; | ||
@@ -576,7 +712,7 @@ | ||
assert.equal(getString.function.toString(), declaration); | ||
_context5.next = 5; | ||
_context7.next = 5; | ||
return getString(); | ||
case 5: | ||
string = _context5.sent; | ||
string = _context7.sent; | ||
@@ -591,14 +727,14 @@ assert(_.isBuffer(string)); | ||
case 'end': | ||
return _context5.stop(); | ||
return _context7.stop(); | ||
} | ||
} | ||
}, _callee5, this); | ||
}, _callee7, this); | ||
})); | ||
// void getNumbers(double** nums, size_t* size) | ||
var testGetNumbersAsync = async(regeneratorRuntime.mark(function _callee6(declaration) { | ||
var testGetNumbersAsync = async(regeneratorRuntime.mark(function _callee8(declaration) { | ||
var getNumbers, double, doublePtrType, doublePtrPtr, sizeTPtr, size, doublePtr, first; | ||
return regeneratorRuntime.wrap(function _callee6$(_context6) { | ||
return regeneratorRuntime.wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
@@ -614,3 +750,3 @@ getNumbers = lib.interface.getNumbers; | ||
sizeTPtr = ref.alloc('size_t'); | ||
_context6.next = 9; | ||
_context8.next = 9; | ||
return getNumbers(doublePtrPtr, sizeTPtr); | ||
@@ -635,13 +771,13 @@ | ||
case 'end': | ||
return _context6.stop(); | ||
return _context8.stop(); | ||
} | ||
} | ||
}, _callee6, this); | ||
}, _callee8, this); | ||
})); | ||
var testMakeIntAsync = async(regeneratorRuntime.mark(function _callee7(callbackDecl, funcDecl) { | ||
var testMakeIntAsync = async(regeneratorRuntime.mark(function _callee9(callbackDecl, funcDecl) { | ||
var TMakeIntFunc, makeInt, predeclaredCallback, result; | ||
return regeneratorRuntime.wrap(function _callee7$(_context7) { | ||
return regeneratorRuntime.wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
@@ -662,7 +798,7 @@ TMakeIntFunc = lib.interface.TMakeIntFunc; | ||
}); | ||
_context7.next = 10; | ||
_context9.next = 10; | ||
return makeInt(1.1, 2.2, predeclaredCallback); | ||
case 10: | ||
result = _context7.sent; | ||
result = _context9.sent; | ||
@@ -673,6 +809,6 @@ assert.equal(result, Math.floor((1.1 + 2.2) * 2)); | ||
case 'end': | ||
return _context7.stop(); | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee7, this); | ||
}, _callee9, this); | ||
})); | ||
@@ -679,0 +815,0 @@ }); |
@@ -33,3 +33,3 @@ /* | ||
dispose() { | ||
doDispose(this); | ||
return doDispose(this); | ||
} | ||
@@ -53,3 +53,3 @@ | ||
LegacyDisposable.prototype.dispose = function () { | ||
doDispose(this); | ||
return doDispose(this); | ||
}; | ||
@@ -70,4 +70,5 @@ | ||
} | ||
let result; | ||
if (disposeFunction) { | ||
disposeFunction(); | ||
result = disposeFunction(); | ||
if (approxExternalMemoryUse > 0) { | ||
@@ -78,2 +79,3 @@ weak.adjustExternalMemory(-approxExternalMemoryUse); | ||
disposed = true; | ||
return result; | ||
}; | ||
@@ -98,8 +100,10 @@ weak.watch(obj, weakCallback); | ||
} | ||
let result; | ||
if (obj._dispose) { | ||
obj._dispose(); | ||
result = obj._dispose(); | ||
} | ||
obj._disposed = true; | ||
return result; | ||
} | ||
module.exports = scope.Disposable = Disposable; |
@@ -131,3 +131,3 @@ /* | ||
setter.func(specPtrDef.makePtr(value)); | ||
} | ||
}; | ||
} | ||
@@ -137,3 +137,3 @@ else if (refHelpers.isArrayType(setter.type)) { | ||
setter.func(FastFunction._makeArrayPtr(value)); | ||
} | ||
}; | ||
} | ||
@@ -143,3 +143,3 @@ else if (refHelpers.isFunctionType(setter.type)) { | ||
setter.func(fn._makeCallbackPtr(value)); | ||
} | ||
}; | ||
} | ||
@@ -149,3 +149,3 @@ else if (refHelpers.isStringType(setter.type)) { | ||
setter.func(fn._makeStringPtr(value)); | ||
} | ||
}; | ||
} | ||
@@ -227,3 +227,3 @@ else { | ||
setter.func(ptr); | ||
} | ||
}; | ||
} | ||
@@ -235,3 +235,3 @@ else if (refHelpers.isArrayType(setter.type)) { | ||
setter.func(ptr); | ||
} | ||
}; | ||
} | ||
@@ -243,3 +243,3 @@ else if (refHelpers.isFunctionType(setter.type)) { | ||
setter.func(ptr); | ||
} | ||
}; | ||
} | ||
@@ -251,3 +251,3 @@ else if (refHelpers.isStringType(setter.type)) { | ||
setter.func(ptr); | ||
} | ||
}; | ||
} | ||
@@ -258,3 +258,3 @@ else { | ||
setter.func(value); | ||
} | ||
}; | ||
} | ||
@@ -342,3 +342,3 @@ } | ||
}); | ||
} | ||
}; | ||
} | ||
@@ -355,3 +355,3 @@ | ||
return result; | ||
} | ||
}; | ||
} | ||
@@ -358,0 +358,0 @@ |
@@ -76,6 +76,6 @@ /* | ||
})); | ||
return { | ||
resultType, | ||
name: match.name, | ||
args | ||
return { | ||
resultType, | ||
name: match.name, | ||
args | ||
}; | ||
@@ -82,0 +82,0 @@ } |
@@ -87,3 +87,2 @@ /* | ||
a&&ert(this._mutex instanceof Buffer); | ||
} | ||
@@ -90,0 +89,0 @@ this._initialized = true; |
@@ -41,4 +41,4 @@ /* | ||
for (const part of splitter.split(str)) { | ||
let match; | ||
if (match = rex.matchFunction(part)) { | ||
const match = rex.matchFunction(part); | ||
if (match) { | ||
if (match.isCallback) { | ||
@@ -57,3 +57,3 @@ lib.callback(part); | ||
} | ||
else if (rex.matchArrayDeclaration(part)){ | ||
else if (rex.matchArrayDeclaration(part)) { | ||
lib.array(part); | ||
@@ -60,0 +60,0 @@ } |
@@ -0,1 +1,17 @@ | ||
/* | ||
Copyright 2016 Gábor Mező (gabor.mezo@outlook.com) | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
'use strict'; | ||
@@ -13,3 +29,3 @@ const ref = require('./ref-libs/ref'); | ||
const _type = ref.coerceType(type); | ||
return _type.indirection > 1 || | ||
return _type.indirection > 1 || | ||
_type.name === 'ArrayType' || | ||
@@ -16,0 +32,0 @@ _type.name === 'Function' || |
@@ -82,3 +82,3 @@ /* | ||
else { | ||
parsed = this._parseFields(def, typeHint); | ||
parsed = this._parseFields(def, typeHint); | ||
} | ||
@@ -136,5 +136,5 @@ const { type, body } = this._makeType(factoryType, parsed.defBody); | ||
} | ||
return { | ||
name: match.name, | ||
defBody | ||
return { | ||
name: match.name, | ||
defBody | ||
}; | ||
@@ -141,0 +141,0 @@ } |
@@ -58,3 +58,3 @@ /* | ||
return null; | ||
} | ||
}; | ||
@@ -77,3 +77,3 @@ const BEGIN_FIELDS = '^\\s*'; | ||
return null; | ||
} | ||
}; | ||
@@ -93,3 +93,3 @@ const ARRAY_DECL = /^\s*([\w_][\w\d_]*[\s\*]*)\s*\[\s*\]\s*([\w_][\w\d_]*)\s*$/; | ||
return null; | ||
} | ||
}; | ||
@@ -110,2 +110,2 @@ const TYPE = /(([\w_][\w\d_]*)\s*(?:\[\s*(\d+)\s*\])?)([\s\*]*)/; | ||
return null; | ||
} | ||
}; |
@@ -37,8 +37,9 @@ /* | ||
escape(asyncResult, true); | ||
end(); | ||
return asyncResult; | ||
return Promise.try(end).then(() => asyncResult); | ||
}, | ||
function (asyncError) { | ||
end(); | ||
throw asyncError; | ||
return Promise.try(end) | ||
.then(() => { | ||
throw asyncError; | ||
}); | ||
}); | ||
@@ -48,3 +49,4 @@ } | ||
} | ||
end(); | ||
const endSyncResult = end(); | ||
verifyEndSyncResult(endSyncResult); | ||
return result; | ||
@@ -56,2 +58,11 @@ } | ||
} | ||
function verifyEndSyncResult(endSyncResult) { | ||
if (endSyncResult) { | ||
if (_.isFunction(endSyncResult.then)) { | ||
throw new Error('disposeFunction should be synchronous in a synchronous scope.'); | ||
} | ||
throw new Error('disposeFunction should not return anything in a synchronous scope.'); | ||
} | ||
} | ||
} | ||
@@ -83,7 +94,18 @@ | ||
const last = layers.pop(); | ||
let promises = null; | ||
if (last) { | ||
for (let disposable of last.values()) { | ||
disposable.dispose(); | ||
const result = disposable.dispose(); | ||
if (result && _.isFunction(result.then)) { | ||
if (!promises) { | ||
promises = []; | ||
} | ||
promises.push(Promise.resolve(result)); | ||
} | ||
} | ||
} | ||
if (promises) { | ||
return Promise.all(promises); | ||
} | ||
return null; | ||
} | ||
@@ -90,0 +112,0 @@ |
@@ -52,3 +52,3 @@ /* | ||
blockCounters[blockBegin] = (blockCounters[blockBegin] || 0) - 1; | ||
} | ||
} | ||
else if (chr === ';' && _(blockCounters).values().sum() === 0) { | ||
@@ -55,0 +55,0 @@ push(); |
@@ -21,3 +21,3 @@ /* | ||
const ref = require('./ref-libs/ref'); | ||
const refHelpers = require('./refHelpers'); | ||
const refHelpers = require('./refHelpers'); | ||
@@ -24,0 +24,0 @@ exports.getForType = getForType; |
{ | ||
"name": "fastcall", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "fastcall - Very fast, asynchronous, dyncall based foreign function interface library for Node.js", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
@@ -710,5 +710,5 @@ # TOC | ||
- `disposeFunction`: could be null or a function. If null, then `Disposable` doesn't dispose anything. If a function, then it should release your object's native resources. Please note that this function has no parameters, and only allowed to capture native handles from the source object, not a reference of the source itself because that would prevent garbage collection! More on this later, please keep reading! | ||
- `disposeFunction`: could be null or a function. If null, then `Disposable` doesn't dispose anything. If a function, then it should release your object's native resources. **It could be asynchronous**, and should return a Promise on that case (any *thenable* object will do). Please note that this function has no parameters, and only allowed to capture native handles from the source object, not a reference of the source itself because that would prevent garbage collection! More on this later, please keep reading! | ||
- `aproxAllocatedMemory`: in bytes. You could inform Node.js' GC about your object's native memory usage (calls [Nan::AdjustExternalMemory()](https://github.com/nodejs/nan/blob/master/doc/v8_internals.md#api_nan_adjust_external_memory)). Will get considered only if it's a positive number. | ||
- `dispose()`: will invoke `disposeFunction` manually (for the mentioned try ... catch use cases). Subsequent calls does nothing. You can override this method for implementing custom disposing logic, just don't forget to call its prototype's dispose() if you passed a `disposeFunction` to `super`. | ||
- `dispose()`: will invoke `disposeFunction` manually (for the mentioned try ... catch use cases). Subsequent calls does nothing. You can override this method for implementing custom disposing logic, just don't forget to call its prototype's `dispose()` if you passed a `disposeFunction` to `super`. If `disposeFunction` is asynchronous then `dipsose()` should be asynchronous too by returning a Promise (or any *thenable* object). | ||
- `resetDisposable(...)`: reinitializes the dispose function and the allocated memory of the given `Disposable`. You should call this, when the underlying handle changed. *WARNING*: the original `disposeFunction` is not called implicitly by this method. You can rely on garbage collector to clean it up, or you can call `dispose()` explicitly prior calling of this method. | ||
@@ -715,0 +715,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
4027274
913
18457
22