Permalink
Browse files

FELIX-3623: made the locks used to notify listeners of new log entrie…

…s as small as possible by breaking them in separate locks. Also notify all listeners of all current log entries, instead of the 'single delivery' policy used before.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1370708 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 55d4dfe commit 5451bb9d299c7eaf21abcb9f60a68c995481e50d Jan Willem Janssen committed Aug 8, 2012
Showing with 46 additions and 34 deletions.
  1. +46 −34 log/src/main/java/org/apache/felix/log/LogListenerThread.java
@@ -33,8 +33,6 @@
*/
final class LogListenerThread extends Thread
{
- // Whether the thread is stopping or not.
- private boolean m_stopping = false;
// The list of entries waiting to be delivered to the log listeners.
private final List m_entriesToDeliver = new ArrayList();
// The list of listeners.
@@ -87,7 +85,10 @@ void removeListener(final LogListener listener)
*/
int getListenerCount()
{
- return m_listeners.size();
+ synchronized (m_listeners)
+ {
+ return m_listeners.size();
+ }
}
/**
@@ -97,8 +98,7 @@ void shutdown()
{
synchronized (m_entriesToDeliver)
{
- m_stopping = true;
- m_entriesToDeliver.notifyAll();
+ interrupt();
}
}
@@ -108,34 +108,11 @@ void shutdown()
*/
public void run()
{
- boolean stop = false;
-
- for (; !stop;)
+ while (!isInterrupted())
{
+ List entriesToDeliver = new ArrayList();
synchronized (m_entriesToDeliver)
{
- if (!m_entriesToDeliver.isEmpty())
- {
- LogEntry entry = (LogEntry) m_entriesToDeliver.remove(0);
-
- synchronized (m_listeners)
- {
- Iterator listenerIt = m_listeners.iterator();
- while (listenerIt.hasNext())
- {
- try
- {
- LogListener listener = (LogListener) listenerIt.next();
- listener.logged(entry);
- }
- catch (Throwable t)
- {
- // catch and discard any exceptions thrown by the listener
- }
- }
- }
- }
-
if (m_entriesToDeliver.isEmpty())
{
try
@@ -144,14 +121,49 @@ public void run()
}
catch (InterruptedException e)
{
- // do nothing
+ // the interrupt-flag is cleared; so, let's play nice and
+ // interrupt this thread again to stop it...
+ interrupt();
}
}
+ else
+ {
+ // Copy all current entries and deliver them in a single go...
+ entriesToDeliver.addAll(m_entriesToDeliver);
+ m_entriesToDeliver.clear();
+ }
}
-
- if (m_stopping)
+
+ if (!entriesToDeliver.isEmpty())
{
- stop = true;
+ // Take a snapshot of all current listeners and deliver all
+ // pending messages to them...
+ List listeners = new ArrayList();
+ synchronized (m_listeners)
+ {
+ listeners.addAll(m_listeners);
+ }
+
+ Iterator entriesIt = entriesToDeliver.iterator();
+ while (entriesIt.hasNext())
+ {
+ LogEntry entry = (LogEntry) entriesIt.next();
+
+ Iterator listenerIt = listeners.iterator();
+ while (listenerIt.hasNext())
+ {
+ LogListener listener = (LogListener) listenerIt.next();
+
+ try
+ {
+ listener.logged(entry);
+ }
+ catch (Throwable t)
+ {
+ // catch and discard any exceptions thrown by the listener
+ }
+ }
+ }
}
}
}

0 comments on commit 5451bb9

Please sign in to comment.