2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:33:43 PST
file stats: LOC: 110   Methods: 5
NCLOC: 59   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ThreadEventNotifierImpl.java 87.5% 100% 100% 97.1%
coverage coverage
 1    // Copyright 2004, 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 15    package org.apache.hivemind.service.impl;
 16   
 17    import java.util.Iterator;
 18   
 19    import org.apache.commons.logging.Log;
 20    import org.apache.commons.logging.LogFactory;
 21    import org.apache.hivemind.service.ThreadCleanupListener;
 22    import org.apache.hivemind.service.ThreadEventNotifier;
 23    import org.apache.hivemind.util.Defense;
 24    import org.apache.hivemind.util.EventListenerList;
 25   
 26    /**
 27    * Implementation of {@link org.apache.hivemind.service.ThreadEventNotifier}, available as service
 28    * <code>hivemind.ThreadEventNotifier</code>.
 29    *
 30    * @author Howard Lewis Ship
 31    */
 32    public class ThreadEventNotifierImpl implements ThreadEventNotifier
 33    {
 34    private static final Log DEFAULT_LOG = LogFactory.getLog(ThreadEventNotifier.class);
 35   
 36    private final Log _log;
 37   
 38    private final ThreadLocal _storage = new ThreadLocal();
 39   
 40  30 public ThreadEventNotifierImpl()
 41    {
 42  30 this(DEFAULT_LOG);
 43    }
 44   
 45  31 public ThreadEventNotifierImpl(Log log)
 46    {
 47  31 Defense.notNull(log, "log");
 48   
 49  31 _log = log;
 50    }
 51   
 52  17981 public void addThreadCleanupListener(ThreadCleanupListener listener)
 53    {
 54  17960 EventListenerList list = (EventListenerList) _storage.get();
 55   
 56  18010 if (list == null)
 57    {
 58  12028 list = new EventListenerList();
 59  12029 _storage.set(list);
 60    }
 61   
 62  18009 list.addListener(listener);
 63    }
 64   
 65  1 public void removeThreadCleanupListener(ThreadCleanupListener listener)
 66    {
 67  1 EventListenerList list = (EventListenerList) _storage.get();
 68   
 69  1 if (list != null)
 70  1 list.removeListener(listener);
 71    }
 72   
 73  12012 public void fireThreadCleanup()
 74    {
 75    // Here's where we need the CursorableLinkedList since listeners
 76    // are free to unregister as listeners from threadDidCleanup() and
 77    // we need to avoid concurrent modification errors.
 78   
 79  12012 EventListenerList list = (EventListenerList) _storage.get();
 80   
 81  12012 if (list == null)
 82  2 return;
 83   
 84  12010 Iterator i = list.getListeners();
 85   
 86    // Discard the list of listeners as early as possible to ensure that
 87    // they can in no way be retained, even if this thread aborts abnormally.
 88   
 89  12010 _storage.set(null);
 90   
 91  12010 while (i.hasNext())
 92    {
 93  18010 ThreadCleanupListener listener = (ThreadCleanupListener) i.next();
 94   
 95    // Each listener may decide to remove itself; that's OK,
 96    // EventListenerList handles that kind of concurrent modification
 97    // well.
 98   
 99  18010 try
 100    {
 101  18010 listener.threadDidCleanup();
 102    }
 103    catch (RuntimeException ex)
 104    {
 105  1 _log.warn(ServiceMessages.threadCleanupException(ex), ex);
 106    }
 107    }
 108    }
 109   
 110    }