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 Ya you're right. It hasn't caused any compiler error for me though. I've updated the gist, thanks :)
Thanks, it will be more conform with node.h macroses.
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.
Regardles to your defines,
RETURN_ASYNC_AFTERandRETURN_ASYNCshould be used without semicolon?)