Skip to content

@TooTallNate /README.md
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A C header file to make your node bindings backwards and forwards compatible that use eio_custom()

node_async_shim.h

Use this header file to conditionally invoke eio_custom() or uv_queue_work(), depending on the node version that the module is being compiled for.

See the usage.cc file for a partial example.

Comments, forks, and improvements are welcome!

/**
* eio_custom() vs. uv_queue_work() file.
* Original gist: https://gist.github.com/1368935
*
* Copyright (c) 2011-2012, Nathan Rajlich <nathan@tootallnate.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <node.h>
#include <node_version.h>
/* Node Thread Pool version compat */
#if NODE_VERSION_AT_LEAST(0, 5, 6)
#define BEGIN_ASYNC(_data, async, after) \
uv_work_t *_req = new uv_work_t; \
_req->data = _data; \
uv_queue_work(uv_default_loop(), _req, async, after);
typedef void async_rtn;
#define RETURN_ASYNC
#define RETURN_ASYNC_AFTER delete req;
#else
#define BEGIN_ASYNC(data, async, after) \
ev_ref(EV_DEFAULT_UC); \
eio_custom(async, EIO_PRI_DEFAULT, after, data);
typedef int async_rtn;
typedef eio_req uv_work_t;
#define RETURN_ASYNC return 0;
#define RETURN_ASYNC_AFTER \
ev_unref(EV_DEFAULT_UC); \
RETURN_ASYNC;
#endif
/**
* The "Thread Pool" function
*/
async_rtn doing_work (uv_work_t *req) {
my_struct *m = (my_struct *)req->data;
/* Something computationally expensive here */
r->rtn = 1 + 1;
RETURN_ASYNC
}
/**
* The "After" function
*/
async_rtn after_doing_work (uv_work_t *req) {
HandleScope scope;
my_struct *m = (my_struct *)req->data;
Handle<Value> argv[1];
argv[0] = Integer::New(r->rtn);
TryCatch try_catch;
m->callback->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught())
FatalException(try_catch);
// cleanup
m->callback.Dispose();
delete m;
RETURN_ASYNC_AFTER
}
/**
* The JS Entry Point
*/
Handle<Value> start_doing_work (const Arguments& args) {
HandleScope scope;
my_struct *m = new my_struct;
m->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
/* Start the async function on the thread pool */
BEGIN_ASYNC(m, doing_work, after_doing_work);
return Undefined();
}
@Sannis

Regardles to your defines, RETURN_ASYNC_AFTER and RETURN_ASYNC should be used without semicolon?)

@TooTallNate
Owner

@Sannis Ya you're right. It hasn't caused any compiler error for me though. I've updated the gist, thanks :)

@Sannis

Thanks, it will be more conform with node.h macroses.

@teeler

This looks broken - you mention r->rtn - what is r?

@victusfate

Heyo Nate, I'm seeing maybe a missing header?

error: no matching function for call to 'uv_queue_work'
BEGIN_ASYNC(pm, asyncWriteTask, afterWriteTask);

checking recent v0.10.0 docs to see if uv_queue_work moved

oh, this may help

/Users/messel/.node-gyp/0.10.0/deps/uv/include/uv.h:1397:15: note: candidate function not viable: no known conversion from
      'async_rtn (uv_work_t *)' to 'uv_after_work_cb' (aka 'void (*)(uv_work_t *, int)') for 4th argument
UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,

looks like I need to convert the callback to
void (*)(uv_work_t *, int)

got it, just need to cast it.

#include 
#include 

/* Node Thread Pool version compat */
#if NODE_VERSION_AT_LEAST(0, 5, 6)
  #define BEGIN_ASYNC(_data, async, after) \
    uv_work_t *_req = new uv_work_t; \
    _req->data = _data; \
    uv_queue_work(uv_default_loop(), _req, async, (uv_after_work_cb)after);
  typedef void async_rtn;
  #define RETURN_ASYNC
  #define RETURN_ASYNC_AFTER delete req;
#else
  #define BEGIN_ASYNC(data, async, after) \
    ev_ref(EV_DEFAULT_UC); \
    eio_custom(async, EIO_PRI_DEFAULT, after, data);
  typedef int async_rtn;
  typedef eio_req uv_work_t;
  #define RETURN_ASYNC return 0;
  #define RETURN_ASYNC_AFTER \
    ev_unref(EV_DEFAULT_UC); \
    RETURN_ASYNC;
#endif
@tim-kos

This does not work for 0.10.24 right? I tried it and it seemed to work, but then it said it could not find symbol module.

It seems a call to NODE_MODULE() is required now. Do you guys have any insights into this? If not, then I'd go and try to get it to work with https://github.com/rvagg/nan.

Thanks in advance for any pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.