1

I'm writing a piece of C code for Node.js and want to distinguish synchroneous from asynchroneous calls. In other words, I want to detect whether my code is running on the V8 event dispatch thread, called from within the main event loop, or whether it's called from some separate worker thread. In the former case, I could call back to JavaScript immediately, while in the latter I'd have to use a more complicated async callback.

The libuv threading API provides uv_thread_self to identify the current thread, and uv_thread_equal to compare threads for equality. So all I need is find the uv_thread_t of the main event loop.

MvG
  • 57,380
  • 22
  • 148
  • 276
  • I'm confused how it's possible to have code that doesn't know what thread it has run on. Any callback will be run on the same thread as it was queued, and libuv isn't thread safe anyway so you can't queue callbacks from a thread that isn't the event loop thread. – Trevor Norris Jan 30 '15 at 20:11
  • I'm working on [libxslt extension functions](https://github.com/albanm/node-libxslt/issues/2). So I'm writing C code which will be registered with a global data structure of the XSLT library and which will be called from the XSLT processor, which in turn can be invoced synchroneously or asynchroneously. My best bet at the moment is saving the result from `uv_thread_self` at the time the function gets registered, assuming that will always be the main event loop thread. But I'm still wondering whether there is something more elegant than this. – MvG Jan 30 '15 at 20:45

2 Answers2

1

I suppose its as easy as grabbing the uv_thread_self() from the v8 thread in the module's initialisation (as you mentioned you use node.js)? This module init code is supposed to run from the main v8 thread, as this is require()'d from your library's Javascript package.

uv_thread_t main_thread;

extern "C" void init(Handle<Object> target, Handle<Object> module) {

    Nan::HandleScope scope;

    main_thread = uv_thread_self();

then you can use uv_thread_equal to determine whether the code is running in the main thread or not:

void ozw_watcher_callback(OpenZWave::Notification const *cb, void *ctx)
// ===================================================================
{
    uv_thread_t this_thread = uv_thread_self();
    std::cout << "~~~~ ozw_watcher_callback : main thread? " << (uv_thread_equal(&main_thread, &this_thread)) << "\n";
ekarak
  • 608
  • 6
  • 15
0

On Linux (and possibly MacOS and Solaris), you could have a look at backtrace():

backtrace() returns a backtrace for the calling program, in the array pointed to by buffer. A backtrace is the series of currently active function calls for the program.

and it's friend, backtrace_symbols():

Given the set of addresses returned by backtrace() in buffer, backtrace_symbols() translates the addresses into an array of strings that describe the addresses symbolically. The size argument specifies the number of addresses in buffer. The symbolic representation of each address consists of the function name (if this can be determined), a hexadecimal offset into the function, and the actual return address (in hexadecimal).

http://linux.die.net/man/3/backtrace

On Windows, I think the following question shows how to achieve similar functionality: http://bewitchingkitchen.com/2010/01/30/slow-roasted-chicken-thighs-an-ice-breaker/

Squirrel
  • 2,262
  • 2
  • 18
  • 29
  • Thanks for this answer. I'm still hoping for something more portable, though. – MvG Jan 30 '15 at 13:49
  • I did find an answer to a similar question for Windows as well: http://stackoverflow.com/questions/5693192/win32-backtrace-from-c-code -- and I think `backtrace` may also be available on MacOS and Solaris. – Squirrel Jan 30 '15 at 13:54