From 14c00ce33ed6d2df50b2682c21e0c9a0d97a5e33 Mon Sep 17 00:00:00 2001 From: Steve Sharp Date: Sun, 28 Sep 2014 15:36:31 -0700 Subject: [PATCH 1/5] Update addons.markdown Updates addons.markdown to mention AtExit() function. Addresses issue #8324. --- doc/api/addons.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 1f0562ede2c938..0583dc19616261 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -811,3 +811,9 @@ Test it with: var result = addon.add(obj1, obj2); console.log(result); // 30 + + +### AtExit + +Lets native addons register exit hooks that run after the event loop has quit +but before the VM is killed. From a8e8fc1dc8a0e6897f29d5654870bbfabad7b631 Mon Sep 17 00:00:00 2001 From: Steve Sharp Date: Mon, 29 Sep 2014 22:20:16 -0700 Subject: [PATCH 2/5] Update addons.markdown Updated description, added arguments and arguments types, and quick code example. --- doc/api/addons.markdown | 67 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 0583dc19616261..a99e83e370e329 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -815,5 +815,68 @@ Test it with: ### AtExit -Lets native addons register exit hooks that run after the event loop has quit -but before the VM is killed. +Registers exit hooks that run after the event loop has ended, but before the +VM is killed. + +AtExit works by creating a new AtExitCallback and prepends it to the list of +functions to be run at exit, i.e., callbacks are run in reverse order of +registration. AtExit takes a callback and arguments to the AtExitCallback as +arguments. + + void AtExit(void (*cb)(void* arg), void* arg) { + AtExitCallback* p = new AtExitCallback; + p->cb_ = cb; + p->arg_ = arg; + p->next_ = at_exit_functions_; + at_exit_functions_ = p; + } + +We introduce a `binding.cc` to illustrate AtExit: + + #undef NDEBUG + #include + #include + #include + #include + + using node::AtExit; + using v8::Handle; + using v8::HandleScope; + using v8::Local; + using v8::Object; + + static char cookie[] = "yum yum"; + static int at_exit_cb1_called = 0; + static int at_exit_cb2_called = 0; + + static void at_exit_cb1(void* arg) { + HandleScope scope; + assert(arg == 0); + Local obj = Object::New(); + assert(!obj.IsEmpty()); // assert VM is still alive + assert(obj->IsObject()); + at_exit_cb1_called++; + } + + static void at_exit_cb2(void* arg) { + assert(arg == static_cast(cookie)); + at_exit_cb2_called++; + } + + static void sanity_check(void) { + assert(at_exit_cb1_called == 1); + assert(at_exit_cb2_called == 2); + } + + void init(Handle target) { + AtExit(at_exit_cb1); + AtExit(at_exit_cb2, cookie); + AtExit(at_exit_cb2, cookie); + atexit(sanity_check); + } + + NODE_MODULE(binding, init); + +To test it in JavaScript: + + var binding = require('./build/Release/binding'); From 857abfeb4ce08648311a370ee224dc2ec2912738 Mon Sep 17 00:00:00 2001 From: Steve Sharp Date: Wed, 1 Oct 2014 20:35:10 -0700 Subject: [PATCH 3/5] Update addons.markdown Incorporated latest suggestions. --- doc/api/addons.markdown | 129 ++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index a99e83e370e329..0d5c75a1f7d2a8 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -813,70 +813,69 @@ Test it with: console.log(result); // 30 -### AtExit - -Registers exit hooks that run after the event loop has ended, but before the -VM is killed. - -AtExit works by creating a new AtExitCallback and prepends it to the list of -functions to be run at exit, i.e., callbacks are run in reverse order of -registration. AtExit takes a callback and arguments to the AtExitCallback as -arguments. - - void AtExit(void (*cb)(void* arg), void* arg) { - AtExitCallback* p = new AtExitCallback; - p->cb_ = cb; - p->arg_ = arg; - p->next_ = at_exit_functions_; - at_exit_functions_ = p; - } - -We introduce a `binding.cc` to illustrate AtExit: - - #undef NDEBUG - #include - #include - #include - #include - - using node::AtExit; - using v8::Handle; - using v8::HandleScope; - using v8::Local; - using v8::Object; - - static char cookie[] = "yum yum"; - static int at_exit_cb1_called = 0; - static int at_exit_cb2_called = 0; - - static void at_exit_cb1(void* arg) { - HandleScope scope; - assert(arg == 0); - Local obj = Object::New(); - assert(!obj.IsEmpty()); // assert VM is still alive - assert(obj->IsObject()); - at_exit_cb1_called++; - } - - static void at_exit_cb2(void* arg) { - assert(arg == static_cast(cookie)); - at_exit_cb2_called++; - } - - static void sanity_check(void) { - assert(at_exit_cb1_called == 1); - assert(at_exit_cb2_called == 2); - } - - void init(Handle target) { - AtExit(at_exit_cb1); - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb2, cookie); - atexit(sanity_check); - } - - NODE_MODULE(binding, init); +### void AtExit(callback, args) -To test it in JavaScript: +* `callback`: `void (*)(void*)` - A pointer to the function to call at exit. +* `args`: `void*` - A pointer to pass to the callback at exit. + +Registers exit hooks that run after the event loop has ended, but before the VM is killed. + +Callbacks are run in reverse order of registration, i.e. newest first. AtExit takes callback +and its arguments as arguments. See implementation below: + + void AtExit(void (*cb)(void* arg), void* arg) { + AtExitCallback* p = new AtExitCallback; + p->cb_ = cb; + p->arg_ = arg; + p->next_ = at_exit_functions_; + at_exit_functions_ = p; + } +The file `binding.cc` implements AtExit below: + + #undef NDEBUG + #include + #include + #include + #include + + using node::AtExit; + using v8::Handle; + using v8::HandleScope; + using v8::Local; + using v8::Object; + + static char cookie[] = "yum yum"; + static int at_exit_cb1_called = 0; + static int at_exit_cb2_called = 0; + + static void at_exit_cb1(void* arg) { + HandleScope scope; + assert(arg == 0); + Local obj = Object::New(); + assert(!obj.IsEmpty()); // assert VM is still alive + assert(obj->IsObject()); + at_exit_cb1_called++; + } + + static void at_exit_cb2(void* arg) { + assert(arg == static_cast(cookie)); + at_exit_cb2_called++; + } + + static void sanity_check(void) { + assert(at_exit_cb1_called == 1); + assert(at_exit_cb2_called == 2); + } + + void init(Handle target) { + AtExit(at_exit_cb1); + AtExit(at_exit_cb2, cookie); + AtExit(at_exit_cb2, cookie); + atexit(sanity_check); + } + + NODE_MODULE(binding, init); + +Test in JavaScript by running: - var binding = require('./build/Release/binding'); + var binding = require('./build/Release/binding'); From cd3aa020641ba9a4f67947e4698abd0b1fcbd66e Mon Sep 17 00:00:00 2001 From: Jonathan Cardoso Date: Sun, 1 Mar 2015 12:38:38 -0300 Subject: [PATCH 4/5] doc: Add documentation for AtExit hook Closes #999 --- doc/api/addons.markdown | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 0d5c75a1f7d2a8..12e80db8590c67 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -812,46 +812,32 @@ Test it with: console.log(result); // 30 - -### void AtExit(callback, args) +### AtExit hooks +#### void AtExit(callback, args) * `callback`: `void (*)(void*)` - A pointer to the function to call at exit. * `args`: `void*` - A pointer to pass to the callback at exit. Registers exit hooks that run after the event loop has ended, but before the VM is killed. -Callbacks are run in reverse order of registration, i.e. newest first. AtExit takes callback -and its arguments as arguments. See implementation below: +Callbacks are run in reverse order of registration, i.e. newest first. AtExit takes callback and its arguments as arguments. - void AtExit(void (*cb)(void* arg), void* arg) { - AtExitCallback* p = new AtExitCallback; - p->cb_ = cb; - p->arg_ = arg; - p->next_ = at_exit_functions_; - at_exit_functions_ = p; - } The file `binding.cc` implements AtExit below: #undef NDEBUG #include #include #include - #include - - using node::AtExit; - using v8::Handle; - using v8::HandleScope; - using v8::Local; - using v8::Object; static char cookie[] = "yum yum"; static int at_exit_cb1_called = 0; static int at_exit_cb2_called = 0; static void at_exit_cb1(void* arg) { - HandleScope scope; + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::HandleScope scope(isolate); assert(arg == 0); - Local obj = Object::New(); + v8::Local obj = v8::Object::New(isolate); assert(!obj.IsEmpty()); // assert VM is still alive assert(obj->IsObject()); at_exit_cb1_called++; @@ -867,11 +853,11 @@ The file `binding.cc` implements AtExit below: assert(at_exit_cb2_called == 2); } - void init(Handle target) { + void init(Handle exports) { AtExit(at_exit_cb1); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb2, cookie); - atexit(sanity_check); + AtExit(sanity_check); } NODE_MODULE(binding, init); From 3e7546258e8bd37637c6df81f5dd46e49c95f8d3 Mon Sep 17 00:00:00 2001 From: Jonathan Cardoso Date: Sat, 4 Apr 2015 20:19:55 -0300 Subject: [PATCH 5/5] Removed call to v8::Isolate::GetCurrent(), wrap line at 80. --- doc/api/addons.markdown | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 12e80db8590c67..e02f01c5a1f973 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -818,9 +818,12 @@ Test it with: * `callback`: `void (*)(void*)` - A pointer to the function to call at exit. * `args`: `void*` - A pointer to pass to the callback at exit. -Registers exit hooks that run after the event loop has ended, but before the VM is killed. +Registers exit hooks that run after the event loop has ended, but before the VM +is killed. -Callbacks are run in reverse order of registration, i.e. newest first. AtExit takes callback and its arguments as arguments. +Callbacks are run in last-in, first-out order. AtExit takes two parameters: +a pointer to a callback function to run at exit, and a pointer to untyped +context data to be passed to that callback. The file `binding.cc` implements AtExit below: @@ -834,7 +837,7 @@ The file `binding.cc` implements AtExit below: static int at_exit_cb2_called = 0; static void at_exit_cb1(void* arg) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Isolate* isolate = static_cast(arg); v8::HandleScope scope(isolate); assert(arg == 0); v8::Local obj = v8::Object::New(isolate); @@ -854,7 +857,7 @@ The file `binding.cc` implements AtExit below: } void init(Handle exports) { - AtExit(at_exit_cb1); + AtExit(at_exit_cb1, exports->GetIsolate()); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb2, cookie); AtExit(sanity_check);