Skip to content

Instantly share code, notes, and snippets.

@Raynos
Last active August 29, 2015 14:00
Show Gist options
  • Save Raynos/11155596 to your computer and use it in GitHub Desktop.
Save Raynos/11155596 to your computer and use it in GitHub Desktop.
int main() {
loop = uv_default_loop();
uv_tcp_t server;
uv_tcp_init(loop, &server);
struct sockaddr_in bind_addr = uv_ip4_addr("0.0.0.0", 7000);
uv_tcp_bind(&server, bind_addr);
int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection);
if (r) {
fprintf(stderr, "Listen error %s\n", uv_err_name(uv_last_error(loop)));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
var uv = require('uv');
var console = require('./support/console.js');
function main() {
var loop = uv.default_loop();
var handle = uv.tcp_init(loop);
var addr = uv.ip4_addr("0.0.0.0", 7000);
uv.tcp_bind(handle, addr);
var err = uv.listen(handle, 128, on_new_connection);
if (err) {
console.log('Listen error %s\n', uv.err_name(uv.last_error(loop)));
return 1;
}
return uv.run(loop, uv.RUN_DEFAULT);
}
@trevnorris
Copy link

Couple issues. Each uv_handle_t needs to be associated with a JS object to persist state of a given instance. Otherwise there's no state to persist onto callbacks like on_new_connection. You'll also have to make use of the v8::Persistent<T>() class on each of those objects to make sure the object isn't GC'd prior to when the handle is actually destroyed.

Keep in mind you can't achieve things like epoll from JS. So in libuv-tcp.c the return uv_run(loop, UV_RUN_DEFAULT); blocks until the end of the program. While on the JS side your main() will have to return immediately. Which means the objects loop, handle and addr will have left scope and been GC'd.

Don't get me wrong. I think this an awesome idea, and this type of binding layer is something I'm actually working on right now as part of experimental performance whatnot. Just remember that there will have to be some abstraction between the two.

Note: The libuv API has changed in v0.11. It would now look like so (with a little extra to keep valgrind happy :-):

static uv_loop_t* loop;

void check(int i) {
    if (0 != i) {
        fprintf(stderr, "err: %s\n", uv_err_name(i));
        abort();
    }
}

int main() {
    uv_tcp_t server;
    struct sockaddr_in bind_addr;
    int r;

    loop = uv_default_loop();

    check(uv_tcp_init(loop, &server))
    check(uv_ip4_addr("0.0.0.0", 7000, &bind_addr))
    check(uv_tcp_bind(&server, (const struct sockaddr*) &bind_addr, 0));
    check(uv_listen((uv_stream_t*) &server, 128, on_new_connection))

    r = uv_run(loop, UV_RUN_DEFAULT);
    uv_loop_close(loop);
    return r;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment