Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active June 20, 2024 18:22
Show Gist options
  • Select an option

  • Save bellbind/b69c3aa266cffe43940c to your computer and use it in GitHub Desktop.

Select an option

Save bellbind/b69c3aa266cffe43940c to your computer and use it in GitHub Desktop.

Revisions

  1. bellbind revised this gist Oct 9, 2015. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions timer-and-promise.cc
    Original file line number Diff line number Diff line change
    @@ -6,13 +6,12 @@

    // Promise returned function
    NAN_METHOD(Wait) {
    using ResolverPersistent = v8::Persistent<v8::Promise::Resolver>;
    using ResolverLocal = v8::Local<v8::Promise::Resolver>;
    using ResolverPersistent = Nan::Persistent<v8::Promise::Resolver>;

    auto ms = Nan::To<unsigned>(info[0]).FromJust();
    auto resolver = v8::Promise::Resolver::New(info.GetIsolate());
    auto promise = resolver->GetPromise();
    auto persistent = new ResolverPersistent(info.GetIsolate(), resolver);
    auto persistent = new ResolverPersistent(resolver);

    uv_timer_t* handle = new uv_timer_t;
    handle->data = persistent;
    @@ -28,7 +27,7 @@ NAN_METHOD(Wait) {
    uv_close(reinterpret_cast<uv_handle_t*>(handle),
    [](uv_handle_t* handle) -> void {delete handle;});

    auto resolver = ResolverLocal::New(v8::Isolate::GetCurrent(), *persistent);
    auto resolver = Nan::New(*persistent);
    resolver->Resolve(Nan::New("invoked").ToLocalChecked());

    persistent->Reset();
  2. bellbind revised this gist Oct 6, 2015. 3 changed files with 48 additions and 24 deletions.
    23 changes: 23 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,26 @@
    # Native Module with libuv and Promise

    - `v8::Persistent`: Keep a v8 Object over scope
    - it require to release the Object manulally with `Reset(void)`
    - Use Object with convert Local to `v8::Local<T>::New(isolate, persistent)`
    - `v8::Promise` is made from `v8::Promise::Resolver` object
    - `Promise::Resolver::New(isolate)` then `resolver->GetPromise()`
    - use `ressolver->Resolve(obj)` or `resolver->Reject(obj)` to pass promise
    - `v8::Isolate`: requires to create v8 Object
    - hidden by `Nan::New` inside to use `v8::Isolate::GetCurrent()`
    - (for creating Isolate as barrier (e.f. for different tasks))
    - `Nan::HandleScope scope`: It requires to create v8 Object
    in outside of NAN_METHOD function (e.g. in native callbacks)
    - `libuv` pattern
    - make `uv_xxx_t` handle
    - set `handle->data` to objects use inside callback
    - call `uv_xxx_init(uv_default_loop(), handle)`
    - call `uv_xxx_yyy(handle, callback, ...)` function
    - in callback
    - retrieve objects from `handle->data`
    - `uv_close(handle, dispose)` to register deleting handle memory
    - do something as callback

    ## Reference

    For native module basics, see:
    3 changes: 2 additions & 1 deletion run.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    "use strict";

    let m = require(".");
    m.wait(10).then((msg) => console.log(`OK: ${msg}`));
    let start = Date.now();
    m.wait(500).then((msg) => console.log(`${Date.now() - start}ms OK: ${msg}`));
    46 changes: 23 additions & 23 deletions timer-and-promise.cc
    Original file line number Diff line number Diff line change
    @@ -1,39 +1,39 @@
    // build: npm install

    #include <iostream>
    #include <nan.h>

    // callback for uv_timer
    void timercb(uv_timer_t* handle) {
    Nan::HandleScope scope;

    auto persistent =
    static_cast<v8::Persistent<v8::Promise::Resolver>*>(handle->data);

    uv_timer_stop(handle);
    uv_close(reinterpret_cast<uv_handle_t*>(handle),
    [](uv_handle_t* handle) -> void {delete handle;});

    auto resolver =
    v8::Local<v8::Promise::Resolver>::New(v8::Isolate::GetCurrent(),
    *persistent);
    resolver->Resolve(Nan::New("invoked").ToLocalChecked());

    persistent->Reset();
    delete persistent;
    }

    // Promise returned function
    NAN_METHOD(Wait) {
    using ResolverPersistent = v8::Persistent<v8::Promise::Resolver>;
    using ResolverLocal = v8::Local<v8::Promise::Resolver>;

    auto ms = Nan::To<unsigned>(info[0]).FromJust();

    auto resolver = v8::Promise::Resolver::New(info.GetIsolate());
    auto promise = resolver->GetPromise();
    auto persistent = new v8::Persistent<v8::Promise::Resolver>();
    persistent->Reset(info.GetIsolate(), resolver);

    auto persistent = new ResolverPersistent(info.GetIsolate(), resolver);

    uv_timer_t* handle = new uv_timer_t;
    handle->data = persistent;
    uv_timer_init(uv_default_loop(), handle);

    // use capture-less lambda for c-callback
    auto timercb = [](uv_timer_t* handle) -> void {
    Nan::HandleScope scope;

    auto persistent = static_cast<ResolverPersistent*>(handle->data);

    uv_timer_stop(handle);
    uv_close(reinterpret_cast<uv_handle_t*>(handle),
    [](uv_handle_t* handle) -> void {delete handle;});

    auto resolver = ResolverLocal::New(v8::Isolate::GetCurrent(), *persistent);
    resolver->Resolve(Nan::New("invoked").ToLocalChecked());

    persistent->Reset();
    delete persistent;
    };
    uv_timer_start(handle, timercb, ms, 0);

    info.GetReturnValue().Set(promise);
  3. bellbind revised this gist Oct 2, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion run.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    use strict";
    "use strict";

    let m = require(".");
    m.wait(10).then((msg) => console.log(`OK: ${msg}`));
  4. bellbind created this gist Oct 2, 2015.
    18 changes: 18 additions & 0 deletions binding.gyp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    # -*- mode: python -*-
    {
    "targets": [
    {
    "include_dirs": ["<!(node -e \"require('nan')\")"],
    "target_name": "TimerAndPromise",
    "sources": [
    "timer-and-promise.cc"
    ],
    "conditions": [
    ["OS != 'win'",{
    "cflags": ["-Wall", "-Wextra", "-pedantic"],
    "cflags_cc": ["-std=c++14"],
    }]
    ],
    },
    ],
    }
    12 changes: 12 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    {
    "name": "timer-and-promise",
    "version": "0.1.0",
    "description": "Native module example with libuv uv_timer and promise",
    "license": "MIT",
    "repository": "gist:",
    "engine": {"node": ">=4.0.0"},
    "main": "./build/Release/TimerAndPromise",
    "dependencies": {
    "nan": ">=2.0.0"
    }
    }
    11 changes: 11 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    ## Reference

    For native module basics, see:

    - https://gist.github.com/bellbind/cc915d252eeb77a3e03e

    For APIs, see:

    - http://docs.libuv.org/en/v1.x/timer.html
    - http://v8.paulfryzel.com/docs/master/classv8_1_1_persistent_base.html
    - http://v8.paulfryzel.com/docs/master/classv8_1_1_promise_1_1_resolver.html
    4 changes: 4 additions & 0 deletions run.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    use strict";

    let m = require(".");
    m.wait(10).then((msg) => console.log(`OK: ${msg}`));
    47 changes: 47 additions & 0 deletions timer-and-promise.cc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    // build: npm install

    #include <nan.h>

    // callback for uv_timer
    void timercb(uv_timer_t* handle) {
    Nan::HandleScope scope;

    auto persistent =
    static_cast<v8::Persistent<v8::Promise::Resolver>*>(handle->data);

    uv_timer_stop(handle);
    uv_close(reinterpret_cast<uv_handle_t*>(handle),
    [](uv_handle_t* handle) -> void {delete handle;});

    auto resolver =
    v8::Local<v8::Promise::Resolver>::New(v8::Isolate::GetCurrent(),
    *persistent);
    resolver->Resolve(Nan::New("invoked").ToLocalChecked());

    persistent->Reset();
    delete persistent;
    }

    // Promise returned function
    NAN_METHOD(Wait) {
    auto ms = Nan::To<unsigned>(info[0]).FromJust();

    auto resolver = v8::Promise::Resolver::New(info.GetIsolate());
    auto promise = resolver->GetPromise();
    auto persistent = new v8::Persistent<v8::Promise::Resolver>();
    persistent->Reset(info.GetIsolate(), resolver);

    uv_timer_t* handle = new uv_timer_t;
    handle->data = persistent;
    uv_timer_init(uv_default_loop(), handle);
    uv_timer_start(handle, timercb, ms, 0);

    info.GetReturnValue().Set(promise);
    }


    NAN_MODULE_INIT(InitAll) {
    Nan::Export(target, "wait", Wait);
    }

    NODE_MODULE(TimerAndPromise, InitAll)