2009/4/10 <[email protected]>:
>
> 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.
Without having read your code I just wonder: Are you by any chance
calling V8 from more than one thread? See the comments around the
Locker class in include/v8.h for details of the rules for
multithreaded V8 programs.
>
> 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
>
> >
>
--
Erik Corry, Software Engineer
Google Denmark ApS. CVR nr. 28 86 69 84
c/o Philip & Partners, 7 Vognmagergade, P.O. Box 2227, DK-1018
Copenhagen K, Denmark.
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---