[njs] Introduced njs.on('exit') callback support.

Dmitry Volyntsev xeioex at nginx.com
Sat Mar 6 12:48:51 UTC 2021


details:   https://hg.nginx.org/njs/rev/84af87035c4e
branches:  
changeset: 1617:84af87035c4e
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Sat Mar 06 12:42:30 2021 +0000
description:
Introduced njs.on('exit') callback support.

diffstat:

 src/njs_builtin.c        |  67 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/njs_vm.c             |   4 ++
 src/njs_vm.h             |   8 +++++
 src/test/njs_unit_test.c |  17 ++++++++++++
 4 files changed, 94 insertions(+), 2 deletions(-)

diffs (157 lines):

diff -r 52ddc3a050be -r 84af87035c4e src/njs_builtin.c
--- a/src/njs_builtin.c	Wed Mar 03 18:28:00 2021 +0000
+++ b/src/njs_builtin.c	Sat Mar 06 12:42:30 2021 +0000
@@ -851,7 +851,7 @@ found:
 
 
 static njs_int_t
-njs_dump_value(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+njs_ext_dump(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
     uint32_t     n;
@@ -878,6 +878,62 @@ njs_dump_value(njs_vm_t *vm, njs_value_t
 
 
 static njs_int_t
+njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_index_t unused)
+{
+    njs_str_t    type;
+    njs_uint_t   i, n;
+    njs_value_t  *value;
+
+    static const struct {
+        njs_str_t   name;
+        njs_uint_t  id;
+    } hooks[] = {
+        {
+            njs_str("exit"),
+            NJS_HOOK_EXIT
+        },
+    };
+
+    value = njs_arg(args, nargs, 1);
+
+    if (njs_slow_path(!njs_is_string(value))) {
+        njs_type_error(vm, "hook type is not a string");
+        return NJS_ERROR;
+    }
+
+    njs_string_get(value, &type);
+
+    i = 0;
+    n = sizeof(hooks) / sizeof(hooks[0]);
+
+    while (i < n) {
+        if (njs_strstr_eq(&type, &hooks[i].name)) {
+            break;
+        }
+
+        i++;
+    }
+
+    if (i == n) {
+        njs_type_error(vm, "unknown hook type \"%V\"", &type);
+        return NJS_ERROR;
+    }
+
+    value = njs_arg(args, nargs, 2);
+
+    if (njs_slow_path(!njs_is_function(value) && !njs_is_null(value))) {
+        njs_type_error(vm, "callback is not a function or null");
+        return NJS_ERROR;
+    }
+
+    vm->hooks[i] = njs_is_function(value) ? njs_function(value) : NULL;
+
+    return NJS_OK;
+}
+
+
+static njs_int_t
 njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *global, njs_value_t *setval, njs_value_t *retval)
 {
@@ -1629,7 +1685,14 @@ static const njs_object_prop_t  njs_njs_
     {
         .type = NJS_PROPERTY,
         .name = njs_string("dump"),
-        .value = njs_native_function(njs_dump_value, 0),
+        .value = njs_native_function(njs_ext_dump, 0),
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY,
+        .name = njs_string("on"),
+        .value = njs_native_function(njs_ext_on, 0),
         .configurable = 1,
     },
 };
diff -r 52ddc3a050be -r 84af87035c4e src/njs_vm.c
--- a/src/njs_vm.c	Wed Mar 03 18:28:00 2021 +0000
+++ b/src/njs_vm.c	Sat Mar 06 12:42:30 2021 +0000
@@ -91,6 +91,10 @@ njs_vm_destroy(njs_vm_t *vm)
     njs_event_t        *event;
     njs_lvlhsh_each_t  lhe;
 
+    if (vm->hooks[NJS_HOOK_EXIT] != NULL) {
+        (void) njs_vm_call(vm, vm->hooks[NJS_HOOK_EXIT], NULL, 0);
+    }
+
     if (njs_waiting_events(vm)) {
         njs_lvlhsh_each_init(&lhe, &njs_event_hash_proto);
 
diff -r 52ddc3a050be -r 84af87035c4e src/njs_vm.h
--- a/src/njs_vm.h	Wed Mar 03 18:28:00 2021 +0000
+++ b/src/njs_vm.h	Sat Mar 06 12:42:30 2021 +0000
@@ -175,6 +175,12 @@ enum njs_object_e {
       + njs_scope_offset(index)))
 
 
+enum njs_hook_e {
+    NJS_HOOK_EXIT = 0,
+    NJS_HOOK_MAX
+};
+
+
 struct njs_vm_s {
     /* njs_vm_t must be aligned to njs_value_t due to scratch value. */
     njs_value_t              retval;
@@ -210,6 +216,8 @@ struct njs_vm_s {
     njs_object_prototype_t   prototypes[NJS_OBJ_TYPE_MAX];
     njs_function_t           constructors[NJS_OBJ_TYPE_MAX];
 
+    njs_function_t           *hooks[NJS_HOOK_MAX];
+
     njs_mp_t                 *mem_pool;
 
     u_char                   *start;
diff -r 52ddc3a050be -r 84af87035c4e src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Mar 03 18:28:00 2021 +0000
+++ b/src/test/njs_unit_test.c	Sat Mar 06 12:42:30 2021 +0000
@@ -17197,6 +17197,23 @@ static njs_unit_test_t  njs_test[] =
               "decodeURI.name = 'XXX'; njs.dump(decodeURI)"),
       njs_str("[Function: XXX]") },
 
+    /* njs.on(). */
+
+    { njs_str("njs.on(decodeURI)"),
+      njs_str("TypeError: hook type is not a string") },
+
+    { njs_str("njs.on('xxx')"),
+      njs_str("TypeError: unknown hook type \"xxx\"") },
+
+    { njs_str("njs.on('exit')"),
+      njs_str("TypeError: callback is not a function or null") },
+
+    { njs_str("njs.on('exit', null); 1"),
+      njs_str("1") },
+
+    { njs_str("njs.on('exit', ()=>{}); 1"),
+      njs_str("1") },
+
     /* Built-in methods name. */
 
     { njs_str(


More information about the nginx-devel mailing list