From c9c4a33ef34e7b972de6c7cb5e31c81111873382 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 12 May 2008 22:06:30 +0000 Subject: [PATCH] [221899] Removed pre-processed example sources from CVS. --- .../dsf/dataviewer/AsyncDataViewer.java | 272 -------------- .../dataviewer/DataGeneratorWithExecutor.java | 336 ------------------ .../dataviewer/DataGeneratorWithThread.java | 238 ------------- .../dsf/dataviewer/IDataGenerator.java | 59 --- .../dsf/dataviewer/SyncDataViewer.java | 183 ---------- .../dataviewer/answers/AsyncDataViewer.java | 272 -------------- .../answers/DataGeneratorWithExecutor.java | 311 ---------------- .../answers/DataGeneratorWithThread.java | 238 ------------- .../dataviewer/answers/IDataGenerator.java | 59 --- .../dataviewer/answers/SyncDataViewer.java | 182 ---------- .../dsf/requestmonitor/Async2Plus2.java | 40 --- .../dsf/requestmonitor/AsyncHelloWorld.java | 46 --- .../dsf/requestmonitor/AsyncQuicksort.java | 111 ------ .../requestmonitor/answers/Async2Plus2.java | 40 --- .../answers/AsyncHelloWorld.java | 44 --- .../answers/AsyncQuicksort.java | 113 ------ .../dd/examples/dsf/timers/AlarmsVMNode.java | 22 +- .../dd/examples/dsf/timers/TimersVMNode.java | 19 +- .../examples/dsf/timers/TriggersVMNode.java | 14 +- 19 files changed, 18 insertions(+), 2581 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/AsyncDataViewer.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithExecutor.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithThread.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/IDataGenerator.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/SyncDataViewer.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/Async2Plus2.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncHelloWorld.java delete mode 100644 plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncQuicksort.java diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java deleted file mode 100644 index 54f2caad63a..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/AsyncDataViewer.java +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; - -/** - * Data viewer based on a table, which reads data using asynchronous methods. - *

- * This viewer implements the {@link ILazyContentProvider} interface - * which is used by the JFace TableViewer class to populate a Table. This - * interface contains separate asynchronous methods for requesting the count - * and values for individual indexes, which neatly correspond to the methods - * in {@link IDataGenerator}. As an added optimization, this viewer - * implementation checks for the range of visible items in the view upon each - * request, and it cancels old requests which scroll out of view but have not - * been completed yet. However, it is up to the data generator implementation - * to check the canceled state of the requests and ignore them. - *

- */ -@ConfinedToDsfExecutor("fDisplayExecutor") -public class AsyncDataViewer - implements ILazyContentProvider, IDataGenerator.Listener -{ - // Executor to use instead of Display.asyncExec(). - @ThreadSafe - final private DsfExecutor fDisplayExecutor; - - // The viewer and generator that this content provider using. - final private TableViewer fViewer; - final private IDataGenerator fDataGenerator; - - // Fields used in request cancellation logic. - private List fItemDataRequestMonitors = new LinkedList(); - private Set fIndexesToCancel = new HashSet(); - private int fCancelCallsPending = 0; - - public AsyncDataViewer(TableViewer viewer, IDataGenerator generator) { - fViewer = viewer; - fDisplayExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(fViewer.getTable().getDisplay()); - fDataGenerator = generator; - fDataGenerator.addListener(this); - } - - public void dispose() { - fDataGenerator.removeListener(this); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Set the initial count to the viewer after the input is set. - queryItemCount(); - } - - public void updateElement(final int index) { - // Calculate the visible index range. - final int topIdx = fViewer.getTable().getTopIndex(); - final int botIdx = topIdx + getVisibleItemCount(topIdx); - - // Request the item for the given index. - queryValue(index); - - // Invoke a cancel task with a delay. The delay allows multiple cancel - // calls to be combined together improving performance of the viewer. - fCancelCallsPending++; - fDisplayExecutor.schedule( - new Runnable() { public void run() { - cancelStaleRequests(topIdx, botIdx); - }}, - 1, TimeUnit.MILLISECONDS); - } - - private int getVisibleItemCount(int top) { - Table table = fViewer.getTable(); - int itemCount = table.getItemCount(); - return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); - } - - @ThreadSafe - public void countChanged() { - queryItemCount(); - } - - @ThreadSafe - public void valuesChanged(final Set indexes) { - // Mark the changed items in table viewer as dirty, this will - // trigger update requests for these indexes if they are - // visible in the viewer. - final TableViewer tableViewer = fViewer; - fDisplayExecutor.execute( new Runnable() { - public void run() { - if (!fViewer.getTable().isDisposed()) { - for (Integer index : indexes) { - tableViewer.clear(index); - } - } - }}); - } - - - private void queryItemCount() { - // Request count from data provider. When the count is returned, we - // have to re-dispatch into the display thread to avoid calling - // the table widget on the DSF dispatch thread. - fIndexesToCancel.clear(); - fDataGenerator.getCount( - // Use the display executor to construct the request monitor, this - // will cause the handleCompleted() method to be automatically - // called on the display thread. - new DataRequestMonitor(fDisplayExecutor, null) { - @Override - protected void handleCompleted() { - if (!fViewer.getTable().isDisposed()) { - fViewer.setItemCount(getData()); - fViewer.getTable().clearAll(); - } - } - }); - - } - - - // Dedicated class for data item requests. This class holds the index - // argument so it can be examined when canceling stale requests. - private class ValueDataRequestMonitor extends DataRequestMonitor { - - /** Index is used when canceling stale requests. */ - int fIndex; - - ValueDataRequestMonitor(int index) { - super(fDisplayExecutor, null); - fIndex = index; - } - - @Override - protected void handleCompleted() { - fItemDataRequestMonitors.remove(this); - - // Check if the request completed successfully, otherwise ignore it. - if (isSuccess()) { - if (!fViewer.getTable().isDisposed()) { - fViewer.replace(getData(), fIndex); - } - } - } - } - - private void queryValue(final int index) { - ValueDataRequestMonitor rm = new ValueDataRequestMonitor(index); - fItemDataRequestMonitors.add(rm); - fDataGenerator.getValue(index, rm); - } - - private void cancelStaleRequests(int topIdx, int botIdx) { - // Decrement the count of outstanding cancel calls. - fCancelCallsPending--; - - // Must check again, in case disposed while re-dispatching. - if (fDataGenerator == null || fViewer.getTable().isDisposed()) return; - - // Go through the outstanding requests and cancel any that - // are not visible anymore. - for (Iterator itr = fItemDataRequestMonitors.iterator(); itr.hasNext();) { - ValueDataRequestMonitor item = itr.next(); - if (item.fIndex < topIdx || item.fIndex > botIdx) { - // Set the item to canceled status, so that the data provider - // will ignore it. - item.cancel(); - - // Add the item index to list of indexes that were canceled, - // which will be sent to the table widget. - fIndexesToCancel.add(item.fIndex); - - // Remove the item from the outstanding cancel requests. - itr.remove(); - } - } - if (!fIndexesToCancel.isEmpty() && fCancelCallsPending == 0) { - Set canceledIdxs = fIndexesToCancel; - fIndexesToCancel = new HashSet(); - - // Clear the indexes of the canceled request, so that the - // viewer knows to request them again when needed. - // Note: clearing using TableViewer.clear(int) seems very - // inefficient, it's better to use Table.clear(int[]). - int[] canceledIdxsArray = new int[canceledIdxs.size()]; - int i = 0; - for (Integer index : canceledIdxs) { - canceledIdxsArray[i++] = index; - } - fViewer.getTable().clear(canceledIdxsArray); - } - } - - - public static void main(String[] args) { - // Create the shell to hold the viewer. - Display display = new Display(); - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - GridData data = new GridData(GridData.FILL_BOTH); - shell.setLayoutData(data); - Font font = new Font(display, "Courier", 10, SWT.NORMAL); - - // Create the table viewer. - TableViewer tableViewer = new TableViewer(shell, SWT.BORDER | SWT.VIRTUAL); - tableViewer.getControl().setLayoutData(data); - - // Create the data generator. - final IDataGenerator generator = new DataGeneratorWithExecutor(); - - // Create the content provider which will populate the viewer. - AsyncDataViewer contentProvider = new AsyncDataViewer(tableViewer, generator); - tableViewer.setContentProvider(contentProvider); - tableViewer.setInput(new Object()); - - // Open the shell and service the display dispatch loop until user - // closes the shell. - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - // The IDataGenerator.shutdown() method is asynchronous, this requires - // using a query again in order to wait for its completion. - Query shutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - generator.shutdown(rm); - } - }; - ImmediateExecutor.getInstance().execute(shutdownQuery); - try { - shutdownQuery.get(); - } catch (Exception e) {} - - // Shut down the display. - font.dispose(); - display.dispose(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java deleted file mode 100644 index 1b742b3fc62..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithExecutor.java +++ /dev/null @@ -1,336 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * DSF Executor-based implementation of the data generator. - *

- * This generator uses a queue of client requests and processes these - * requests periodically using a DSF executor. The main feature of this - * generator is that it uses the executor as its only synchronization object. - * This means that all the fields with the exception of the executor can only - * be accessed while running in the executor thread. - *

- */ -//TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) -//indicating allowed thread access to this class/method/member -public class DataGeneratorWithExecutor implements IDataGenerator { - - // Request objects are used to serialize the interface calls into objects - // which can then be pushed into a queue. - // TODO Ecercise 4 - Add an annotationindicating allowed concurrency access - // Hint: Request and its subclasses have all their fields declared as final. - abstract class Request { - final RequestMonitor fRequestMonitor; - - Request(RequestMonitor rm) { - fRequestMonitor = rm; - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - class CountRequest extends Request { - CountRequest(DataRequestMonitor rm) { - super(rm); - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - class ItemRequest extends Request { - final int fIndex; - ItemRequest(int index, DataRequestMonitor rm) { - super(rm); - fIndex = index; - } - } - - // The executor used to access all internal data of the generator. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - // Hint: If a member does not have an annotation, the programmer can assume - // that the concurrency rule that applies to the class also applies to this - // member. - private DsfExecutor fExecutor; - - // Main request queue of the data generator. The getValue(), getCount(), - // and shutdown() methods write into the queue, while the serviceQueue() - // method reads from it. - // The executor used to access all internal data of the generator. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private List fQueue = new LinkedList(); - - // List of listeners is not synchronized, it also has to be accessed - // using the executor. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private List fListeners = new LinkedList(); - - // Current number of elements in this generator. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private int fCount = MIN_COUNT; - - // Counter used to determine when to reset the element count. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private int fCountResetTrigger = 0; - - // Elements which were modified since the last reset. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private Set fChangedIndexes = new HashSet(); - - // Flag used to ensure that requests are processed sequentially. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private boolean fServiceQueueInProgress = false; - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public DataGeneratorWithExecutor() { - // Create the executor - fExecutor = new DefaultDsfExecutor("Supplier Executor"); - - // Schedule a runnable to make the random changes. - fExecutor.scheduleAtFixedRate( - new DsfRunnable() { - public void run() { - randomChanges(); - } - }, - RANDOM_CHANGE_INTERVAL, - RANDOM_CHANGE_INTERVAL, - TimeUnit.MILLISECONDS); - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public void shutdown(final RequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - // Empty the queue of requests and fail them. - for (Request request : fQueue) { - request.fRequestMonitor.setStatus( - new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - request.fRequestMonitor.done(); - } - fQueue.clear(); - - // Kill executor. - fExecutor.shutdown(); - rm.done(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public void getCount(final DataRequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fQueue.add(new CountRequest(rm)); - serviceQueue(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public void getValue(final int index, final DataRequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fQueue.add(new ItemRequest(index, rm)); - serviceQueue(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public void addListener(final Listener listener) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fListeners.add(listener); - } - }); - } catch (RejectedExecutionException e) {} - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - public void removeListener(final Listener listener) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fListeners.remove(listener); - } - }); - } catch (RejectedExecutionException e) {} - } - - // Main processing function of this generator. - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void serviceQueue() { - - // TODO Exercise 3 - Add logic to discard cancelled requests from queue. - // Hint: Since serviceQueue() is called using the executor, and the - // fQueue list can only be modified when running in the executor - // thread. This method can safely iterate and modify fQueue without - // risk of race conditions or concurrent modification exceptions. - - // If a queue servicing is already scheduled, do nothing. - if (fServiceQueueInProgress) { - return; - } - - if (fQueue.size() != 0) { - // If there are requests to service, remove one from the queue and - // schedule a runnable to process the request after a processing - // delay. - fServiceQueueInProgress = true; - final Request request = fQueue.remove(0); - fExecutor.schedule( - new DsfRunnable() { - public void run() { - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } - - // Reset the processing flag and process next - // request. - fServiceQueueInProgress = false; - serviceQueue(); - } - }, - PROCESSING_DELAY, TimeUnit.MILLISECONDS); - } - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void processCountRequest(CountRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - rm.setData(fCount); - rm.done(); - } - - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void processItemRequest(ItemRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - if (fChangedIndexes.contains(request.fIndex)) { - rm.setData("Changed: " + request.fIndex); - } else { - rm.setData(Integer.toString(request.fIndex)); - } - rm.done(); - } - - /** - * This method simulates changes in the supplier's data set. - */ - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void randomChanges() { - // Once every number of changes, reset the count, the rest of the - // times just change certain values. - if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ - randomCountReset(); - } else { - randomDataChange(); - } - } - - /** - * Calculates new size for provider's data set. - */ - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void randomCountReset() { - // Calculate the new count. - Random random = new java.util.Random(); - fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Reset the changed values. - fChangedIndexes.clear(); - - // Notify listeners - for (Listener listener : fListeners) { - listener.countChanged(); - } - } - - /** - * Invalidates a random range of indexes. - */ - // TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) - // indicating allowed thread access to this class/method/member - private void randomDataChange() { - // Calculate the indexes to change. - Random random = new java.util.Random(); - Set set = new HashSet(); - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); - } - - // Add the indexes to an overall set of changed indexes. - fChangedIndexes.addAll(set); - - // Notify listeners - for (Listener listener : fListeners) { - listener.valuesChanged(set); - } - } -} - diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java deleted file mode 100644 index 04fab7aaf2e..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/DataGeneratorWithThread.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * Thread-based implementation of the data generator. - *

- * This generator is based around a queue of client requests and a thread which - * reads the requests from the queue and processes them. The distinguishing - * feature of this generator is that it uses a a blocking queue as the main - * synchronization object. However, fListeners, fShutdown, and fChangedIndexes - * fields also need to be thread-safe and so they implement their own - * synchronization. - *

- */ -public class DataGeneratorWithThread extends Thread implements IDataGenerator { - - // Request objects are used to serialize the interface calls into objects - // which can then be pushed into a queue. - abstract class Request { - final RequestMonitor fRequestMonitor; - - Request(RequestMonitor rm) { - fRequestMonitor = rm; - } - } - - class CountRequest extends Request { - CountRequest(DataRequestMonitor rm) { - super(rm); - } - } - - class ItemRequest extends Request { - final int fIndex; - ItemRequest(int index, DataRequestMonitor rm) { - super(rm); - fIndex = index; - } - } - - class ShutdownRequest extends Request { - ShutdownRequest(RequestMonitor rm) { - super(rm); - } - } - - // Main request queue of the data generator. The getValue(), getCount(), - // and shutdown() methods write into the queue, while the run() method - // reads from it. - private final BlockingQueue fQueue = new LinkedBlockingQueue(); - - // ListenerList class provides thread safety. - private ListenerList fListeners = new ListenerList(); - - // Current number of elements in this generator. - private int fCount = MIN_COUNT; - - // Counter used to determine when to reset the element count. - private int fCountResetTrigger = 0; - - // Elements which were modified since the last reset. - private Set fChangedIndexes = Collections.synchronizedSet(new HashSet()); - - // Used to determine when to make changes in data. - private long fLastChangeTime = System.currentTimeMillis(); - - // Flag indicating when the generator has been shut down. - private AtomicBoolean fShutdown = new AtomicBoolean(false); - - public DataGeneratorWithThread() { - // Immediately kick off the request processing thread. - start(); - } - - public void shutdown(RequestMonitor rm) { - // Mark the generator as shut down. After the fShutdown flag is set, - // all new requests should be shut down. - if (!fShutdown.getAndSet(true)) { - fQueue.add(new ShutdownRequest(rm)); - } else { - // - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getCount(DataRequestMonitor rm) { - if (!fShutdown.get()) { - fQueue.add(new CountRequest(rm)); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getValue(int index, DataRequestMonitor rm) { - if (!fShutdown.get()) { - fQueue.add(new ItemRequest(index, rm)); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void addListener(Listener listener) { - fListeners.add(listener); - } - - public void removeListener(Listener listener) { - fListeners.remove(listener); - } - - @Override - public void run() { - try { - while(true) { - // Get the next request from the queue. The time-out - // ensures that that the random changes get processed. - final Request request = fQueue.poll(100, TimeUnit.MILLISECONDS); - - // If a request was dequeued, process it. - if (request != null) { - // Simulate a processing delay. - Thread.sleep(PROCESSING_DELAY); - - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } else if (request instanceof ShutdownRequest) { - // If shutting down, just break out of the while(true) - // loop and thread will exit. - request.fRequestMonitor.done(); - break; - } - } - - // Simulate data changes. - randomChanges(); - } - } - catch (InterruptedException x) {} - } - - private void processCountRequest(CountRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - rm.setData(fCount); - rm.done(); - } - - private void processItemRequest(ItemRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - if (fChangedIndexes.contains(request.fIndex)) { - rm.setData("Changed: " + request.fIndex); - } else { - rm.setData(Integer.toString(request.fIndex)); - } - rm.done(); - } - - - private void randomChanges() { - // Check if enough time is elapsed. - if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_INTERVAL) { - fLastChangeTime = System.currentTimeMillis(); - - // Once every number of changes, reset the count, the rest of the - // times just change certain values. - if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ - randomCountReset(); - } else { - randomDataChange(); - } - } - } - - private void randomCountReset() { - // Calculate the new count. - Random random = new java.util.Random(); - fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Reset the changed values. - fChangedIndexes.clear(); - - // Notify listeners - for (Object listener : fListeners.getListeners()) { - ((Listener)listener).countChanged(); - } - } - - private void randomDataChange() { - // Calculate the indexes to change. - Random random = new java.util.Random(); - Set set = new HashSet(); - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); - } - - // Add the indexes to an overall set of changed indexes. - fChangedIndexes.addAll(set); - - // Notify listeners - for (Object listener : fListeners.getListeners()) { - ((Listener)listener).valuesChanged(set); - } - } -} - - diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java deleted file mode 100644 index 066eda82377..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/IDataGenerator.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; - -/** - * Data generator is simple source of data used to populate the example table - * view. It contains two asynchronous methods for retrieving the data - * parameters: the count and the value for a given index. It also allows the - * view to receive events indicating when the data supplied by the generator - * is changed. - */ -// TODO Exercise 4 - Add an annotation (ThreadSafe/ConfinedToDsfExecutor) -// indicating allowed thread access to this class/method/member -public interface IDataGenerator { - - // Constants which control the data generator behavior. - // Changing the count range can stress the scalability of the system, while - // changing of the process delay and random change interval can stress - // its performance. - final static int MIN_COUNT = 100; - final static int MAX_COUNT = 200; - final static int PROCESSING_DELAY = 10; - final static int RANDOM_CHANGE_INTERVAL = 10000; - final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; - final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; - - - // Listener interface that the view needs to implement to react - // to the changes in data. - public interface Listener { - void countChanged(); - void valuesChanged(Set indexes); - } - - // Data access methods. - void getCount(DataRequestMonitor rm); - void getValue(int index, DataRequestMonitor rm); - - // Method used to shutdown the data generator including any threads that - // it may use. - void shutdown(RequestMonitor rm); - - // Methods for registering change listeners. - void addListener(Listener listener); - void removeListener(Listener listener); -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java deleted file mode 100644 index d4d4bdc7fe7..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/SyncDataViewer.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Data viewer based on a table, which reads data using synchronous methods. - *

- * This viewer implements the {@link IStructuredContentProvider} interface - * which is used by the JFace TableViewer class to populate a Table. This - * interface contains one principal methods for reading data {@link #getElements(Object)}, - * which synchronously returns an array of elements. In order to implement this - * method using the asynchronous data generator, this provider uses the - * {@link Query} object. - *

- */ -public class SyncDataViewer - implements IStructuredContentProvider, IDataGenerator.Listener -{ - // The viewer and generator that this content provider using. - final private TableViewer fViewer; - final private IDataGenerator fDataGenerator; - - public SyncDataViewer(TableViewer viewer, IDataGenerator generator) { - fViewer = viewer; - fDataGenerator = generator; - fDataGenerator.addListener(this); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Not used - } - - - public Object[] getElements(Object inputElement) { - - // Create the query object for reading data count. - Query countQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - fDataGenerator.getCount(rm); - } - }; - - // Submit the query to be executed. A query implements a runnable - // interface and it has to be executed in order to do its work. - ImmediateExecutor.getInstance().execute(countQuery); - int count = 0; - - // Block until the query completes, which will happen when the request - // monitor of the execute() method is marked done. - try { - count = countQuery.get(); - } catch (Exception e) { - // InterruptedException and ExecutionException can be thrown here. - // ExecutionException containing a CoreException will be thrown - // if an error status is set to the Query's request monitor. - return new Object[0]; - } - - // Create the array that will be filled with elements. - // For each index in the array execute a query to get the element at - // that index. - final Object[] elements = new Object[count]; - - for (int i = 0; i < count; i++) { - final int index = i; - Query valueQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - fDataGenerator.getValue(index, rm); - } - }; - ImmediateExecutor.getInstance().execute(valueQuery); - try { - elements[i] = valueQuery.get(); - } catch (Exception e) { - elements[i] = "error"; - } - } - return elements; - } - - public void dispose() { - fDataGenerator.removeListener(this); - } - - public void countChanged() { - // For any event from the generator, refresh the whole viewer. - refreshViewer(); - } - - public void valuesChanged(Set indexes) { - // For any event from the generator, refresh the whole viewer. - refreshViewer(); - } - - private void refreshViewer() { - // TODO Exercise 5 - Add a call to getElements() to force a deadlock. - - // This method may be called on any thread, switch to the display - // thread before calling the viewer. - Display display = fViewer.getControl().getDisplay(); - display.asyncExec( new Runnable() { - public void run() { - if (!fViewer.getControl().isDisposed()) { - fViewer.refresh(); - } - } - }); - } - - public static void main(String[] args) { - // Create the shell to hold the viewer. - Display display = new Display(); - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - GridData data = new GridData(GridData.FILL_BOTH); - shell.setLayoutData(data); - Font font = new Font(display, "Courier", 10, SWT.NORMAL); - - // Create the table viewer. - TableViewer tableViewer = new TableViewer(shell, SWT.BORDER); - tableViewer.getControl().setLayoutData(data); - - // Create the data generator. - // TODO Exercise 5 - Use the DataGeneratorWithExecutor() instead. - final IDataGenerator generator = new DataGeneratorWithThread(); - - // Create the content provider which will populate the viewer. - SyncDataViewer contentProvider = new SyncDataViewer(tableViewer, generator); - tableViewer.setContentProvider(contentProvider); - tableViewer.setInput(new Object()); - - // Open the shell and service the display dispatch loop until user - // closes the shell. - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - // The IDataGenerator.shutdown() method is asynchronous, this requires - // using a query again in order to wait for its completion. - Query shutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - generator.shutdown(rm); - } - }; - ImmediateExecutor.getInstance().execute(shutdownQuery); - try { - shutdownQuery.get(); - } catch (Exception e) {} - - // Shut down the display. - font.dispose(); - display.dispose(); - } - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/AsyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/AsyncDataViewer.java deleted file mode 100644 index 8c8195595a9..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/AsyncDataViewer.java +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer.answers; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.dd.dsf.ui.concurrent.DisplayDsfExecutor; -import org.eclipse.jface.viewers.ILazyContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; - -/** - * Data viewer based on a table, which reads data using asynchronous methods. - *

- * This viewer implements the {@link ILazyContentProvider} interface - * which is used by the JFace TableViewer class to populate a Table. This - * interface contains separate asynchronous methods for requesting the count - * and values for individual indexes, which neatly correspond to the methods - * in {@link IDataGenerator}. As an added optimization, this viewer - * implementation checks for the range of visible items in the view upon each - * request, and it cancels old requests which scroll out of view but have not - * been completed yet. However, it is up to the data generator implementation - * to check the canceled state of the requests and ignore them. - *

- */ -@ConfinedToDsfExecutor("fDisplayExecutor") -public class AsyncDataViewer - implements ILazyContentProvider, IDataGenerator.Listener -{ - // Executor to use instead of Display.asyncExec(). - @ThreadSafe - final private DsfExecutor fDisplayExecutor; - - // The viewer and generator that this content provider using. - final private TableViewer fViewer; - final private IDataGenerator fDataGenerator; - - // Fields used in request cancellation logic. - private List fItemDataRequestMonitors = new LinkedList(); - private Set fIndexesToCancel = new HashSet(); - private int fCancelCallsPending = 0; - - public AsyncDataViewer(TableViewer viewer, IDataGenerator generator) { - fViewer = viewer; - fDisplayExecutor = DisplayDsfExecutor.getDisplayDsfExecutor(fViewer.getTable().getDisplay()); - fDataGenerator = generator; - fDataGenerator.addListener(this); - } - - public void dispose() { - fDataGenerator.removeListener(this); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Set the initial count to the viewer after the input is set. - queryItemCount(); - } - - public void updateElement(final int index) { - // Calculate the visible index range. - final int topIdx = fViewer.getTable().getTopIndex(); - final int botIdx = topIdx + getVisibleItemCount(topIdx); - - // Request the item for the given index. - queryValue(index); - - // Invoke a cancel task with a delay. The delay allows multiple cancel - // calls to be combined together improving performance of the viewer. - fCancelCallsPending++; - fDisplayExecutor.schedule( - new Runnable() { public void run() { - cancelStaleRequests(topIdx, botIdx); - }}, - 1, TimeUnit.MILLISECONDS); - } - - private int getVisibleItemCount(int top) { - Table table = fViewer.getTable(); - int itemCount = table.getItemCount(); - return Math.min((table.getBounds().height / table.getItemHeight()) + 2, itemCount - top); - } - - @ThreadSafe - public void countChanged() { - queryItemCount(); - } - - @ThreadSafe - public void valuesChanged(final Set indexes) { - // Mark the changed items in table viewer as dirty, this will - // trigger update requests for these indexes if they are - // visible in the viewer. - final TableViewer tableViewer = fViewer; - fDisplayExecutor.execute( new Runnable() { - public void run() { - if (!fViewer.getTable().isDisposed()) { - for (Integer index : indexes) { - tableViewer.clear(index); - } - } - }}); - } - - - private void queryItemCount() { - // Request count from data provider. When the count is returned, we - // have to re-dispatch into the display thread to avoid calling - // the table widget on the DSF dispatch thread. - fIndexesToCancel.clear(); - fDataGenerator.getCount( - // Use the display executor to construct the request monitor, this - // will cause the handleCompleted() method to be automatically - // called on the display thread. - new DataRequestMonitor(fDisplayExecutor, null) { - @Override - protected void handleCompleted() { - if (!fViewer.getTable().isDisposed()) { - fViewer.setItemCount(getData()); - fViewer.getTable().clearAll(); - } - } - }); - - } - - - // Dedicated class for data item requests. This class holds the index - // argument so it can be examined when canceling stale requests. - private class ValueDataRequestMonitor extends DataRequestMonitor { - - /** Index is used when canceling stale requests. */ - int fIndex; - - ValueDataRequestMonitor(int index) { - super(fDisplayExecutor, null); - fIndex = index; - } - - @Override - protected void handleCompleted() { - fItemDataRequestMonitors.remove(this); - - // Check if the request completed successfully, otherwise ignore it. - if (isSuccess()) { - if (!fViewer.getTable().isDisposed()) { - fViewer.replace(getData(), fIndex); - } - } - } - } - - private void queryValue(final int index) { - ValueDataRequestMonitor rm = new ValueDataRequestMonitor(index); - fItemDataRequestMonitors.add(rm); - fDataGenerator.getValue(index, rm); - } - - private void cancelStaleRequests(int topIdx, int botIdx) { - // Decrement the count of outstanding cancel calls. - fCancelCallsPending--; - - // Must check again, in case disposed while re-dispatching. - if (fDataGenerator == null || fViewer.getTable().isDisposed()) return; - - // Go through the outstanding requests and cancel any that - // are not visible anymore. - for (Iterator itr = fItemDataRequestMonitors.iterator(); itr.hasNext();) { - ValueDataRequestMonitor item = itr.next(); - if (item.fIndex < topIdx || item.fIndex > botIdx) { - // Set the item to canceled status, so that the data provider - // will ignore it. - item.cancel(); - - // Add the item index to list of indexes that were canceled, - // which will be sent to the table widget. - fIndexesToCancel.add(item.fIndex); - - // Remove the item from the outstanding cancel requests. - itr.remove(); - } - } - if (!fIndexesToCancel.isEmpty() && fCancelCallsPending == 0) { - Set canceledIdxs = fIndexesToCancel; - fIndexesToCancel = new HashSet(); - - // Clear the indexes of the canceled request, so that the - // viewer knows to request them again when needed. - // Note: clearing using TableViewer.clear(int) seems very - // inefficient, it's better to use Table.clear(int[]). - int[] canceledIdxsArray = new int[canceledIdxs.size()]; - int i = 0; - for (Integer index : canceledIdxs) { - canceledIdxsArray[i++] = index; - } - fViewer.getTable().clear(canceledIdxsArray); - } - } - - - public static void main(String[] args) { - // Create the shell to hold the viewer. - Display display = new Display(); - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - GridData data = new GridData(GridData.FILL_BOTH); - shell.setLayoutData(data); - Font font = new Font(display, "Courier", 10, SWT.NORMAL); - - // Create the table viewer. - TableViewer tableViewer = new TableViewer(shell, SWT.BORDER | SWT.VIRTUAL); - tableViewer.getControl().setLayoutData(data); - - // Create the data generator. - final IDataGenerator generator = new DataGeneratorWithExecutor(); - - // Create the content provider which will populate the viewer. - AsyncDataViewer contentProvider = new AsyncDataViewer(tableViewer, generator); - tableViewer.setContentProvider(contentProvider); - tableViewer.setInput(new Object()); - - // Open the shell and service the display dispatch loop until user - // closes the shell. - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - // The IDataGenerator.shutdown() method is asynchronous, this requires - // using a query again in order to wait for its completion. - Query shutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - generator.shutdown(rm); - } - }; - ImmediateExecutor.getInstance().execute(shutdownQuery); - try { - shutdownQuery.get(); - } catch (Exception e) {} - - // Shut down the display. - font.dispose(); - display.dispose(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithExecutor.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithExecutor.java deleted file mode 100644 index 9d84110d1a5..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithExecutor.java +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer.answers; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor; -import org.eclipse.dd.dsf.concurrent.Immutable; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfExecutor; -import org.eclipse.dd.dsf.concurrent.DsfRunnable; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * DSF Executor-based implementation of the data generator. - *

- * This generator uses a queue of client requests and processes these - * requests periodically using a DSF executor. The main feature of this - * generator is that it uses the executor as its only synchronization object. - * This means that all the fields with the exception of the executor can only - * be accessed while running in the executor thread. - *

- */ -@ThreadSafe -public class DataGeneratorWithExecutor implements IDataGenerator { - - // Request objects are used to serialize the interface calls into objects - // which can then be pushed into a queue. - @Immutable - abstract class Request { - final RequestMonitor fRequestMonitor; - - Request(RequestMonitor rm) { - fRequestMonitor = rm; - } - } - - @Immutable - class CountRequest extends Request { - CountRequest(DataRequestMonitor rm) { - super(rm); - } - } - - @Immutable - class ItemRequest extends Request { - final int fIndex; - ItemRequest(int index, DataRequestMonitor rm) { - super(rm); - fIndex = index; - } - } - - // The executor used to access all internal data of the generator. - private DsfExecutor fExecutor; - - // Main request queue of the data generator. The getValue(), getCount(), - // and shutdown() methods write into the queue, while the serviceQueue() - // method reads from it. - // The executor used to access all internal data of the generator. - @ConfinedToDsfExecutor("fExecutor") - private List fQueue = new LinkedList(); - - // List of listeners is not synchronized, it also has to be accessed - // using the executor. - @ConfinedToDsfExecutor("fExecutor") - private List fListeners = new LinkedList(); - - // Current number of elements in this generator. - @ConfinedToDsfExecutor("fExecutor") - private int fCount = MIN_COUNT; - - // Counter used to determine when to reset the element count. - @ConfinedToDsfExecutor("fExecutor") - private int fCountResetTrigger = 0; - - // Elements which were modified since the last reset. - @ConfinedToDsfExecutor("fExecutor") - private Set fChangedIndexes = new HashSet(); - - // Flag used to ensure that requests are processed sequentially. - @ConfinedToDsfExecutor("fExecutor") - private boolean fServiceQueueInProgress = false; - - public DataGeneratorWithExecutor() { - // Create the executor - fExecutor = new DefaultDsfExecutor("Supplier Executor"); - - // Schedule a runnable to make the random changes. - fExecutor.scheduleAtFixedRate( - new DsfRunnable() { - public void run() { - randomChanges(); - } - }, - RANDOM_CHANGE_INTERVAL, - RANDOM_CHANGE_INTERVAL, - TimeUnit.MILLISECONDS); - } - - public void shutdown(final RequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - // Empty the queue of requests and fail them. - for (Request request : fQueue) { - request.fRequestMonitor.setStatus( - new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - request.fRequestMonitor.done(); - } - fQueue.clear(); - - // Kill executor. - fExecutor.shutdown(); - rm.done(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getCount(final DataRequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fQueue.add(new CountRequest(rm)); - serviceQueue(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getValue(final int index, final DataRequestMonitor rm) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fQueue.add(new ItemRequest(index, rm)); - serviceQueue(); - } - }); - } catch (RejectedExecutionException e) { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void addListener(final Listener listener) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fListeners.add(listener); - } - }); - } catch (RejectedExecutionException e) {} - } - - public void removeListener(final Listener listener) { - try { - fExecutor.execute( new DsfRunnable() { - public void run() { - fListeners.remove(listener); - } - }); - } catch (RejectedExecutionException e) {} - } - - // Main processing function of this generator. - @ConfinedToDsfExecutor("fExecutor") - private void serviceQueue() { - - for (Iterator requestItr = fQueue.iterator(); requestItr.hasNext();) { - Request request = requestItr.next(); - if (request.fRequestMonitor.isCanceled()) { - request.fRequestMonitor.setStatus( - new Status(IStatus.CANCEL, DsfExamplesPlugin.PLUGIN_ID, "Request canceled")); - request.fRequestMonitor.done(); - requestItr.remove(); - } - } - - // If a queue servicing is already scheduled, do nothing. - if (fServiceQueueInProgress) { - return; - } - - if (fQueue.size() != 0) { - // If there are requests to service, remove one from the queue and - // schedule a runnable to process the request after a processing - // delay. - fServiceQueueInProgress = true; - final Request request = fQueue.remove(0); - fExecutor.schedule( - new DsfRunnable() { - public void run() { - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } - - // Reset the processing flag and process next - // request. - fServiceQueueInProgress = false; - serviceQueue(); - } - }, - PROCESSING_DELAY, TimeUnit.MILLISECONDS); - } - } - - @ConfinedToDsfExecutor("fExecutor") - private void processCountRequest(CountRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - rm.setData(fCount); - rm.done(); - } - - @ConfinedToDsfExecutor("fExecutor") - private void processItemRequest(ItemRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - if (fChangedIndexes.contains(request.fIndex)) { - rm.setData("Changed: " + request.fIndex); - } else { - rm.setData(Integer.toString(request.fIndex)); - } - rm.done(); - } - - /** - * This method simulates changes in the supplier's data set. - */ - @ConfinedToDsfExecutor("fExecutor") - private void randomChanges() { - // Once every number of changes, reset the count, the rest of the - // times just change certain values. - if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ - randomCountReset(); - } else { - randomDataChange(); - } - } - - /** - * Calculates new size for provider's data set. - */ - @ConfinedToDsfExecutor("fExecutor") - private void randomCountReset() { - // Calculate the new count. - Random random = new java.util.Random(); - fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Reset the changed values. - fChangedIndexes.clear(); - - // Notify listeners - for (Listener listener : fListeners) { - listener.countChanged(); - } - } - - /** - * Invalidates a random range of indexes. - */ - @ConfinedToDsfExecutor("fExecutor") - private void randomDataChange() { - // Calculate the indexes to change. - Random random = new java.util.Random(); - Set set = new HashSet(); - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); - } - - // Add the indexes to an overall set of changed indexes. - fChangedIndexes.addAll(set); - - // Notify listeners - for (Listener listener : fListeners) { - listener.valuesChanged(set); - } - } -} - diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithThread.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithThread.java deleted file mode 100644 index 25bab2d5bc9..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/DataGeneratorWithThread.java +++ /dev/null @@ -1,238 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer.answers; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.Status; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.examples.dsf.DsfExamplesPlugin; - -/** - * Thread-based implementation of the data generator. - *

- * This generator is based around a queue of client requests and a thread which - * reads the requests from the queue and processes them. The distinguishing - * feature of this generator is that it uses a a blocking queue as the main - * synchronization object. However, fListeners, fShutdown, and fChangedIndexes - * fields also need to be thread-safe and so they implement their own - * synchronization. - *

- */ -public class DataGeneratorWithThread extends Thread implements IDataGenerator { - - // Request objects are used to serialize the interface calls into objects - // which can then be pushed into a queue. - abstract class Request { - final RequestMonitor fRequestMonitor; - - Request(RequestMonitor rm) { - fRequestMonitor = rm; - } - } - - class CountRequest extends Request { - CountRequest(DataRequestMonitor rm) { - super(rm); - } - } - - class ItemRequest extends Request { - final int fIndex; - ItemRequest(int index, DataRequestMonitor rm) { - super(rm); - fIndex = index; - } - } - - class ShutdownRequest extends Request { - ShutdownRequest(RequestMonitor rm) { - super(rm); - } - } - - // Main request queue of the data generator. The getValue(), getCount(), - // and shutdown() methods write into the queue, while the run() method - // reads from it. - private final BlockingQueue fQueue = new LinkedBlockingQueue(); - - // ListenerList class provides thread safety. - private ListenerList fListeners = new ListenerList(); - - // Current number of elements in this generator. - private int fCount = MIN_COUNT; - - // Counter used to determine when to reset the element count. - private int fCountResetTrigger = 0; - - // Elements which were modified since the last reset. - private Set fChangedIndexes = Collections.synchronizedSet(new HashSet()); - - // Used to determine when to make changes in data. - private long fLastChangeTime = System.currentTimeMillis(); - - // Flag indicating when the generator has been shut down. - private AtomicBoolean fShutdown = new AtomicBoolean(false); - - public DataGeneratorWithThread() { - // Immediately kick off the request processing thread. - start(); - } - - public void shutdown(RequestMonitor rm) { - // Mark the generator as shut down. After the fShutdown flag is set, - // all new requests should be shut down. - if (!fShutdown.getAndSet(true)) { - fQueue.add(new ShutdownRequest(rm)); - } else { - // - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getCount(DataRequestMonitor rm) { - if (!fShutdown.get()) { - fQueue.add(new CountRequest(rm)); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void getValue(int index, DataRequestMonitor rm) { - if (!fShutdown.get()) { - fQueue.add(new ItemRequest(index, rm)); - } else { - rm.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Supplier shut down")); - rm.done(); - } - } - - public void addListener(Listener listener) { - fListeners.add(listener); - } - - public void removeListener(Listener listener) { - fListeners.remove(listener); - } - - @Override - public void run() { - try { - while(true) { - // Get the next request from the queue. The time-out - // ensures that that the random changes get processed. - final Request request = fQueue.poll(100, TimeUnit.MILLISECONDS); - - // If a request was dequeued, process it. - if (request != null) { - // Simulate a processing delay. - Thread.sleep(PROCESSING_DELAY); - - if (request instanceof CountRequest) { - processCountRequest((CountRequest)request); - } else if (request instanceof ItemRequest) { - processItemRequest((ItemRequest)request); - } else if (request instanceof ShutdownRequest) { - // If shutting down, just break out of the while(true) - // loop and thread will exit. - request.fRequestMonitor.done(); - break; - } - } - - // Simulate data changes. - randomChanges(); - } - } - catch (InterruptedException x) {} - } - - private void processCountRequest(CountRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - rm.setData(fCount); - rm.done(); - } - - private void processItemRequest(ItemRequest request) { - @SuppressWarnings("unchecked") // Suppress warning about lost type info. - DataRequestMonitor rm = (DataRequestMonitor)request.fRequestMonitor; - - if (fChangedIndexes.contains(request.fIndex)) { - rm.setData("Changed: " + request.fIndex); - } else { - rm.setData(Integer.toString(request.fIndex)); - } - rm.done(); - } - - - private void randomChanges() { - // Check if enough time is elapsed. - if (System.currentTimeMillis() > fLastChangeTime + RANDOM_CHANGE_INTERVAL) { - fLastChangeTime = System.currentTimeMillis(); - - // Once every number of changes, reset the count, the rest of the - // times just change certain values. - if (++fCountResetTrigger % RANDOM_COUNT_CHANGE_INTERVALS == 0){ - randomCountReset(); - } else { - randomDataChange(); - } - } - } - - private void randomCountReset() { - // Calculate the new count. - Random random = new java.util.Random(); - fCount = MIN_COUNT + Math.abs(random.nextInt()) % (MAX_COUNT - MIN_COUNT); - - // Reset the changed values. - fChangedIndexes.clear(); - - // Notify listeners - for (Object listener : fListeners.getListeners()) { - ((Listener)listener).countChanged(); - } - } - - private void randomDataChange() { - // Calculate the indexes to change. - Random random = new java.util.Random(); - Set set = new HashSet(); - for (int i = 0; i < fCount * RANDOM_CHANGE_SET_PERCENTAGE / 100; i++) { - set.add( new Integer(Math.abs(random.nextInt()) % fCount) ); - } - - // Add the indexes to an overall set of changed indexes. - fChangedIndexes.addAll(set); - - // Notify listeners - for (Object listener : fListeners.getListeners()) { - ((Listener)listener).valuesChanged(set); - } - } -} - - diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/IDataGenerator.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/IDataGenerator.java deleted file mode 100644 index eb8348f8848..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/IDataGenerator.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer.answers; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.concurrent.ThreadSafe; - -/** - * Data generator is simple source of data used to populate the example table - * view. It contains two asynchronous methods for retrieving the data - * parameters: the count and the value for a given index. It also allows the - * view to receive events indicating when the data supplied by the generator - * is changed. - */ -@ThreadSafe -public interface IDataGenerator { - - // Constants which control the data generator behavior. - // Changing the count range can stress the scalability of the system, while - // changing of the process delay and random change interval can stress - // its performance. - final static int MIN_COUNT = 100; - final static int MAX_COUNT = 200; - final static int PROCESSING_DELAY = 10; - final static int RANDOM_CHANGE_INTERVAL = 10000; - final static int RANDOM_COUNT_CHANGE_INTERVALS = 3; - final static int RANDOM_CHANGE_SET_PERCENTAGE = 10; - - - // Listener interface that the view needs to implement to react - // to the changes in data. - public interface Listener { - void countChanged(); - void valuesChanged(Set indexes); - } - - // Data access methods. - void getCount(DataRequestMonitor rm); - void getValue(int index, DataRequestMonitor rm); - - // Method used to shutdown the data generator including any threads that - // it may use. - void shutdown(RequestMonitor rm); - - // Methods for registering change listeners. - void addListener(Listener listener); - void removeListener(Listener listener); -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/SyncDataViewer.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/SyncDataViewer.java deleted file mode 100644 index ef442cb2a9d..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/dataviewer/answers/SyncDataViewer.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.dataviewer.answers; - -import java.util.Set; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.Query; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Data viewer based on a table, which reads data using synchronous methods. - *

- * This viewer implements the {@link IStructuredContentProvider} interface - * which is used by the JFace TableViewer class to populate a Table. This - * interface contains one principal methods for reading data {@link #getElements(Object)}, - * which synchronously returns an array of elements. In order to implement this - * method using the asynchronous data generator, this provider uses the - * {@link Query} object. - *

- */ -public class SyncDataViewer - implements IStructuredContentProvider, IDataGenerator.Listener -{ - // The viewer and generator that this content provider using. - final private TableViewer fViewer; - final private IDataGenerator fDataGenerator; - - public SyncDataViewer(TableViewer viewer, IDataGenerator generator) { - fViewer = viewer; - fDataGenerator = generator; - fDataGenerator.addListener(this); - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Not used - } - - - public Object[] getElements(Object inputElement) { - - // Create the query object for reading data count. - Query countQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - fDataGenerator.getCount(rm); - } - }; - - // Submit the query to be executed. A query implements a runnable - // interface and it has to be executed in order to do its work. - ImmediateExecutor.getInstance().execute(countQuery); - int count = 0; - - // Block until the query completes, which will happen when the request - // monitor of the execute() method is marked done. - try { - count = countQuery.get(); - } catch (Exception e) { - // InterruptedException and ExecutionException can be thrown here. - // ExecutionException containing a CoreException will be thrown - // if an error status is set to the Query's request monitor. - return new Object[0]; - } - - // Create the array that will be filled with elements. - // For each index in the array execute a query to get the element at - // that index. - final Object[] elements = new Object[count]; - - for (int i = 0; i < count; i++) { - final int index = i; - Query valueQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - fDataGenerator.getValue(index, rm); - } - }; - ImmediateExecutor.getInstance().execute(valueQuery); - try { - elements[i] = valueQuery.get(); - } catch (Exception e) { - elements[i] = "error"; - } - } - return elements; - } - - public void dispose() { - fDataGenerator.removeListener(this); - } - - public void countChanged() { - // For any event from the generator, refresh the whole viewer. - refreshViewer(); - } - - public void valuesChanged(Set indexes) { - // For any event from the generator, refresh the whole viewer. - refreshViewer(); - } - - private void refreshViewer() { - getElements(null); - - // This method may be called on any thread, switch to the display - // thread before calling the viewer. - Display display = fViewer.getControl().getDisplay(); - display.asyncExec( new Runnable() { - public void run() { - if (!fViewer.getControl().isDisposed()) { - fViewer.refresh(); - } - } - }); - } - - public static void main(String[] args) { - // Create the shell to hold the viewer. - Display display = new Display(); - Shell shell = new Shell(display, SWT.SHELL_TRIM); - shell.setLayout(new GridLayout()); - GridData data = new GridData(GridData.FILL_BOTH); - shell.setLayoutData(data); - Font font = new Font(display, "Courier", 10, SWT.NORMAL); - - // Create the table viewer. - TableViewer tableViewer = new TableViewer(shell, SWT.BORDER); - tableViewer.getControl().setLayoutData(data); - - // Create the data generator. - final IDataGenerator generator = new DataGeneratorWithExecutor(); - - // Create the content provider which will populate the viewer. - SyncDataViewer contentProvider = new SyncDataViewer(tableViewer, generator); - tableViewer.setContentProvider(contentProvider); - tableViewer.setInput(new Object()); - - // Open the shell and service the display dispatch loop until user - // closes the shell. - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - // The IDataGenerator.shutdown() method is asynchronous, this requires - // using a query again in order to wait for its completion. - Query shutdownQuery = new Query() { - @Override - protected void execute(DataRequestMonitor rm) { - generator.shutdown(rm); - } - }; - ImmediateExecutor.getInstance().execute(shutdownQuery); - try { - shutdownQuery.get(); - } catch (Exception e) {} - - // Shut down the display. - font.dispose(); - display.dispose(); - } - -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java deleted file mode 100644 index 6fa56cb19c4..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/Async2Plus2.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor; - -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; - -/** - * Example of using a DataRequestMonitor to retrieve a result from an - * asynchronous method. - */ -public class Async2Plus2 { - - public static void main(String[] args) { - Executor executor = ImmediateExecutor.getInstance(); - DataRequestMonitor rm = - new DataRequestMonitor(executor, null) { - @Override - protected void handleCompleted() { - System.out.println("2 + 2 = " + getData()); - } - }; - asyncAdd(2, 2, rm); - } - - static void asyncAdd(int value1, int value2, DataRequestMonitor rm) { - rm.setData(value1 + value2); - rm.done(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java deleted file mode 100644 index 293c0b399f8..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncHelloWorld.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor; - -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; - -/** - * "Hello world" example which uses an asynchronous method to print out - * the result. - *

- * The main method uses an immediate executor, which executes runnables - * as soon as they are submitted, in creating its request monitor. - * - */ -public class AsyncHelloWorld { - - public static void main(String[] args) { - Executor executor = ImmediateExecutor.getInstance(); - RequestMonitor rm = new RequestMonitor(executor, null); - asyncHelloWorld(rm); - } - - static void asyncHelloWorld(RequestMonitor rm) { - System.out.println("Hello world"); - // TODO Exercise 1: - Call the second async. "Hello world 2" method. - // Hint: Calling an asynchronous method requires passing to it a - // request monitor. A new request monitor can be constructed with - // a parent RequestMonitor as an argument argument. The parent gets - // completed automatically when the lower level request monitor is - // completed. - rm.done(); - } - - // TODO: Exercise 1 - Add a second async. "Hello world 2" method. -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java deleted file mode 100644 index f6b6a16e86b..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/AsyncQuicksort.java +++ /dev/null @@ -1,111 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor; - -import java.util.Arrays; -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; - -/** - * Example of using a CountingRequestMonitor to wait for multiple - * asynchronous calls to complete. - */ -public class AsyncQuicksort { - - static Executor fgExecutor = ImmediateExecutor.getInstance(); - - public static void main(String[] args) { - final int[] array = {5, 7, 8, 3, 2, 1, 9, 5, 4}; - - System.out.println("To sort: " + Arrays.toString(array)); - asyncQuicksort( - array, 0, array.length - 1, - new RequestMonitor(fgExecutor, null) { - @Override - protected void handleCompleted() { - System.out.println("Sorted: " + Arrays.toString(array)); - } - }); - } - - static void asyncQuicksort(final int[] array, final int left, - final int right, final RequestMonitor rm) - { - if (right > left) { - int pivot = left; - // TODO: Exercise 2 - Convert the call to partition into an - // asynchronous call to asyncPartition(). - // Hint: The rest of the code below should be executed inside - // the DataRequestMonitor.handleCompleted() overriding method. - int newPivot = partition(array, left, right, pivot); - printArray(array, left, right, newPivot); - - CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); - asyncQuicksort(array, left, newPivot - 1, countingRm); - asyncQuicksort(array, newPivot + 1, right, countingRm); - countingRm.setDoneCount(2); - } else { - rm.done(); - } - } - - // TODO Exercise 2 - Convert partition to an asynchronous method. - // Hint: a DataRequestMonitor should be used to carry the - // return value to the caller. - static int partition(int[] array, int left, int right, int pivot) - { - int pivotValue = array[pivot]; - array[pivot] = array[right]; - array[right] = pivotValue; - int store = left; - for (int i = left; i < right; i++) { - if (array[i] <= pivotValue) { - int tmp = array[store]; - array[store] = array[i]; - array[i] = tmp; - store++; - } - } - array[right] = array[store]; - array[store] = pivotValue; - - // TODO: Request Monitors Exercise 2 - Return the data to caller using - // a request monitor. - return store; - } - - static void printArray(int[] array, int left, int right, int pivot) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < array.length; i++ ) { - if (i == left) { - buffer.append('>'); - } else if (i == pivot) { - buffer.append('-'); - } else { - buffer.append(' '); - } - buffer.append(array[i]); - - if (i == right) { - buffer.append('<'); - } else if (i == pivot) { - buffer.append('-'); - } else { - buffer.append(' '); - } - } - - System.out.println(buffer); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/Async2Plus2.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/Async2Plus2.java deleted file mode 100644 index d775c0c1e1e..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/Async2Plus2.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor.answers; - -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; - -/** - * Example of using a DataRequestMonitor to retrieve a result from an - * asynchronous method. - */ -public class Async2Plus2 { - - public static void main(String[] args) { - Executor executor = ImmediateExecutor.getInstance(); - DataRequestMonitor rm = - new DataRequestMonitor(executor, null) { - @Override - protected void handleCompleted() { - System.out.println("2 + 2 = " + getData()); - } - }; - asyncAdd(2, 2, rm); - } - - static void asyncAdd(int value1, int value2, DataRequestMonitor rm) { - rm.setData(value1 + value2); - rm.done(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncHelloWorld.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncHelloWorld.java deleted file mode 100644 index 89061748a35..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncHelloWorld.java +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor.answers; - -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; - -/** - * "Hello world" example which uses an asynchronous method to print out - * the result. - *

- * The main method uses an immediate executor, which executes runnables - * as soon as they are submitted, in creating its request monitor. - * - */ -public class AsyncHelloWorld { - - public static void main(String[] args) { - Executor executor = ImmediateExecutor.getInstance(); - RequestMonitor rm = new RequestMonitor(executor, null); - asyncHelloWorld(rm); - } - - static void asyncHelloWorld(RequestMonitor rm) { - System.out.println("Hello world"); - RequestMonitor rm2 = new RequestMonitor(ImmediateExecutor.getInstance(), rm); - asyncHelloWorld2(rm2); - } - - static void asyncHelloWorld2(RequestMonitor rm) { - System.out.println("Hello world 2"); - rm.done(); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncQuicksort.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncQuicksort.java deleted file mode 100644 index 10b510d389d..00000000000 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/requestmonitor/answers/AsyncQuicksort.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 Wind River Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wind River Systems - initial API and implementation - *******************************************************************************/ -package org.eclipse.dd.examples.dsf.requestmonitor.answers; - -import java.util.Arrays; -import java.util.concurrent.Executor; - -import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor; -import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; -import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; -import org.eclipse.dd.dsf.concurrent.RequestMonitor; - -/** - * Example of using a CountingRequestMonitor to wait for multiple - * asynchronous calls to complete. - */ -public class AsyncQuicksort { - - static Executor fgExecutor = ImmediateExecutor.getInstance(); - - public static void main(String[] args) { - final int[] array = {5, 7, 8, 3, 2, 1, 9, 5, 4}; - - System.out.println("To sort: " + Arrays.toString(array)); - asyncQuicksort( - array, 0, array.length - 1, - new RequestMonitor(fgExecutor, null) { - @Override - protected void handleCompleted() { - System.out.println("Sorted: " + Arrays.toString(array)); - } - }); - } - - static void asyncQuicksort(final int[] array, final int left, - final int right, final RequestMonitor rm) - { - if (right > left) { - int pivot = left; - asyncPartition( - array, left, right, pivot, - new DataRequestMonitor(fgExecutor, rm) { - @Override - protected void handleCompleted() { - int newPivot = getData(); - printArray(array, left, right, newPivot); - - CountingRequestMonitor countingRm = new CountingRequestMonitor(fgExecutor, rm); - asyncQuicksort(array, left, newPivot - 1, countingRm); - asyncQuicksort(array, newPivot + 1, right, countingRm); - countingRm.setDoneCount(2); - } - }); - } else { - rm.done(); - } - } - - static void asyncPartition(int[] array, int left, int right, int pivot, DataRequestMonitor rm) - { - int pivotValue = array[pivot]; - array[pivot] = array[right]; - array[right] = pivotValue; - int store = left; - for (int i = left; i < right; i++) { - if (array[i] <= pivotValue) { - int tmp = array[store]; - array[store] = array[i]; - array[i] = tmp; - store++; - } - } - array[right] = array[store]; - array[store] = pivotValue; - - // Java 5 automatically converts the int type of the store variable - // to an Integer object. - rm.setData(store); - rm.done(); - } - - static void printArray(int[] array, int left, int right, int pivot) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < array.length; i++ ) { - if (i == left) { - buffer.append('>'); - } else if (i == pivot) { - buffer.append('-'); - } else { - buffer.append(' '); - } - buffer.append(array[i]); - - if (i == right) { - buffer.append('<'); - } else if (i == pivot) { - buffer.append('-'); - } else { - buffer.append(' '); - } - } - - System.out.println(buffer); - } -} diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java index 4d67b00ac01..d4ad61525d1 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/AlarmsVMNode.java @@ -43,32 +43,22 @@ class AlarmsVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - // Check that the services are available - if ( getServicesTracker().getService(AlarmService.class) == null ) { - handleFailedUpdate(update); - return; - } - if ( getServicesTracker().getService(TimerService.class) == null ) { - handleFailedUpdate(update); - return; - } - - // Find the trigger and timer contexts. If not found, fail. + // Check that the service is available and find the trigger and timer contexts. + // If not found, fail. + AlarmService alarmService = getServicesTracker().getService(AlarmService.class, null); TriggerDMContext alarmDmc = findDmcInPath( update.getViewerInput(), update.getElementPath(), TriggerDMContext.class); TimerDMContext timerDmc = findDmcInPath( update.getViewerInput(), update.getElementPath(), TimerDMContext.class); - if (alarmDmc == null || timerDmc == null) { + if (alarmService == null || alarmDmc == null || timerDmc == null) { update.setStatus(new Status(IStatus.ERROR, DsfExamplesPlugin.PLUGIN_ID, "Required elements not found in path")); update.done(); return; } // Get the alarm context then check the triggered value. - final AlarmDMContext alarmStatusDmc = getServicesTracker().getService(AlarmService.class). - getAlarm(alarmDmc, timerDmc); - boolean triggered = getServicesTracker().getService(AlarmService.class). - isAlarmTriggered(alarmStatusDmc); + final AlarmDMContext alarmStatusDmc = alarmService.getAlarm(alarmDmc, timerDmc); + boolean triggered = alarmService.isAlarmTriggered(alarmStatusDmc); // Only return the alarm in list of elements if it is triggered. if (triggered) { diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java index d0714e4fe74..e9b8e4fa22a 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TimersVMNode.java @@ -84,14 +84,15 @@ class TimersVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if ( getServicesTracker().getService(TimerService.class) == null ) { + TimerService timerService = getServicesTracker().getService(TimerService.class, null); + if ( timerService == null ) { handleFailedUpdate(update); return; } // Retrieve the timer DMContexts, create the corresponding VMCs array, and // set them as result. - TimerDMContext[] timers = getServicesTracker().getService(TimerService.class).getTimers(); + TimerDMContext[] timers = timerService.getTimers(); fillUpdateWithVMCs(update, timers); update.done(); } @@ -116,21 +117,15 @@ class TimersVMNode extends AbstractDMVMNode @ConfinedToDsfExecutor("getSession#getExecutor") private void updatePropertiesInSessionThread(final IPropertiesUpdate update) { // Find the timer context in the element being updated - final TimerDMContext dmc = findDmcInPath( - update.getViewerInput(), update.getElementPath(), TimerDMContext.class); - + TimerDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), TimerDMContext.class); + TimerService timerService = getServicesTracker().getService(TimerService.class, null); + // If either update or service are not valid, fail the update and exit. - if ( dmc == null ) { + if ( dmc == null || timerService == null) { handleFailedUpdate(update); return; } - TimerService timerService = getServicesTracker().getService(TimerService.class, null); - if ( timerService == null ) { - handleFailedUpdate(update); - return; - } - int value = timerService.getTimerValue(dmc); if (value == -1) { diff --git a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java index 78f29ad4937..96c138000b2 100644 --- a/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java +++ b/plugins/org.eclipse.dd.examples.dsf/src/org/eclipse/dd/examples/dsf/timers/TriggersVMNode.java @@ -85,12 +85,13 @@ class TriggersVMNode extends AbstractDMVMNode @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { - if ( getServicesTracker().getService(AlarmService.class) == null ) { + AlarmService alarmService = getServicesTracker().getService(AlarmService.class, null); + if ( alarmService == null ) { handleFailedUpdate(update); return; } - TriggerDMContext[] triggers = getServicesTracker().getService(AlarmService.class).getTriggers(); + TriggerDMContext[] triggers = alarmService.getTriggers(); fillUpdateWithVMCs(update, triggers); update.done(); } @@ -120,19 +121,14 @@ class TriggersVMNode extends AbstractDMVMNode // Find the trigger context in the element being updated TriggerDMContext triggerCtx = findDmcInPath( update.getViewerInput(), update.getElementPath(), TriggerDMContext.class); + AlarmService alarmService = getServicesTracker().getService(AlarmService.class, null); // If either update or service are not valid, fail the update and return. - if ( triggerCtx == null ) { + if ( triggerCtx == null || alarmService == null) { handleFailedUpdate(update); return; } - AlarmService alarmService = getServicesTracker().getService(AlarmService.class, null); - if ( alarmService == null ) { - handleFailedUpdate(update); - return; - } - // Calculate and set the update properties. int value = alarmService.getTriggerValue(triggerCtx);