aboutsummaryrefslogtreecommitdiff
path: root/nginx/ngx_js.c
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2023-12-05 08:54:18 -0800
committerDmitry Volyntsev <xeioex@nginx.com>2023-12-05 08:54:18 -0800
commit16004b37e9fee21ad8e1369023903163cf55f6a0 (patch)
tree9a3a3ebead2d2bd75939b52f0dd180b5bd201b12 /nginx/ngx_js.c
parent4a145c3e2d3ad910a5b85280e9c6db00ecd7a5af (diff)
downloadnjs-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.c107
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);