mirror of https://github.com/nodejs/node.git
Page:
Migrating IO polling from libev to libuv
Pages
API changes between v0.10 and v0.12
API changes between v0.10 and v4
API changes between v0.4 and v0.6
API changes between v0.6 and v0.8
API changes between v0.8 and v0.10
Breaking Changes
Breaking changes between Node 7 and 8
Breaking changes between v4 LTS and v6 LTS
Breaking changes between v4 and v5
Breaking changes between v5 and v6
Breaking changes between v6 LTS and v8 LTS
Breaking changes between v6 and v7
CITGM Status
CITGM known flakes
CITGM results table
Creating a CTC Meeting Issue
ES6 Module Detection in Node
Flaky tests
Frequently Asked Questions
Home
Installing and Building Node.js
Installing io.js via package manager
Meetings: Creating a Hangouts On Air Event
Merging pull requests with Jenkins
Migrating IO polling from libev to libuv
Migrating from v0.2 to v0.3
Migrating from v0.2 to v0.4
Statically linked executable
Testing pull requests with Jenkins
Windows Environment
1
Migrating IO polling from libev to libuv
Vse Mozhet Byt edited this page 2018-04-23 22:34:36 +03:00
For native modules that wanted to watch for IO events on file descriptors, the original functions to do this was ev_io_*()
, exposed by libev
. You would have code that looked something like this:
/** THIS IS THE OLD API, DON'T COPY THIS, SEE BELOW!! **/
struct my_struct {
Persistent<Function> callback;
int fd;
};
/* the "on fd IO event" callback; called on the main thread */
void on_fd_event (EV_P_ ev_io *io_watcher, int events) {
HandleScope scope;
my_struct *m = (my_struct *) io_watcher->data;
// stop watcher
ev_io_stop(EV_DEFAULT_UC_ io_watcher);
delete io_watcher;
/* Some code here that works with `fd` (and closes it if needed) and produces `Handle<Value> result` */
Handle<Value> argv[1];
argv[0] = Integer::New(result);
TryCatch try_catch;
m->callback->Call(Context::GetCurrent()->Global(), 1, argv);
// cleanup
m->callback.Dispose();
delete m;
if (try_catch.HasCaught())
FatalException(try_catch);
}
/* the JS entry point */
Handle<Value> start_fd_watch (const Arguments& args) {
HandleScope scope;
/* Some code here that opens `fd` and do something */
my_struct *m = new my_struct;
m->fd = fd;
m->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
// create IO watcher and start watching
ev_io* io_watcher = new ev_io;
io_watcher->data = m;
ev_init(io_watcher, on_fd_event);
ev_io_set(io_watcher, fd, EV_READ /* or other flags */);
ev_io_start(EV_DEFAULT_UC_ io_watcher);
return Undefined();
}
Now, there is a new preferred method to poll IO events: uv_poll_*()
, exposed by libuv
. The API is similar but slightly different:
/** THIS IS THE CURRENT API. COPY THIS!!! **/
struct my_struct {
Persistent<Function> callback;
int fd;
};
static void on_handle_close (uv_handle_t *handle) {
delete handle;
}
/* the "on fd IO event" callback; called on the main thread */
void on_fd_event (uv_poll_t* handle, int status, int events) {
HandleScope scope;
my_struct *m = (my_struct *) handle->data;
// stop watcher
uv_poll_stop(handle);
// and close poll handle
uv_close((uv_handle_t *)handle, on_handle_close);
/* Some code here that works with `fd` (and closes it if needed) and produces `Handle<Value> result` */
Handle<Value> argv[1];
argv[0] = Integer::New(result);
TryCatch try_catch;
m->callback->Call(Context::GetCurrent()->Global(), 1, argv);
// cleanup
m->callback.Dispose();
delete m;
if (try_catch.HasCaught())
FatalException(try_catch);
}
/* the JS entry point */
Handle<Value> start_fd_watch (const Arguments& args) {
HandleScope scope;
/* Some code here that opens `fd` and do something */
my_struct *m = new my_struct;
m->fd = fd;
m->callback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
// create poll handle and start polling
uv_poll_t* handle = new uv_poll_t;
handle->data = m;
uv_poll_init(uv_default_loop(), handle, fd);
uv_poll_start(handle, UV_READABLE /* or other flags */, on_fd_event);
return Undefined();
}
Rundown:
- Call
uv_poll_init()
+uv_poll_start()
instead ofev_init()
+ev_set()
+ev_start()
to initiate IO watching. - The "on fd IO event" callback functions now accept a
uv_poll_t *
pointer as their arguments and extraint status
, instead of aev_io *
pointer. - You can attach a custom
void *
to thedata
field of theuv_poll_t
struct.