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

Matthew Swift
16.47.2012 1e9516a3f84cb1a524c3b4446ef5f7260f6e51d1
Fix OPENDJ-524: CME in LDAPClientConnection when writing many large responses concurrently to the same connection
1 files modified
26 ■■■■ changed files
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java 26 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -52,6 +52,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
@@ -154,6 +156,9 @@
   */
  private class TimeoutWriteByteChannel implements ByteChannel
  {
    // Synchronize concurrent writes to the same connection.
    private final Lock writeLock = new ReentrantLock();
    public int read(ByteBuffer byteBuffer) throws IOException
    {
      return clientChannel.read(byteBuffer);
@@ -169,14 +174,20 @@
      clientChannel.close();
    }
    public int write(ByteBuffer byteBuffer) throws IOException
    {
      writeLock.lock();
      try
      {
      int bytesToWrite = byteBuffer.remaining();
      clientChannel.write(byteBuffer);
      if(!byteBuffer.hasRemaining())
      {
        return bytesToWrite;
      }
      long startTime = System.currentTimeMillis();
      long waitTime = getMaxBlockedWriteTimeLimit();
      if (waitTime <= 0)
@@ -186,7 +197,6 @@
        // blocking a worker thread.
        waitTime = 300000L;
      }
      long stopTime = startTime + waitTime;
      Selector selector = getWriteSelector();
@@ -215,9 +225,8 @@
      }
      // Register with the selector for handling write operations.
      SelectionKey key =
          clientChannel.register(selector, SelectionKey.OP_WRITE);
        SelectionKey key = clientChannel.register(selector,
            SelectionKey.OP_WRITE);
      try
      {
        selector.select(waitTime);
@@ -234,8 +243,8 @@
            waitTime = stopTime - currentTime;
          }
          Iterator<SelectionKey> iterator =
              selector.selectedKeys().iterator();
            Iterator<SelectionKey> iterator = selector.selectedKeys()
                .iterator();
          while (iterator.hasNext())
          {
            SelectionKey k = iterator.next();
@@ -269,6 +278,11 @@
        }
      }
    }
      finally
      {
        writeLock.unlock();
      }
    }
  }