-// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
package org.xwt;
-import org.xwt.util.*;
import java.util.*;
-import org.mozilla.javascript.*;
+import org.xwt.util.*;
+import org.xwt.js.*;
/**
* A background thread. All threads created with <tt>xwt.thread</tt>
private volatile static int threadcount = 0;
/** the JavaScript function that we are executing */
- volatile Function f;
+ volatile JS.Callable f;
/** the ThreadMessage thread blocks on this before executing any JavaScript */
Semaphore go = new Semaphore();
- /** The MessageQueue (main) thread blocks on this while the ThreadMessage thread is running JavaScript code */
+ /** The Message.Q (main) thread blocks on this while the ThreadMessage thread is running JavaScript code */
Semaphore done = new Semaphore();
/** used to pool ThreadMessages that are not in use */
private static Object[] emptyobj = new Object[] { };
/** creates a new thread to execute function <tt>f</tt> */
- public static void newthread(Function f) {
+ public static synchronized void newthread(JS.Callable f) {
ThreadMessage ret = (ThreadMessage)spare.remove(false);
if (ret == null) {
if (threadcount < Platform.maxThreads()) ret = new ThreadMessage();
}
}
ret.f = f;
- MessageQueue.add(ret);
+ Message.Q.add(ret);
+ }
+
+ /** attempts to put this thread into the background to perform a blocking operation; returns false if unable to do so */
+ public static boolean suspendThread() {
+ // put ourselves in the background
+ Thread thread = Thread.currentThread();
+ if (!(thread instanceof ThreadMessage)) {
+ if (Log.on) Log.logJS(ThreadMessage.class, "attempt to perform background-only operation in a foreground thread");
+ return false;
+ }
+ ThreadMessage mythread = (ThreadMessage)thread;
+ mythread.setPriority(Thread.MIN_PRIORITY);
+ mythread.done.release();
+ return true;
+ }
+
+ /** re-enqueues this thread */
+ public static void resumeThread() {
+ ThreadMessage mythread = (ThreadMessage)Thread.currentThread();
+ Message.Q.add(mythread);
+ mythread.setPriority(Thread.NORM_PRIORITY);
+ mythread.go.block();
}
public void run() {
try {
threadcount++;
- Context cx = Context.enter();
while (true) {
try {
go.block();
- f.call(cx, f.getParentScope(), f.getParentScope(), emptyobj);
- } catch (EcmaError e) {
- if (Log.on) Log.log(this, "WARNING: uncaught interpreter exception: " + e.getMessage());
- if (Log.on) Log.log(this, " thrown from background thread at " + e.getSourceName() + ":" + e.getLineNumber());
- } catch (JavaScriptException e) {
- if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage());
- if (Log.on) Log.log(this, " thrown from background thread at " + e.sourceFile + ":" + e.line);
+ f.call(new JS.Array());
+ } catch (JS.Exn e) {
+ if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e);
}
done.release();
synchronized(waiting) {
if (waiting.size() > 0) {
- f = (Function)waiting.remove(false);
- MessageQueue.add(this);
+ f = (JS.Callable)waiting.remove(false);
+ Message.Q.add(this);
} else if (spare.size() < 10) {
spare.append(this);
} else {
}
}
- /** this is invoked in the MessageQueue thread */
+ /** this is invoked in the Message.Q thread */
public void perform() {
go.release();
done.block();