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
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---