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 <[email protected]> | |
* | |
* 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(); | |
} |
This looks broken - you mention r->rtn - what is r?
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
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.
Thanks, it will be more conform with
node.h
macroses.