1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Added support for pre-emption
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.request
;
16 import java
.util
.Queue
;
17 import java
.util
.concurrent
.ArrayBlockingQueue
;
18 import java
.util
.concurrent
.Executor
;
19 import java
.util
.concurrent
.ExecutorService
;
20 import java
.util
.concurrent
.Executors
;
22 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.TmfCoreTracer
;
23 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.component
.TmfEventThread
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfDataRequest
.ExecutionType
;
27 * A simple, straightforward request executor.
29 * @author Francois Chouinard
32 public class TmfRequestExecutor
implements Executor
{
34 // ------------------------------------------------------------------------
36 // ------------------------------------------------------------------------
38 // The request executor
39 private final ExecutorService fExecutor
= Executors
.newFixedThreadPool(2);
40 private final String fExecutorName
;
43 private final Queue
<TmfEventThread
> fHighPriorityTasks
= new ArrayBlockingQueue
<TmfEventThread
>(100);
44 private final Queue
<TmfEventThread
> fLowPriorityTasks
= new ArrayBlockingQueue
<TmfEventThread
>(100);
47 private TmfEventThread fActiveTask
;
48 private TmfEventThread fSuspendedTask
;
50 // ------------------------------------------------------------------------
52 // ------------------------------------------------------------------------
57 public TmfRequestExecutor() {
58 String canonicalName
= fExecutor
.getClass().getCanonicalName();
59 fExecutorName
= canonicalName
.substring(canonicalName
.lastIndexOf('.') + 1);
60 if (TmfCoreTracer
.isComponentTraced()) {
61 TmfCoreTracer
.trace(fExecutor
+ " created"); //$NON-NLS-1$
66 * Standard constructor
68 * @param executor The executor service to use
71 public TmfRequestExecutor(ExecutorService executor
) {
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
80 * @return the number of pending requests
83 public synchronized int getNbPendingRequests() {
84 return fHighPriorityTasks
.size() + fLowPriorityTasks
.size();
88 * @return the shutdown state (i.e. if it is accepting new requests)
90 public synchronized boolean isShutdown() {
91 return fExecutor
.isShutdown();
95 * @return the termination state
97 public synchronized boolean isTerminated() {
98 return fExecutor
.isTerminated();
101 // ------------------------------------------------------------------------
103 // ------------------------------------------------------------------------
106 * @see java.util.concurrent.Executor#execute(java.lang.Runnable)
109 public synchronized void execute(final Runnable command
) {
111 // We are expecting MyEventThread:s
112 if (!(command
instanceof TmfEventThread
)) {
113 // TODO: Log an error
117 // Wrap the thread in a MyThread
118 TmfEventThread thread
= (TmfEventThread
) command
;
119 TmfEventThread wrapper
= new TmfEventThread(thread
) {
130 // Add the thread to the appropriate queue
131 ExecutionType priority
= thread
.getExecType();
132 (priority
== ExecutionType
.FOREGROUND ? fHighPriorityTasks
: fLowPriorityTasks
).offer(wrapper
);
134 // Schedule or preempt as appropriate
135 if (fActiveTask
== null) {
137 } else if (priority
== ExecutionType
.FOREGROUND
&& priority
!= fActiveTask
.getExecType()) {
138 fActiveTask
.getThread().suspend();
139 fSuspendedTask
= fActiveTask
;
145 * Executes the next pending request, if applicable.
147 protected synchronized void scheduleNext() {
149 if ((fActiveTask
= fHighPriorityTasks
.poll()) != null) {
150 fExecutor
.execute(fActiveTask
);
151 } else if (fSuspendedTask
!= null) {
152 fActiveTask
= fSuspendedTask
;
153 fSuspendedTask
= null;
154 fActiveTask
.getThread().resume();
155 } else if ((fActiveTask
= fLowPriorityTasks
.poll()) != null) {
156 fExecutor
.execute(fActiveTask
);
164 public synchronized void stop() {
165 if (fActiveTask
!= null) {
166 fActiveTask
.cancel();
169 while ((fActiveTask
= fHighPriorityTasks
.poll()) != null) {
170 fActiveTask
.cancel();
173 fExecutor
.shutdown();
174 if (TmfCoreTracer
.isComponentTraced()) {
175 TmfCoreTracer
.trace(fExecutor
+ " terminated"); //$NON-NLS-1$
179 // ------------------------------------------------------------------------
181 // ------------------------------------------------------------------------
184 @SuppressWarnings("nls")
185 public String
toString() {
186 return "[TmfRequestExecutor(" + fExecutorName
+ ")]";