David,
I think we got a little mixed up - what I ended up doing is:
public class StoppableContext extends Context {
private boolean stop;
@Override
protected void observeInstructionCount(int instructionCount) {
if (stop) {
throw new StoppedExecutionException();
}
}
public void stop() {
stop = true;
}
}
Which is basically what you just wrote :) My only complaint was the
visibility of the constructor, but it sounds like that's already a
known issue and will be solved soon.
Patrick
On Thu, Feb 19, 2009 at 6:58 AM, David Parks <[email protected]> wrote:
> Let me paraphrase to make sure I understand you.
> You want to call observeInstructionCount() externally as the method which
> will interrupt the thread?
>
> If I understood that right then all you want to do is create another method
> in the "MyContext" factory which will set an interrupt flag that
> observeInstructionCount will monitor.
>
> To extend the example given:
>
> // Custom Context to store execution time.
> private static class MyContext extends Context
> {
> long startTime;
> boolean interruptFlag = false;
> }
>
> public synchronized interruptScript(){
> interruptFlag = true;
> }
>
> // Override observeInstructionCount(Context, int)
> protected void observeInstructionCount(Context cx, int
> instructionCount)
> {
> //All the other stuff from the example...
> if(interruptFlag == true) throw new Error();
> }
>
> observeInstructionConnt() is only being called by the javascript engine
> which in turn monitors for the exception to be thrown and propagates it
> through the script (the Error's can't be caught by the script, hence it
> propagates right through and out of the script context).
>
> Let me know if I'm off base with my understanding.
>
> David
>
>
>
> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of Patrick
> Lightbody
> Sent: Thursday, February 19, 2009 9:26 AM
> To: Attila Szegedi
> Cc: David Parks; [email protected]
> Subject: Re: Stopping JavaScript Evaluation
>
> Duh - thanks! I was starting to do that last night, though instead of
> a subclass I was looking at getThreadLocal() and putThreadLocal() as a
> way to get a "Stoppable" object that had the flag in it.
>
> I'd rather do it on the Context directly (less indirection), but am
> curious about one thing: It doesn't appear a subclass (MyContext) can
> set the internal factory field. This will cause an error in many of
> the default methods of Context. For example:
>
> protected void observeInstructionCount(int instructionCount)
> {
> ContextFactory f = getFactory();
> f.observeInstructionCount(this, instructionCount);
> }
>
> Because the "factory" field is private and is only set in a
> package-protected constructor, and because getFactory() is
> public+final, there is no way for me to extend Context while still
> passing in a reference to the factory. In the example JavaDocs, this
> looks like it's skipped entirely.
>
> It may work for me, since I'll be overriding observeInstructionCount
> and not calling super, but it worries me a bit. There are other
> methods that also depend on the factory being not-null:
>
> public boolean hasFeature(int featureIndex)
> {
> ContextFactory f = getFactory();
> return f.hasFeature(this, featureIndex);
> }
>
> public static void exit()
> {
> Object helper = VMBridge.instance.getThreadContextHelper();
> Context cx = VMBridge.instance.getContext(helper);
> if (cx == null) {
> throw new IllegalStateException(
> "Calling Context.exit without previous Context.enter");
> }
> if (cx.enterCount < 1) Kit.codeBug();
> if (--cx.enterCount == 0) {
> VMBridge.instance.setContext(helper, null);
> cx.factory.onContextReleased(cx);
> }
> }
>
> Any ideas?
>
> Patrick
>
> On Thu, Feb 19, 2009 at 1:57 AM, Attila Szegedi <[email protected]> wrote:
>> On 2009.02.19., at 7:49, David Parks wrote:
>>
>>> Can you not add the stop flag check to the observeInstructionCount
>>> callback
>>> method? That would be the most straight forward way to stop the script
> and
>>> really take very few lines of code to implement. Can you explain why this
>>> wouldn't work in your case? If you're concerned with finding a reference
>>> to
>>> the stop check flag you can always extend Context and add your own
>>> reference
>>> to whatever object contains the check you need to perform as nearly
>>> demonstrated in this example:
>>>
>>>
>>>
> http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.h
>>> tml
>>
>> Hm... I'm thinking I might update that example a bit - throw a
>> java.lang.ThreadDeath specifically in place of generic java.lang. Error.
>>
>> Attila.
>>
>>> David
>>
>> _______________________________________________
>> dev-tech-js-engine-rhino mailing list
>> [email protected]
>> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>>
>
>
> _______________________________________________
> dev-tech-js-engine-rhino mailing list
> [email protected]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino
>
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino