Commit | Line | Data |
---|---|---|
951d134a FC |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009, 2010 Ericsson | |
3 | * | |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Francois Chouinard - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
8c8bf09f ASL |
13 | package org.eclipse.linuxtools.tmf.request; |
14 | ||
9b635e61 | 15 | import java.util.Comparator; |
8c8bf09f | 16 | import java.util.concurrent.Executor; |
54d55ced | 17 | import java.util.concurrent.ExecutorService; |
8c8bf09f | 18 | import java.util.concurrent.Executors; |
9b635e61 FC |
19 | import java.util.concurrent.PriorityBlockingQueue; |
20 | ||
21 | import org.eclipse.linuxtools.tmf.Tracer; | |
22 | import org.eclipse.linuxtools.tmf.component.TmfThread; | |
23 | import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType; | |
8c8bf09f | 24 | |
951d134a FC |
25 | /** |
26 | * <b><u>TmfRequestExecutor</u></b> | |
27 | * | |
2fb2eb37 | 28 | * A simple, straightforward request executor. |
951d134a | 29 | */ |
8c8bf09f ASL |
30 | public class TmfRequestExecutor implements Executor { |
31 | ||
54d55ced | 32 | private final ExecutorService fExecutor; |
7a88aecf | 33 | private final String fExecutorName; |
9b635e61 | 34 | private final PriorityBlockingQueue<TmfThread> fRequestQueue = new PriorityBlockingQueue<TmfThread>(100, new Comparator<TmfThread>() { |
d4011df2 | 35 | @Override |
9b635e61 FC |
36 | public int compare(TmfThread o1, TmfThread o2) { |
37 | if (o1.getExecType() == o2.getExecType()) | |
38 | return 0; | |
f6b14ce2 | 39 | if (o1.getExecType() == ExecutionType.BACKGROUND) |
9b635e61 FC |
40 | return 1; |
41 | return -1; | |
42 | } | |
43 | }); | |
475743b7 | 44 | private TmfThread fCurrentRequest; |
5c00c0b7 FC |
45 | |
46 | // ------------------------------------------------------------------------ | |
47 | // Constructors | |
48 | // ------------------------------------------------------------------------ | |
8c8bf09f | 49 | |
fc6ccf6f FC |
50 | public TmfRequestExecutor() { |
51 | this(Executors.newSingleThreadExecutor()); | |
8c8bf09f | 52 | } |
fc6ccf6f | 53 | |
5c00c0b7 FC |
54 | public TmfRequestExecutor(ExecutorService executor) { |
55 | fExecutor = executor; | |
7a88aecf FC |
56 | String canonicalName = fExecutor.getClass().getCanonicalName(); |
57 | fExecutorName = canonicalName.substring(canonicalName.lastIndexOf('.') + 1); | |
3b38ea61 | 58 | if (Tracer.isComponentTraced()) Tracer.trace(fExecutor + " created"); //$NON-NLS-1$ |
54d55ced FC |
59 | } |
60 | ||
5c00c0b7 FC |
61 | /** |
62 | * @return the number of pending requests | |
63 | */ | |
1087f2b9 | 64 | public synchronized int getNbPendingRequests() { |
5c00c0b7 FC |
65 | return fRequestQueue.size(); |
66 | } | |
67 | ||
68 | /** | |
69 | * @return the shutdown state (i.e. if it is accepting new requests) | |
70 | */ | |
db1ea19b | 71 | public synchronized boolean isShutdown() { |
5c00c0b7 FC |
72 | return fExecutor.isShutdown(); |
73 | } | |
74 | ||
75 | /** | |
76 | * @return the termination state | |
77 | */ | |
1087f2b9 | 78 | public synchronized boolean isTerminated() { |
5c00c0b7 FC |
79 | return fExecutor.isTerminated(); |
80 | } | |
81 | ||
2fb2eb37 FC |
82 | /** |
83 | * Stops the executor | |
84 | */ | |
1087f2b9 | 85 | public synchronized void stop() { |
475743b7 FC |
86 | if (fCurrentRequest != null) { |
87 | fCurrentRequest.cancel(); | |
88 | } | |
1087f2b9 BH |
89 | |
90 | while ((fCurrentRequest = fRequestQueue.poll()) != null) { | |
91 | fCurrentRequest.cancel(); | |
92 | } | |
93 | ||
54d55ced | 94 | fExecutor.shutdown(); |
3b38ea61 | 95 | if (Tracer.isComponentTraced()) Tracer.trace(fExecutor + " terminated"); //$NON-NLS-1$ |
54d55ced FC |
96 | } |
97 | ||
5c00c0b7 FC |
98 | // ------------------------------------------------------------------------ |
99 | // Operations | |
100 | // ------------------------------------------------------------------------ | |
101 | ||
2fb2eb37 FC |
102 | /* (non-Javadoc) |
103 | * @see java.util.concurrent.Executor#execute(java.lang.Runnable) | |
104 | */ | |
d4011df2 | 105 | @Override |
9b635e61 FC |
106 | public synchronized void execute(final Runnable requestThread) { |
107 | fRequestQueue.offer(new TmfThread(((TmfThread) requestThread).getExecType()) { | |
108 | @Override | |
8c8bf09f ASL |
109 | public void run() { |
110 | try { | |
9b635e61 | 111 | requestThread.run(); |
8c8bf09f ASL |
112 | } finally { |
113 | scheduleNext(); | |
114 | } | |
115 | } | |
475743b7 FC |
116 | @Override |
117 | public void cancel() { | |
118 | ((TmfThread) requestThread).cancel(); | |
119 | } | |
8c8bf09f | 120 | }); |
5c00c0b7 | 121 | if (fCurrentRequest == null) { |
8c8bf09f ASL |
122 | scheduleNext(); |
123 | } | |
124 | } | |
125 | ||
2fb2eb37 FC |
126 | /** |
127 | * Executes the next pending request, if applicable. | |
128 | */ | |
8c8bf09f | 129 | protected synchronized void scheduleNext() { |
5c00c0b7 | 130 | if ((fCurrentRequest = fRequestQueue.poll()) != null) { |
db1ea19b FC |
131 | if (!isShutdown()) |
132 | fExecutor.execute(fCurrentRequest); | |
8c8bf09f ASL |
133 | } |
134 | } | |
135 | ||
5c00c0b7 FC |
136 | // ------------------------------------------------------------------------ |
137 | // Object | |
138 | // ------------------------------------------------------------------------ | |
139 | ||
140 | @Override | |
3b38ea61 | 141 | @SuppressWarnings("nls") |
5c00c0b7 | 142 | public String toString() { |
7a88aecf | 143 | return "[TmfRequestExecutor(" + fExecutorName + ")]"; |
8c8bf09f ASL |
144 | } |
145 | ||
146 | } |