Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java
41161 views
/*1* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jndi.ldap;2627import java.util.Vector;28import java.util.EventObject;2930import javax.naming.event.NamingEvent;31import javax.naming.event.NamingExceptionEvent;32import javax.naming.event.NamingListener;33import javax.naming.ldap.UnsolicitedNotificationEvent;34import javax.naming.ldap.UnsolicitedNotificationListener;3536/**37* Package private class used by EventSupport to dispatch events.38* This class implements an event queue, and a dispatcher thread that39* dequeues and dispatches events from the queue.40*41* Pieces stolen from sun.misc.Queue.42*43* @author Bill Shannon (from javax.mail.event)44* @author Rosanna Lee (modified for JNDI-related events)45*/46final class EventQueue implements Runnable {47private static final boolean debug = false;4849private static class QueueElement {50QueueElement next = null;51QueueElement prev = null;52EventObject event = null;53Vector<NamingListener> vector = null;5455QueueElement(EventObject event, Vector<NamingListener> vector) {56this.event = event;57this.vector = vector;58}59}6061private QueueElement head = null;62private QueueElement tail = null;63private Thread qThread;6465// package private66EventQueue() {67qThread = Obj.helper.createThread(this);68qThread.setDaemon(true); // not a user thread69qThread.start();70}7172// package private;73/**74* Enqueue an event.75* @param event Either a {@code NamingExceptionEvent} or a subclass76* of {@code NamingEvent} or77* {@code UnsolicitedNotificationEvent}.78* If it is a subclass of {@code NamingEvent}, all listeners must implement79* the corresponding subinterface of {@code NamingListener}.80* For example, for an {@code ObjectAddedEvent}, all listeners <em>must</em>81* implement the {@code ObjectAddedListener} interface.82* <em>The current implementation does not check this before dispatching83* the event.</em>84* If the event is a {@code NamingExceptionEvent}, then all listeners85* are notified.86* @param vector List of NamingListeners that will be notified of event.87*/88synchronized void enqueue(EventObject event, Vector<NamingListener> vector) {89QueueElement newElt = new QueueElement(event, vector);9091if (head == null) {92head = newElt;93tail = newElt;94} else {95newElt.next = head;96head.prev = newElt;97head = newElt;98}99notify();100}101102/**103* Dequeue the oldest object on the queue.104* Used only by the run() method.105*106* @return the oldest object on the queue.107* @exception java.lang.InterruptedException if any thread has108* interrupted this thread.109*/110private synchronized QueueElement dequeue()111throws InterruptedException {112while (tail == null)113wait();114QueueElement elt = tail;115tail = elt.prev;116if (tail == null) {117head = null;118} else {119tail.next = null;120}121elt.prev = elt.next = null;122return elt;123}124125/**126* Pull events off the queue and dispatch them.127*/128public void run() {129QueueElement qe;130131try {132while ((qe = dequeue()) != null) {133EventObject e = qe.event;134Vector<NamingListener> v = qe.vector;135136for (int i = 0; i < v.size(); i++) {137138// Dispatch to corresponding NamingListener139// The listener should only be getting the event that140// it is interested in. (No need to check mask or141// instanceof subinterfaces.)142// It is the responsibility of the enqueuer to143// only enqueue events with listeners of the correct type.144145if (e instanceof NamingEvent) {146((NamingEvent)e).dispatch(v.elementAt(i));147148// An exception occurred: if notify all naming listeners149} else if (e instanceof NamingExceptionEvent) {150((NamingExceptionEvent)e).dispatch(v.elementAt(i));151} else if (e instanceof UnsolicitedNotificationEvent) {152((UnsolicitedNotificationEvent)e).dispatch(153(UnsolicitedNotificationListener)v.elementAt(i));154}155}156157qe = null; e = null; v = null;158}159} catch (InterruptedException e) {160// just die161}162}163164// package private; used by EventSupport;165/**166* Stop the dispatcher so we can be destroyed.167*/168void stop() {169if (debug) System.err.println("EventQueue stopping");170if (qThread != null) {171qThread.interrupt(); // kill our thread172qThread = null;173}174}175}176177178