Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble making threads work #115

Open
vsantosu opened this issue May 16, 2018 · 2 comments
Open

Trouble making threads work #115

vsantosu opened this issue May 16, 2018 · 2 comments

Comments

@vsantosu
Copy link

Hello there, this is an amazing project and I would like to use it for a native node addon.

Do somebody have an idea of how to make threading work? I know that the nbind::cbFunction function must be called within the same thread the parent function was called, so a setTimeout style functionality cannot be done easily.

I made the following experiment:

The Native Class:

#include <string>
#include <iostream>
#include <thread>
#include <chrono>
#include <nan.h>
#include "nbind/api.h"

class Utils
{
  nbind::cbFunction * asyncFactorialCB;

  public:
    Utils(){ }

    void asyncFactorial(int n, nbind::cbFunction &callback)
    {
        /* save callback function reference */
        Utils * self = this;
        self->asyncFactorialCB = new nbind::cbFunction(callback);

        /* a simple factorial thread using lambda */
        std::thread threadObj([n, self] {
            
            std::cout << "Start thread..." << std::endl;
            /* sleep thread for 2 seconds */
            std::this_thread::sleep_for(std::chrono::milliseconds(2000));
            /* do some work */
            int acu = n;
            for (int i = n; i > 1; i--)
            {
                acu = acu * (i - 1);
            }

            std::cout << "Result inside thread is: " <<acu<< std::endl;
            std::cout << "End thread..." << std::endl;
            std::cout << "Callback pointer: " << self->asyncFactorialCB << std::endl;

            /* callback javascript, CAUSES SEGMENTATION FAULT */
            (*self->asyncFactorialCB)(n);
        });
        /* detach from this thread */
        threadObj.detach();

        /* THIS HERE WORKS FINE */
        //(*self->asyncFactorialCB)(5555);
    }
};


#include "nbind/nbind.h"
#ifdef NBIND_CLASS
NBIND_CLASS(Utils)
{
    construct<>();
    method(asyncFactorial);
}
#endif

The Javascript code:

var nbind = require('nbind');

/* init native class */
const Utils = nbind.init().lib.Utils;

/* using the class */
let utl = new Utils();
let n = 5;

/* async example */
utl.asyncFactorial(n,(r)=>{
    console.log("Async Factorial of", n, "is", r);
});
console.log('JS', 'after calling async factorial');

/* prevents process from finish */
setInterval(()=>{
},5000);

Output:

Start thread...
JS after calling async factorial
Result inside thread is: 120
End thread...
Callback pointer: 0x1028033d0
Segmentation fault: 11

This is one of the most valuable use cases at the moment of writing an addon, specially for tools to process data in parallel. Any idea on how to make this work? Thanks in advanced!

@chad3814
Copy link

chad3814 commented Jun 6, 2018

I have a similar issue, though I'm using libuv for threading (since that's what node is using). Seems like nbind is keeping track of a Scope or Isolate when code transitions from js to c++, so that doesn't exist when the main thread tries to go from c++ to js...

@zurp
Copy link

zurp commented Mar 28, 2019

I have the same issue, I'll try out v8pp and see if that works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants