klapa...@gmail.com
unread,Apr 9, 2009, 8:31:55 PM4/9/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to v8-users
Hi,
I'm trying to support up a simple timer going through OS service
(Win32 Timer queue).
The plan is to have a JS function called when timer expires/ticks.
OS provides the usual
void callback(void* userdata)
My void* is cast from/to Persistent <Function> which should be called.
Here's the payload function after casting the void* pointer
void DeferCallback(Persistent<Function>* timer)
{
HandleScope handle_scope; // if this is left out v8 bombs with
StackOverflow error
TryCatch try_catch;
Local<Value> result = timer->callback->Call(timer->callback, 0, 0);
// Quit system timer if function returns false or if an exception is
thrown
// My code in the OS static callback checks if timer has expired and
tells OS to quit calling if so.
if (result == False() || !try_catch.Exception().IsEmpty()) {
if (!try_catch.Exception().IsEmpty())
ReportException(&try_catch); // Defined in shell.cpp
timer->stop();
Persistent<Function> p(timer->callback);
p.Dispose();
}
}
This works for a while, then I get arbitrary crashes in V8 since
something tries to use some Handle value that is dead.
The script wrapper part is added to global thus:
// Defer object
Handle<ObjectTemplate> deferrer = ObjectTemplate::New();
deferrer->Set(String::New("once"), FunctionTemplate::New(DeferOnce),
DEFAULT_ATTR );
deferrer->Set(String::New("repeat"), FunctionTemplate::New
(DeferRepeat), DEFAULT_ATTR);
global->Set(String::New("Defer"), deferrer, DEFAULT_ATTR);
Defer doesn't use a constructor. User calls like
<js>
Defer.repeat(3, 1/10, myFunction);
</js>
to call myFunction 10 times per sec starting after 3 seconds.
This will work perfectly for a while, then crash.
The DeferRepeat function starts timer and forwards the function to
call:
Handle<Value> DeferRepeat(const Arguments& args)
{
HandleScope handle_scope;
// (arg checks elided)
// Get deferred function from arguments
Handle<Function> fun = Handle<Function>::Cast(args[2]);
Persistent<Function> func = Persistent<Function>::New(fun);
double waitsecs = args[0]->NumberValue();
double repeatsecs = args[1]->NumberValue();
// systemtimer() repeat(...) starts the OS service, with
DeferCallback as callback
Deferred* d = systemtimer()->repeat(waitsecs, repeatsecs,
DeferredCallPtr(&DeferCallback));
d->callback = func;
// where Deferred has a single member
// Persistent<Function> callback; -- which is the part used in
DeferCallback function above
return func;
}
I'm also unsure what I should send as Receiver when making the
function Call in DeferCallback:
Local<Value> result = timer->callback->Call(timer->callback, 0, 0);
Using the Function as its own receiver works, but I'm not sure if it
works right - just copied blindly from a post to this list...
Thanks for any tips,
k