001: /*
002: * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
003: * Copyright (C) 2006 - Javolution (http://javolution.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package javolution.context;
010:
011: import j2mex.realtime.MemoryArea;
012: import j2mex.realtime.RealtimeThread;
013: import javolution.lang.Reflection;
014:
015: /**
016: * <p> This class represents the concurrent executors used by the default
017: * implementation of {@link ConcurrentContext}. Executions
018: * are performed in the same memory area and at the same priority
019: * as the calling thread.</p>
020: *
021: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
022: * @version 5.1, July 1, 2007
023: */
024: class ConcurrentThread extends RealtimeThread {
025:
026: private volatile Runnable _logic;
027:
028: private MemoryArea _memoryArea;
029:
030: private int _priority;
031:
032: private ConcurrentContext.Default _context;
033:
034: private boolean _terminate;
035:
036: private String _name;
037:
038: private Thread _source;
039:
040: /**
041: * Default constructor.
042: */
043: public ConcurrentThread() {
044: _name = "ConcurrentThread-" + getCount();
045: if (SET_NAME != null) {
046: SET_NAME.invoke(this , _name);
047: }
048: if (SET_DAEMON != null) {
049: SET_DAEMON.invoke(this , new Boolean(true));
050: }
051: }
052:
053: private synchronized int getCount() {
054: return _Count++;
055: }
056:
057: private static int _Count;
058:
059: private static final Reflection.Method SET_NAME = Reflection
060: .getMethod("java.lang.Thread.setName(String)");
061:
062: private static final Reflection.Method SET_DAEMON = Reflection
063: .getMethod("java.lang.Thread.setDaemon(boolean)");
064:
065: /**
066: * Executes the concurrent logics sequentially.
067: */
068: public void run() {
069: while (true) { // Main loop.
070: synchronized (this ) { // Waits for a task.
071: try {
072: while ((_logic == null) && !_terminate)
073: this .wait();
074: } catch (InterruptedException e) {
075: throw new ConcurrentException(e);
076: }
077: }
078: if (_logic == null)
079: break; // Terminates.
080: try {
081: Thread current = Thread.currentThread();
082: if (current.getPriority() != _priority) {
083: current.setPriority(_priority);
084: }
085: _context.started();
086: _memoryArea.executeInArea(_logic);
087: } catch (Throwable error) {
088: _context.error(error);
089: } finally {
090: _context.completed();
091: _logic = null; // Last (ready).
092: }
093: }
094: }
095:
096: /**
097: * Executes the specified logic by this thread if ready.
098: *
099: * @param logic the logic to execute.
100: * @param context the concurrent context.
101: */
102: public boolean execute(Runnable logic,
103: ConcurrentContext.Default context) {
104: if (_logic != null)
105: return false; // Shortcut to avoid synchronizing.
106: synchronized (this ) {
107: if (_logic != null)
108: return false; // Synchronized check.
109: _memoryArea = RealtimeThread.getCurrentMemoryArea();
110: _priority = Thread.currentThread().getPriority();
111: _context = context;
112: _logic = logic; // Must be last.
113: this .notify();
114: return true;
115: }
116: }
117:
118: // Implements ConcurrentExecutor
119: public void terminate() {
120: synchronized (this ) {
121: _terminate = true;
122: this .notify();
123: }
124: }
125:
126: /**
127: * Returns the name of this concurrent thread as well as its calling source
128: * (in parenthesis).
129: *
130: * @return the string representation of this thread.
131: */
132: public String toString() {
133: return _name + "(" + _source + ")";
134: }
135:
136: }
|