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
-~----------~----~----~----~------~----~------~--~---

Reply via email to