001: /*=============================================================================
002: * Copyright Texas Instruments 2005. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.util;
022:
023: import java.util.*;
024:
025: /**
026: * A common minimum priority worker thread for all background tasks.
027: *
028: * @author Rob Clark (rob@ti.com)
029: * @version 1
030: */
031: public class WorkerThread extends Thread {
032: private static final Runnable[] EMPTY_RUNNABLES = new Runnable[0];
033:
034: private static Runnable[] runnables = EMPTY_RUNNABLES;
035: private static LinkedList runnableList = new LinkedList();
036:
037: private static LinkedList oneShotRunnables = new LinkedList();
038:
039: private static WorkerThread worker = new WorkerThread();
040:
041: private WorkerThread() {
042: super ("background worker");
043: setPriority(MIN_PRIORITY);
044: setDaemon(true);
045: start();
046: }
047:
048: /**
049: * Call the specified runnable from the worker thread as soon as possible.
050: */
051: public static synchronized void invokeLater(Runnable r) {
052: oneShotRunnables.add(r);
053: synchronized (worker) {
054: worker.notify();
055: }
056: }
057:
058: /**
059: * Add a runnable to be called periodically from the background worker thread.
060: *
061: * @param r the runnable
062: * @param freq how frequently (in ms) should the worker attempt to run
063: * the runnable. Of course higher priority tasks can cause the runnable
064: * to be run less frequently. <b>(note: not implemented yet... everything
065: * is currently hard coded to 500ms)</b>
066: */
067: public static synchronized void addRunnable(Runnable r,
068: int frequency) {
069: runnables = null;
070: runnableList.add(r);
071: }
072:
073: /**
074: * Remove a runnable.
075: */
076: public static synchronized void removeRunnable(Runnable r) {
077: runnables = null;
078: runnableList.remove(r);
079: }
080:
081: private static synchronized Runnable[] getOneShotRunnables() {
082: if (oneShotRunnables.size() == 0)
083: return EMPTY_RUNNABLES;
084: LinkedList tmp = oneShotRunnables;
085: oneShotRunnables = new LinkedList();
086: return (Runnable[]) (tmp.toArray(new Runnable[tmp.size()]));
087: }
088:
089: private static synchronized Runnable[] getRunnables() {
090: if (runnables == null) {
091: if (runnableList.size() == 0)
092: runnables = EMPTY_RUNNABLES;
093: else
094: runnables = (Runnable[]) (runnableList
095: .toArray(new Runnable[runnableList.size()]));
096: }
097: return runnables;
098: }
099:
100: public void run() {
101: while (true) {
102: try {
103: synchronized (this ) {
104: this .wait(500);
105: }
106:
107: Runnable[] runnables = getOneShotRunnables();
108: for (int i = 0; i < runnables.length; i++)
109: runnables[i].run();
110:
111: // note: keep our own copy, because the list may change beneth us:
112: runnables = getRunnables();
113: for (int i = 0; i < runnables.length; i++)
114: if (runnableList.contains(runnables[i]))
115: runnables[i].run();
116: } catch (Throwable t) {
117: t.printStackTrace(); // XXX
118: }
119: }
120: }
121: }
122:
123: /*
124: * Local Variables:
125: * tab-width: 2
126: * indent-tabs-mode: nil
127: * mode: java
128: * c-indentation-style: java
129: * c-basic-offset: 2
130: * eval: (c-set-offset 'substatement-open '0)
131: * eval: (c-set-offset 'case-label '+)
132: * eval: (c-set-offset 'inclass '+)
133: * eval: (c-set-offset 'inline-open '0)
134: * End:
135: */
|