mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

gbellato
13.26.2008 9f0dae3d08ca0cf7c131af2f1fc09670ace301fa
Fix for 3052 : IllegalMonitorStateException in replication HeartbeatThread

The replication HeartBeatThread uses non final Boolean for the synchronization
of the shutdown phase.

This can cause some rare IllegalMonitorStateException when trying to shutdown the HeartbeatThread because the Boolean can be modified by another thread.

The fix is to use a dedicated lock for this synchronization purpose.

This change also turn some replication objects that were used for sycnhronization
purpose into final objects so that the same bug cannot happen again.
4 files modified
26 ■■■■ changed files
opends/src/server/org/opends/server/replication/protocol/HeartbeatThread.java 9 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/server/DbHandler.java 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java 10 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/server/ServerHandler.java 2 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/protocol/HeartbeatThread.java
@@ -68,6 +68,7 @@
   * Set this to stop the thread.
   */
  private Boolean shutdown = false;
  private final Object shutdown_lock = new Object();
  /**
@@ -135,11 +136,11 @@
            TRACER.debugVerbose("Heartbeat thread sleeping for %d", sleepTime);
          }
          synchronized (shutdown)
          synchronized (shutdown_lock)
          {
            if (!shutdown)
            {
              shutdown.wait(sleepTime);
              shutdown_lock.wait(sleepTime);
            }
          }
        }
@@ -173,10 +174,10 @@
   */
  public void shutdown()
  {
    synchronized (shutdown)
    synchronized (shutdown_lock)
    {
      shutdown.notifyAll();
      shutdown = true;
      shutdown_lock.notifyAll();
      if (debugEnabled())
      {
        TRACER.debugInfo("Going to notify Heartbeat thread.");
opends/src/server/org/opends/server/replication/server/DbHandler.java
@@ -79,7 +79,8 @@
  // Changes are not read back by replicationServer threads that are responsible
  // for pushing the changes to other replication server or to LDAP server
  //
  private LinkedList<UpdateMessage> msgQueue = new LinkedList<UpdateMessage>();
  private final LinkedList<UpdateMessage> msgQueue =
    new LinkedList<UpdateMessage>();
  private ReplicationDB db;
  private ChangeNumber firstChange = null;
  private ChangeNumber lastChange = null;
@@ -89,7 +90,7 @@
  private boolean shutdown = false;
  private boolean done = false;
  private DirectoryThread thread = null;
  private Object flushLock = new Object();
  private final Object flushLock = new Object();
  private ReplicationServer replicationServer;
opends/src/server/org/opends/server/replication/server/ReplicationServerDomain.java
@@ -80,8 +80,8 @@
 */
public class ReplicationServerDomain
{
  private Object flowControlLock = new Object();
  private DN baseDn = null;
  private final Object flowControlLock = new Object();
  private final DN baseDn;
  /*
   * The following map contains one balanced tree for each replica ID
@@ -93,7 +93,7 @@
   * to this replication server.
   *
   */
  private Map<Short, ServerHandler> connectedServers =
  private final Map<Short, ServerHandler> connectedServers =
    new ConcurrentHashMap<Short, ServerHandler>();
  /*
@@ -106,14 +106,14 @@
   * to this replication server.
   */
  private Map<Short, ServerHandler> replicationServers =
  private final Map<Short, ServerHandler> replicationServers =
    new ConcurrentHashMap<Short, ServerHandler>();
  /*
   * This map contains the List of updates received from each
   * LDAP server
   */
  private Map<Short, DbHandler> sourceDbHandlers =
  private final Map<Short, DbHandler> sourceDbHandlers =
    new ConcurrentHashMap<Short, DbHandler>();
  private ReplicationServer replicationServer;
opends/src/server/org/opends/server/replication/server/ServerHandler.java
@@ -129,7 +129,7 @@
   * this collection will contain as many elements as there are
   * LDAP servers connected to the remote replication server.
   */
  private Map<Short, LightweightServerHandler> connectedServers =
  private final Map<Short, LightweightServerHandler> connectedServers =
    new ConcurrentHashMap<Short, LightweightServerHandler>();
  /**