diff options
author | Dmitry Volyntsev <xeioex@nginx.com> | 2023-12-05 08:54:18 -0800 |
---|---|---|
committer | Dmitry Volyntsev <xeioex@nginx.com> | 2023-12-05 08:54:18 -0800 |
commit | 16004b37e9fee21ad8e1369023903163cf55f6a0 (patch) | |
tree | 9a3a3ebead2d2bd75939b52f0dd180b5bd201b12 /nginx/ngx_js.c | |
parent | 4a145c3e2d3ad910a5b85280e9c6db00ecd7a5af (diff) | |
download | njs-16004b37e9fee21ad8e1369023903163cf55f6a0.tar.gz njs-16004b37e9fee21ad8e1369023903163cf55f6a0.zip |
Refactored asynchronous events.
To align njs with other JS engines, async events are removed from njs
core. The following functions were removed: njs_vm_add_event(),
njs_vm_del_event(), njs_vm_waiting(). Instead the host is expected
to manage async events by itself.
In addition, the posted events are renamed to jobs, to better align with
the ECMA specs. The following methods are removed: njs_vm_run().
Instead, the host is expected to call njs_vm_execute_pending_job() in a
loop to execute pending jobs. The following functions were added:
njs_vm_enqueue_job().
Diffstat (limited to 'nginx/ngx_js.c')
-rw-r--r-- | nginx/ngx_js.c | 107 |
1 files changed, 65 insertions, 42 deletions
diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 2b11c4bf..c28995ed 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -334,17 +334,57 @@ static njs_int_t ngx_js_console_proto_id; ngx_int_t -ngx_js_call(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log, +ngx_js_call(njs_vm_t *vm, njs_function_t *func, njs_value_t *args, + njs_uint_t nargs) +{ + njs_int_t ret; + ngx_str_t exception; + ngx_connection_t *c; + + ret = njs_vm_call(vm, func, args, nargs); + if (ret == NJS_ERROR) { + ngx_js_exception(vm, &exception); + + c = ngx_external_connection(vm, njs_vm_external_ptr(vm)); + + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "js exception: %V", &exception); + return NGX_ERROR; + } + + for ( ;; ) { + ret = njs_vm_execute_pending_job(vm); + if (ret <= NJS_OK) { + c = ngx_external_connection(vm, njs_vm_external_ptr(vm)); + + if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) { + ngx_js_exception(vm, &exception); + + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "js job exception: %V", &exception); + return NGX_ERROR; + } + + break; + } + } + + return NGX_OK; +} + + +ngx_int_t +ngx_js_name_call(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log, njs_opaque_value_t *args, njs_uint_t nargs) { njs_opaque_value_t unused; - return ngx_js_invoke(vm, fname, log, args, nargs, &unused); + return ngx_js_name_invoke(vm, fname, log, args, nargs, &unused); } ngx_int_t -ngx_js_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log, +ngx_js_name_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log, njs_opaque_value_t *args, njs_uint_t nargs, njs_opaque_value_t *retval) { njs_int_t ret; @@ -374,18 +414,19 @@ ngx_js_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log, return NGX_ERROR; } - ret = njs_vm_run(vm); - if (ret == NJS_ERROR) { - ngx_js_exception(vm, &exception); - - ngx_log_error(NGX_LOG_ERR, log, 0, - "js exception: %V", &exception); + for ( ;; ) { + ret = njs_vm_execute_pending_job(vm); + if (ret <= NJS_OK) { + if (ret == NJS_ERROR || njs_vm_unhandled_rejection(vm)) { + ngx_js_exception(vm, &exception); - return NGX_ERROR; - } + ngx_log_error(NGX_LOG_ERR, log, 0, + "js job exception: %V", &exception); + return NGX_ERROR; + } - if (ret == NJS_AGAIN) { - return NGX_AGAIN; + break; + } } ctx = ngx_external_ctx(vm, njs_vm_external_ptr(vm)); @@ -966,34 +1007,21 @@ not_found: static void ngx_js_timer_handler(ngx_event_t *ev) { - njs_vm_t *vm; - njs_int_t ret; - ngx_str_t exception; - ngx_js_ctx_t *ctx; - ngx_js_event_t *event; - ngx_connection_t *c; - njs_external_ptr_t external; + njs_vm_t *vm; + ngx_int_t rc; + ngx_js_ctx_t *ctx; + ngx_js_event_t *event; event = (ngx_js_event_t *) ((u_char *) ev - offsetof(ngx_js_event_t, ev)); vm = event->vm; - ret = njs_vm_call(vm, event->function, event->args, event->nargs); + rc = ngx_js_call(vm, event->function, event->args, event->nargs); - external = njs_vm_external_ptr(vm); - ctx = ngx_external_ctx(vm, external); - njs_rbtree_delete(&ctx->waiting_events, &event->node); - - if (ret == NJS_ERROR) { - ngx_js_exception(vm, &exception); - - c = ngx_external_connection(vm, njs_vm_external_ptr(vm)); - - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "js exception: %V", &exception); - } + ctx = ngx_external_ctx(vm, njs_vm_external_ptr(vm)); + ngx_js_del_event(ctx, event); - ngx_external_event_finalize(vm)(external, ret); + ngx_external_event_finalize(vm)(njs_vm_external_ptr(vm), rc); } @@ -1065,7 +1093,7 @@ njs_set_timer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, sizeof(njs_opaque_value_t) * event->nargs); } - njs_rbtree_insert(&ctx->waiting_events, &event->node); + ngx_js_add_event(ctx, event); ngx_add_timer(&event->ev, delay); @@ -1113,14 +1141,9 @@ njs_clear_timeout(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - event = (ngx_js_event_t *) ((u_char *) rb - - offsetof(ngx_js_event_t, node)); - - if (event->ev.timer_set) { - ngx_del_timer(&event->ev); - } + event = (ngx_js_event_t *) ((u_char *) rb - offsetof(ngx_js_event_t, node)); - njs_rbtree_delete(&ctx->waiting_events, (njs_rbtree_part_t *) rb); + ngx_js_del_event(ctx, event); njs_value_undefined_set(retval); |