Skip to content

Commit

Permalink
Implement timer functions and attempt to do async callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
creationix committed Mar 6, 2012
1 parent 8a1a165 commit b6254e7
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 81 deletions.
6 changes: 6 additions & 0 deletions src/luv_handle.h
Expand Up @@ -7,4 +7,10 @@ JSObject* Handle_prototype;

int luv_handle_init(JSContext* cx, JSObject *uv);

typedef struct {
JSContext* cx;
JSObject* obj;
} luv_ref_t;


#endif
103 changes: 83 additions & 20 deletions src/luv_timer.c
Expand Up @@ -18,6 +18,13 @@ static JSBool Timer_constructor(JSContext *cx, uintN argc, jsval *vp) {
uv_timer_init(uv_default_loop(), handle);
JS_SetPrivate(cx, obj, handle);

/* Store a reference to the object in the handle */
luv_ref_t* ref;
ref = (luv_ref_t*)malloc(sizeof(luv_ref_t));
ref->cx = cx;
ref->obj = obj;
handle->data = ref;

JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
return JS_TRUE;
}
Expand All @@ -26,52 +33,108 @@ static JSBool Timer_constructor(JSContext *cx, uintN argc, jsval *vp) {
static void Timer_finalize(JSContext *cx, JSObject *this) {
free(JS_GetPrivate(cx, this));
}
/*
static JSBool luv_tcp_bind(JSContext *cx, uintN argc, jsval *vp) {

void luv_on_timer(uv_timer_t* handle, int status) {
printf("luv_on_timer\n");
luv_ref_t* ref;
ref = (luv_ref_t*)handle->data;
JSContext* cx = ref->cx;
JSObject* this = ref->obj;

jsval callback_val;
if (!JS_GetProperty(cx, this, "on_timer", &callback_val)) {
printf("ERROR getting on_timer prop\n");
return;
}

if (JSVAL_IS_OBJECT(callback_val)) {
printf("calling!\n");
if (!JS_CallFunctionValue(cx, NULL, callback_val, 0, NULL, NULL)) {
printf("Error in call\n");
return;
}
}

}


static JSBool luv_timer_start(JSContext* cx, uintN argc, jsval *vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
uv_timer_t* handle;
handle = (uv_timer_t*)JS_GetInstancePrivate(cx, this, &Timer_class, NULL);

const char* host = "0.0.0.0";
int port = 8080;
int32_t timeout;
int32_t repeat;
JSObject* callback;
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "uuo", &timeout, &repeat, &callback)) {
return JS_FALSE;
}

struct sockaddr_in address = uv_ip4_addr(host, port);
jsval callback_val = OBJECT_TO_JSVAL(callback);
if (!JS_SetProperty(cx, this, "on_timer", &callback_val)) return 1;

UV_CALL(uv_tcp_bind, handle, address);
UV_CALL(uv_timer_start, handle, luv_on_timer, timeout, repeat);

JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_tcp_nodelay(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_timer_stop(JSContext* cx, uintN argc, jsval* vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
uv_timer_t* handle;
handle = (uv_timer_t*)JS_GetInstancePrivate(cx, this, &Timer_class, NULL);

int enable = 1;
UV_CALL(uv_timer_stop, handle);

UV_CALL(uv_tcp_nodelay, handle, enable);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_timer_again(JSContext* cx, uintN argc, jsval* vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_timer_t* handle;
handle = (uv_timer_t*)JS_GetInstancePrivate(cx, this, &Timer_class, NULL);

UV_CALL(uv_timer_again, handle);

JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}

static JSBool luv_tcp_keepalive(JSContext *cx, uintN argc, jsval *vp) {
static JSBool luv_timer_set_repeat(JSContext* cx, uintN argc, jsval* vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_tcp_t* handle;
handle = (uv_tcp_t*)JS_GetInstancePrivate(cx, this, &Tcp_class, NULL);
uv_timer_t* handle;
handle = (uv_timer_t*)JS_GetInstancePrivate(cx, this, &Timer_class, NULL);

int enable = 1;
int delay = 500;
int32_t repeat;
if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "u", &repeat)) {
return JS_FALSE;
}

UV_CALL(uv_tcp_keepalive, handle, enable, delay);
uv_timer_set_repeat(handle, repeat);

JS_SET_RVAL(cx, vp, JSVAL_VOID);
return JS_TRUE;
}
*/

static JSBool luv_timer_get_repeat(JSContext* cx, uintN argc, jsval* vp) {
JSObject* this = JS_THIS_OBJECT(cx, vp);
uv_timer_t* handle;
handle = (uv_timer_t*)JS_GetInstancePrivate(cx, this, &Timer_class, NULL);

int64_t repeat = uv_timer_get_repeat(handle);

JS_SET_RVAL(cx, vp, INT_TO_JSVAL(repeat));
return JS_TRUE;
}


static JSFunctionSpec Timer_methods[] = {
JS_FS("start", luv_timer_start, 0, 0),
JS_FS("stop", luv_timer_stop, 0, 0),
JS_FS("again", luv_timer_again, 0, 0),
JS_FS("setRepeat", luv_timer_set_repeat, 0, 0),
JS_FS("getRepeat", luv_timer_get_repeat, 0, 0),
JS_FS_END
};

Expand Down
77 changes: 16 additions & 61 deletions test.js
@@ -1,68 +1,23 @@

var p = require('utils').prettyPrint;
p(global);
var uv = require('uv');

function bytesToHuman(bytes) {
if (bytes > 0x40000000) {
return (bytes / Math.pow(2, 30)).toFixed(2) + "Gb";
}
if (bytes > 0x100000) {
return (bytes / Math.pow(2, 20)).toFixed(2) + "Mb";
}
if (bytes > 0x400) {
return (bytes / Math.pow(2, 10)).toFixed(2) + "Kb";
}
return bytes + " bytes";
}


// p(global);
var Timer = require('uv').Timer;

p("exepath", uv.exepath());
p("free memory", uv.get_free_memory(), bytesToHuman(uv.get_free_memory()));
p("total memory", uv.get_total_memory(), bytesToHuman(uv.get_total_memory()));
p("loadavg", uv.loadavg());
p("uptime", uv.uptime());
var timer = new Timer();
var timer2 = new Timer();

p("uv.Handle", uv.Handle);
p("uv.Handle.prototype", uv.Handle.prototype);
var h = new uv.Handle();
p("h = new uv.Handle()", h);
p("h instanceof uv.Handle", h instanceof uv.Handle);
p("h.__proto__.constructor", h.__proto__.constructor)
p("uv.Stream.prototype", uv.Stream.prototype);
var s = new uv.Stream();
p("s = new uv.Stream()", s);
p("s instanceof uv.Stream", s instanceof uv.Stream);
p("s instanceof uv.Handle", s instanceof uv.Handle);
p("s.__proto__.constructor", s.__proto__.constructor)
p("uv.Tcp.prototype", uv.Tcp.prototype);
var t = new uv.Tcp();
p("t = new uv.Tcp()", t);
p("t instanceof uv.Tcp", t instanceof uv.Tcp);
p("t instanceof uv.Stream", t instanceof uv.Stream);
p("t instanceof uv.Handle", t instanceof uv.Handle);
p("t.__proto__.constructor", t.__proto__.constructor);
p("t.close === h.close", t.close === h.close);
p("s.close === h.close", s.close === h.close);
p("t.write === s.write", t.write === s.write);
t.close()

p("args", args);
p("uv", uv);

p({
__filename: __filename,
__dirname: __dirname,
exports: exports,
module: module
timer.start(2000, 0, function onTimer() {
p("on_timeout");
timer2.stop();
timer.stop();
timer.close(p);
timer2.close(p);
});

var server = new uv.Tcp();
server.nodelay(1);
server.keepalive(1, 500);
server.bind("0.0.0.0", 8080);
server.close()
timer2.start(333, 333, function onInterval() {
p("on_interval");
var period = timer2.getRepeat();
p("period", period);
timer2.setRepeat(period / 1.2 + 1);
});

p("typeof null", typeof null);
p(timer, timer2);

0 comments on commit b6254e7

Please sign in to comment.