2003/10/29 06:07:29
[org.ibex.core.git] / src / org / xwt / ThreadMessage.java
index 558c49d..0eeefef 100644 (file)
@@ -1,9 +1,9 @@
-// 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>
@@ -16,16 +16,16 @@ import org.mozilla.javascript.*;
  *             this invariant.
  */
 public class ThreadMessage extends Thread implements Message {
-    
+
     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 */
@@ -38,7 +38,7 @@ public class ThreadMessage extends Thread implements Message {
     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();
@@ -48,29 +48,46 @@ public class ThreadMessage extends Thread implements Message {
             }
         }
         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 {
@@ -87,7 +104,7 @@ public class ThreadMessage extends Thread implements Message {
         }
     }
 
-    /** this is invoked in the MessageQueue thread */
+    /** this is invoked in the Message.Q thread */
     public void perform() {
         go.release();
         done.block();