001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.hivemind.service.impl; 016 017 import java.util.Iterator; 018 019 import org.apache.hivemind.service.ThreadCleanupListener; 020 import org.apache.hivemind.service.ThreadEventNotifier; 021 import org.apache.hivemind.util.EventListenerList; 022 023 /** 024 * Implementation of {@link org.apache.hivemind.service.ThreadEventNotifier}, 025 * available as service <code>hivemind.ThreadEventNotifier</code>. 026 * 027 * @author Howard Lewis Ship 028 */ 029 public class ThreadEventNotifierImpl implements ThreadEventNotifier 030 { 031 private ThreadLocal _storage = new ThreadLocal(); 032 033 public void addThreadCleanupListener(ThreadCleanupListener listener) 034 { 035 EventListenerList list = (EventListenerList) _storage.get(); 036 037 if (list == null) 038 { 039 list = new EventListenerList(); 040 _storage.set(list); 041 } 042 043 list.addListener(listener); 044 } 045 046 public void removeThreadCleanupListener(ThreadCleanupListener listener) 047 { 048 EventListenerList list = (EventListenerList) _storage.get(); 049 050 if (list != null) 051 list.removeListener(listener); 052 } 053 054 public void fireThreadCleanup() 055 { 056 // Here's where we need the CursorableLinkedList since listeners 057 // are free to unregister as listeners from threadDidCleanup() and 058 // we need to avoid concurrent modification errors. 059 060 EventListenerList list = (EventListenerList) _storage.get(); 061 062 if (list == null) 063 return; 064 065 Iterator i = list.getListeners(); 066 067 while (i.hasNext()) 068 { 069 ThreadCleanupListener listener = (ThreadCleanupListener) i.next(); 070 071 // Each listener may decide to remove itself; that's OK, 072 // EventListenerList handles that kind of concurrent modification 073 // well. 074 075 listener.threadDidCleanup(); 076 } 077 078 } 079 080 }