Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/EventManager.java416
1 files changed, 0 insertions, 416 deletions
diff --git a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/EventManager.java b/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/EventManager.java
deleted file mode 100644
index 2dc7188c7..000000000
--- a/bundles/org.eclipse.osgi/supplement/src/org/eclipse/osgi/framework/eventmgr/EventManager.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation 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:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.osgi.framework.eventmgr;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.*;
-
-/**
- * This class is the central class for the Event Manager. Each
- * program that wishes to use the Event Manager should construct
- * an EventManager object and use that object to construct
- * ListenerQueue for dispatching events. CopyOnWriteIdentityMap objects
- * must be used to manage listener lists.
- *
- * <p>This example uses the fictitious SomeEvent class and shows how to use this package
- * to deliver a SomeEvent to a set of SomeEventListeners.
- * <pre>
- *
- * // Create an EventManager with a name for an asynchronous event dispatch thread
- * EventManager eventManager = new EventManager("SomeEvent Async Event Dispatcher Thread");
- * // Create a CopyOnWriteIdentityMap to hold the list of SomeEventListeners
- * Map eventListeners = new CopyOnWriteIdentityMap();
- *
- * // Add a SomeEventListener to the listener list
- * eventListeners.put(someEventListener, null);
- *
- * // Asynchronously deliver a SomeEvent to registered SomeEventListeners
- * // Create the listener queue for this event delivery
- * ListenerQueue listenerQueue = new ListenerQueue(eventManager);
- * // Add the listeners to the queue and associate them with the event dispatcher
- * listenerQueue.queueListeners(eventListeners.entrySet(), new EventDispatcher() {
- * public void dispatchEvent(Object eventListener, Object listenerObject,
- * int eventAction, Object eventObject) {
- * try {
- * (SomeEventListener)eventListener.someEventOccured((SomeEvent)eventObject);
- * } catch (Throwable t) {
- * // properly log/handle any Throwable thrown by the listener
- * }
- * }
- * });
- * // Deliver the event to the listeners.
- * listenerQueue.dispatchEventAsynchronous(0, new SomeEvent());
- *
- * // Remove the listener from the listener list
- * eventListeners.remove(someEventListener);
- *
- * // Close EventManager to clean when done to terminate async event dispatch thread.
- * // Note that closing the event manager while asynchronously delivering events
- * // may cause some events to not be delivered before the async event dispatch
- * // thread terminates
- * eventManager.close();
- * </pre>
- *
- * <p>At first glance, this package may seem more complicated than necessary
- * but it has support for some important features. The listener list supports
- * companion objects for each listener object. This is used by the OSGi framework
- * to create wrapper objects for a listener which are passed to the event dispatcher.
- * The ListenerQueue class is used to build a snap shot of the listeners prior to beginning
- * event dispatch.
- *
- * The OSGi framework uses a 2 level listener list for each listener type (4 types).
- * Level one is managed per framework instance and contains the list of BundleContexts which have
- * registered a listener. Level 2 is managed per BundleContext for the listeners in that
- * context. This allows all the listeners of a bundle to be easily and atomically removed from
- * the level one list. To use a "flat" list for all bundles would require the list to know which
- * bundle registered a listener object so that the list could be traversed when stopping a bundle
- * to remove all the bundle's listeners.
- *
- * When an event is fired, a snapshot list (ListenerQueue) must be made of the current listeners before delivery
- * is attempted. The snapshot list is necessary to allow the listener list to be modified while the
- * event is being delivered to the snapshot list. The memory cost of the snapshot list is
- * low since the ListenerQueue object uses the copy-on-write semantics
- * of the CopyOnWriteIdentityMap. This guarantees the snapshot list is never modified once created.
- *
- * The OSGi framework also uses a 2 level dispatch technique (EventDispatcher).
- * Level one dispatch is used by the framework to add the level 2 listener list of each
- * BundleContext to the snapshot in preparation for delivery of the event.
- * Level 2 dispatch is used as the final event deliverer and must cast the listener
- * and event objects to the proper type before calling the listener. Level 2 dispatch
- * will cancel delivery of an event
- * to a bundle that has stopped between the time the snapshot was created and the
- * attempt was made to deliver the event.
- *
- * <p> The highly dynamic nature of the OSGi framework had necessitated these features for
- * proper and efficient event delivery.
- * @since 3.1
- * @noextend This class is not intended to be subclassed by clients.
- */
-
-public class EventManager {
- static final boolean DEBUG = false;
-
- /**
- * EventThread for asynchronous dispatch of events.
- * Access to this field must be protected by a synchronized region.
- */
- private EventThread thread;
-
- /**
- * Once closed, an attempt to create a new EventThread will result in an
- * IllegalStateException.
- */
- private boolean closed;
-
- /**
- * Thread name used for asynchronous event delivery
- */
- protected final String threadName;
-
- /**
- * The thread group used for asynchronous event delivery
- */
- protected final ThreadGroup threadGroup;
-
- /**
- * EventManager constructor. An EventManager object is responsible for
- * the delivery of events to listeners via an EventDispatcher.
- *
- */
- public EventManager() {
- this(null, null);
- }
-
- /**
- * EventManager constructor. An EventManager object is responsible for
- * the delivery of events to listeners via an EventDispatcher.
- *
- * @param threadName The name to give the event thread associated with
- * this EventManager. A <code>null</code> value is allowed.
- */
- public EventManager(String threadName) {
- this(threadName, null);
- }
-
- /**
- * EventManager constructor. An EventManager object is responsible for
- * the delivery of events to listeners via an EventDispatcher.
- *
- * @param threadName The name to give the event thread associated with
- * this EventManager. A <code>null</code> value is allowed.
- * @param threadGroup The thread group to use for the asynchronous event
- * thread associated with this EventManager. A <code>null</code> value is allowed.
- * @since 3.4
- */
- public EventManager(String threadName, ThreadGroup threadGroup) {
- thread = null;
- closed = false;
- this.threadName = threadName;
- this.threadGroup = threadGroup;
- }
-
- /**
- * This method can be called to release any resources associated with this
- * EventManager.
- * <p>
- * Closing this EventManager while it is asynchronously delivering events
- * may cause some events to not be delivered before the async event dispatch
- * thread terminates.
- */
- public synchronized void close() {
- if (closed) {
- return;
- }
- if (thread != null) {
- thread.close();
- thread = null;
- }
- closed = true;
- }
-
- /**
- * Returns the EventThread to use for dispatching events asynchronously for
- * this EventManager.
- *
- * @return EventThread to use for dispatching events asynchronously for
- * this EventManager.
- */
- synchronized EventThread getEventThread() {
- if (closed) {
- throw new IllegalStateException();
- }
- if (thread == null) {
- /* if there is no thread, then create a new one */
- thread = (EventThread) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- EventThread t = new EventThread(threadGroup, threadName);
- return t;
- }
- });
- /* start the new thread */
- thread.start();
- }
- return thread;
- }
-
- /**
- * This method calls the EventDispatcher object to complete the dispatch of
- * the event. If there are more elements in the list, call dispatchEvent
- * on the next item on the list.
- * This method is package private.
- *
- * @param listeners A Set of entries from a CopyOnWriteIdentityMap map.
- * @param dispatcher Call back object which is called to complete the delivery of
- * the event.
- * @param eventAction This value was passed by the event source and
- * is passed to this method. This is passed on to the call back object.
- * @param eventObject This object was created by the event source and
- * is passed to this method. This is passed on to the call back object.
- */
- static void dispatchEvent(Set/*<Map.Entry<Object,Object>>*/listeners, EventDispatcher dispatcher, int eventAction, Object eventObject) {
- for (Iterator iter = listeners.iterator(); iter.hasNext();) { /* iterate over the list of listeners */
- Map.Entry listener = (Map.Entry) iter.next();
- Object eventListener = listener.getKey();
- Object listenerObject = listener.getValue();
- try {
- /* Call the EventDispatcher to complete the delivery of the event. */
- dispatcher.dispatchEvent(eventListener, listenerObject, eventAction, eventObject);
- } catch (Throwable t) {
- /* Consume and ignore any exceptions thrown by the listener */
- if (DEBUG) {
- System.out.println("Exception in " + listener.getKey()); //$NON-NLS-1$
- t.printStackTrace();
- }
- }
- }
- }
-
- /**
- * This package private class is used for asynchronously dispatching events.
- */
-
- static class EventThread extends Thread {
- private static int nextThreadNumber;
-
- /**
- * Queued is a nested top-level (non-member) class. This class
- * represents the items which are placed on the asynch dispatch queue.
- * This class is private.
- */
- private static class Queued {
- /** listener list for this event */
- final Set/*<Map.Entry<Object,Object>>*/listeners;
- /** dispatcher of this event */
- final EventDispatcher dispatcher;
- /** action for this event */
- final int action;
- /** object for this event */
- final Object object;
- /** next item in event queue */
- Queued next;
-
- /**
- * Constructor for event queue item
- *
- * @param l Listener list for this event
- * @param d Dispatcher for this event
- * @param a Action for this event
- * @param o Object for this event
- */
- Queued(Set/*<Map.Entry<Object,Object>>*/l, EventDispatcher d, int a, Object o) {
- listeners = l;
- dispatcher = d;
- action = a;
- object = o;
- next = null;
- }
- }
-
- /** item at the head of the event queue */
- private Queued head;
- /** item at the tail of the event queue */
- private Queued tail;
- /** if false the thread must terminate */
- private volatile boolean running;
-
- /**
- * Constructor for the event thread.
- * @param threadName Name of the EventThread
- */
- EventThread(ThreadGroup threadGroup, String threadName) {
- super(threadGroup, threadName == null ? getNextName() : threadName);
- running = true;
- head = null;
- tail = null;
-
- setDaemon(true); /* Mark thread as daemon thread */
- }
-
- private static synchronized String getNextName() {
- return "EventManagerThread-" + nextThreadNumber++; //$NON-NLS-1$
- }
-
- /**
- * Constructor for the event thread.
- * @param threadName Name of the EventThread
- */
- EventThread(String threadName) {
- this(null, threadName);
- }
-
- /**
- * Constructor for the event thread.
- */
- EventThread() {
- this(null, null);
- }
-
- /**
- * Stop thread.
- */
- void close() {
- running = false;
- interrupt();
- }
-
- /**
- * This method pulls events from
- * the queue and dispatches them.
- */
- public void run() {
- try {
- while (true) {
- Queued item = getNextEvent();
- if (item == null) {
- return;
- }
- EventManager.dispatchEvent(item.listeners, item.dispatcher, item.action, item.object);
- // Bug 299589: since the call to getNextEvent() will eventually block for a long time, we need to make sure that the 'item'
- // variable is cleared of the previous value before the call to getNextEvent(). See VM SPec 2.5.7 for why the compiler
- // will not automatically clear this variable for each loop iteration.
- item = null;
- }
- } catch (RuntimeException e) {
- if (EventManager.DEBUG) {
- e.printStackTrace();
- }
- throw e;
- } catch (Error e) {
- if (EventManager.DEBUG) {
- e.printStackTrace();
- }
- throw e;
- }
- }
-
- /**
- * This methods takes the input parameters and creates a Queued
- * object and queues it.
- * The thread is notified.
- *
- * @param l Listener list for this event
- * @param d Dispatcher for this event
- * @param a Action for this event
- * @param o Object for this event
- */
- synchronized void postEvent(Set/*<Map.Entry<Object,Object>>*/l, EventDispatcher d, int a, Object o) {
- if (!isAlive()) { /* If the thread is not alive, throw an exception */
- throw new IllegalStateException();
- }
-
- Queued item = new Queued(l, d, a, o);
-
- if (head == null) /* if the queue was empty */
- {
- head = item;
- tail = item;
- } else /* else add to end of queue */
- {
- tail.next = item;
- tail = item;
- }
-
- notify();
- }
-
- /**
- * This method is called by the thread to remove
- * items from the queue so that they can be dispatched to their listeners.
- * If the queue is empty, the thread waits.
- *
- * @return The Queued removed from the top of the queue or null
- * if the thread has been requested to stop.
- */
- private synchronized Queued getNextEvent() {
- while (running && (head == null)) {
- try {
- wait();
- } catch (InterruptedException e) {
- // If interrupted, we will loop back up and check running
- }
- }
-
- if (!running) { /* if we are stopping */
- return null;
- }
-
- Queued item = head;
- head = item.next;
- if (head == null) {
- tail = null;
- }
-
- return item;
- }
- }
-}

Back to the top