Welcome! Log In Create A New Profile

Advanced

[njs] Fixed execution of async function in synchronous context.

Dmitry Volyntsev
December 03, 2021 08:58AM
details: https://hg.nginx.org/njs/rev/ed1756875eb5
branches:
changeset: 1758:ed1756875eb5
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Fri Dec 03 13:55:22 2021 +0000
description:
Fixed execution of async function in synchronous context.

The bug was introduced in 92d10cd761e2 (0.7.0).

diffstat:

src/njs_async.c | 6 ++++++
src/test/njs_unit_test.c | 16 ++++++++++++++++
test/js/async_promise.t.js | 20 ++++++++++++++++++++
3 files changed, 42 insertions(+), 0 deletions(-)

diffs (73 lines):

diff -r cd87a113829d -r ed1756875eb5 src/njs_async.c
--- a/src/njs_async.c Fri Dec 03 13:55:12 2021 +0000
+++ b/src/njs_async.c Fri Dec 03 13:55:22 2021 +0000
@@ -37,6 +37,9 @@ njs_async_function_frame_invoke(njs_vm_t
ret = njs_function_call(vm, njs_function(&capability->resolve),
&njs_value_undefined, retval, 1, &vm->retval);

+ } else if (ret == NJS_AGAIN) {
+ ret = NJS_OK;
+
} else if (ret == NJS_ERROR) {
if (njs_is_memory_error(vm, &vm->retval)) {
return NJS_ERROR;
@@ -116,6 +119,9 @@ njs_await_fulfilled(njs_vm_t *vm, njs_va

njs_async_context_free(vm, ctx);

+ } else if (ret == NJS_AGAIN) {
+ ret = NJS_OK;
+
} else if (ret == NJS_ERROR) {
if (njs_is_memory_error(vm, &vm->retval)) {
return NJS_ERROR;
diff -r cd87a113829d -r ed1756875eb5 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Fri Dec 03 13:55:12 2021 +0000
+++ b/src/test/njs_unit_test.c Fri Dec 03 13:55:22 2021 +0000
@@ -21024,6 +21024,22 @@ static njs_unit_test_t njs_externals_te
"$r.subrequest('b')"
".then(select => cb($r, select))"),
njs_str("2") },
+
+ { njs_str("function pr(x) { return new Promise(resolve => {resolve(x + ':pr')}); };"
+ "Promise.all(['a', 'b', 'c'].map(async (v) => {"
+ " return await pr(v + ':async');"
+ "}))"
+ ".then(v => $r.retval(v))"),
+ njs_str("a:async:pr,b:async:pr,c:async:pr") },
+
+ { njs_str("function pr(x) { return new Promise(resolve => {resolve(x + ':pr')}); };"
+ "Promise.all(['a', 'b', 'c'].map(async (v) => {"
+ " let r = await pr(v + ':async');"
+ " let r2 = await pr(r + ':async2');"
+ " return r2 + ':r';"
+ "}))"
+ ".then(v => $r.retval(v))"),
+ njs_str("a:async:pr:async2:pr:r,b:async:pr:async2:pr:r,c:async:pr:async2:pr:r") },
};


diff -r cd87a113829d -r ed1756875eb5 test/js/async_promise.t.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/js/async_promise.t.js Fri Dec 03 13:55:22 2021 +0000
@@ -0,0 +1,20 @@
+/*---
+includes: [compareArray.js]
+flags: [async]
+---*/
+
+let stages = [];
+
+function pr(x) { return new Promise(resolve => {resolve(x)}); }
+
+pr(10)
+.then(async (v) => {
+ stages.push("then before");
+ let y = await pr(22);
+ stages.push(`then ${v} ${y}`);
+ return v + y;
+})
+.then(v => stages.push(`then2 ${v}`))
+.catch(e => $DONOTEVALUATE())
+.then(v => assert.compareArray(stages, ['then before', 'then 10 22', 'then2 32']))
+.then($DONE, $DONE);
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed execution of async function in synchronous context.

Dmitry Volyntsev 467 December 03, 2021 08:58AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 262
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready