From 53c232421f375fb7aec505cd3f152511aed47167 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Thu, 22 Oct 2009 13:31:32 +0000
Subject: [PATCH] Control Panel fix for issue 4302 (Unexpected errors using single JNDI connection with SSL and multiple threads.)

---
 opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java |   98 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java b/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
index ff8ec76..9277f3e 100644
--- a/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
+++ b/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -67,11 +67,13 @@
 import javax.swing.JSeparator;
 import javax.swing.JSplitPane;
 import javax.swing.JTree;
+import javax.swing.SwingUtilities;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
 import javax.swing.tree.TreePath;
 
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
+import org.opends.guitools.controlpanel.datamodel.CustomSearchResult;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
 import org.opends.guitools.controlpanel.event.EntryReadErrorEvent;
@@ -149,8 +151,9 @@
 
   private boolean ignoreTreeSelectionEvents = false;
 
-  private ArrayList<LDAPEntryReader> entryReaderQueue =
-    new ArrayList<LDAPEntryReader>();
+  private LDAPEntryReader entryReader;
+
+  private Thread entryReaderThread;
 
   /**
    * {@inheritDoc}
@@ -523,12 +526,11 @@
           controller.findConnectionForDisplayedEntry(node);
         LDAPEntryReader reader = new LDAPEntryReader(dn, ctx);
         reader.addEntryReadListener(entryPane);
-        cleanupReaderQueue();
         // Required to update the browser controller properly if the entry is
         // deleted.
         entryPane.setTreePath(path);
-        reader.startBackgroundTask();
-        entryReaderQueue.add(reader);
+        stopCurrentReader();
+        startReader(reader);
       }
       catch (Throwable t)
       {
@@ -541,7 +543,7 @@
     }
     else
     {
-      cleanupReaderQueue();
+      stopCurrentReader();
       if ((paths != null) && (paths.length > 1))
       {
         entryPane.multipleEntriesSelected();
@@ -553,26 +555,76 @@
     }
   }
 
-  /**
-   * Cleans up the reader queue (the queue where we store the entries that we
-   * must read).
-   *
-   */
-  private void cleanupReaderQueue()
+  private void stopCurrentReader()
   {
-    ArrayList<LDAPEntryReader> toRemove = new ArrayList<LDAPEntryReader>();
-    for (LDAPEntryReader r : entryReaderQueue)
+    if (entryReader != null)
     {
-      if (r.isOver())
-      {
-        toRemove.add(r);
-      }
-      else
-      {
-        r.interrupt();
-      }
+      entryReader.setNotifyListeners(false);
     }
-    entryReaderQueue.removeAll(toRemove);
+  }
+
+  /**
+   * Starts the provider reader.
+   * @param reader the LDAPEntryReader.
+   */
+  private void startReader(LDAPEntryReader reader)
+  {
+    entryReader = reader;
+    if ((entryReaderThread == null) || !entryReaderThread.isAlive())
+    {
+      entryReaderThread = new Thread(new Runnable()
+      {
+        LDAPEntryReader reader;
+        CustomSearchResult sr;
+        Throwable t;
+        public void run()
+        {
+          while (true)
+          {
+            try
+            {
+              synchronized (entryReaderThread)
+              {
+                while ((reader = entryReader) == null)
+                {
+                  entryReaderThread.wait();
+                }
+              }
+              sr = null;
+              t = null;
+              try
+              {
+                sr = reader.processBackgroundTask();
+              }
+              catch (Throwable th)
+              {
+                t = th;
+              }
+              SwingUtilities.invokeAndWait(new Runnable()
+              {
+                public void run()
+                {
+                  reader.backgroundTaskCompleted(sr, t);
+                  if (reader == entryReader)
+                  {
+                    entryReader = null;
+                  }
+                }
+              });
+            }
+            catch (Throwable t)
+            {
+              entryReader = null;
+            }
+          }
+        }
+      });
+      entryReaderThread.start();
+    }
+    synchronized (entryReaderThread)
+    {
+      entryReaderThread.notify();
+    }
   }
 
   /**

--
Gitblit v1.10.0