From 1ed7d3c70b5b209327a1112cb00e532162fe24ec Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 17 Sep 2010 22:16:30 +0000
Subject: [PATCH] Fix potential deadlock which may occur while performing simultaneous large searches and modify operations on the same connection. Use single channel lock per connection and share it across thread local ASN1 writers.
---
opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java
index db382ed..c73bf60 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/asn1/ASN1ByteChannelWriter.java
@@ -22,7 +22,7 @@
* CDDL HEADER END
*
*
- * Copyright 2006-2009 Sun Microsystems, Inc.
+ * Copyright 2006-2010 Sun Microsystems, Inc.
*/
package org.opends.server.protocols.asn1;
@@ -115,14 +115,16 @@
* Constructs a new ASN1ByteChannelWriter.
*
* @param byteChannel The WritableByteChannel to write to.
+ * @param writeLock The write lock to use when flushing to the destination.
* @param writeBufferSize The NIO ByteBuffer size.
*/
ASN1ByteChannelWriter(WritableByteChannel byteChannel,
- int writeBufferSize)
+ ReentrantLock writeLock,
+ int writeBufferSize)
{
this.byteChannel = byteChannel;
this.byteBuffer = ByteBuffer.allocate(writeBufferSize);
- this.flushLock = new ReentrantLock(false);
+ this.flushLock = writeLock;
ByteBufferOutputStream bufferStream = new ByteBufferOutputStream();
this.writer = new ASN1OutputStreamWriter(bufferStream);
@@ -319,12 +321,12 @@
public void flush() throws IOException
{
byteBuffer.flip();
+ if (!flushLock.isHeldByCurrentThread())
+ {
+ flushLock.lock();
+ }
try
{
- if (!flushLock.isHeldByCurrentThread())
- {
- flushLock.lock();
- }
byteChannel.write(byteBuffer);
}
finally
@@ -347,9 +349,17 @@
{
flushLock.lock();
}
- while(byteBuffer.hasRemaining())
+ try
{
- byteChannel.write(byteBuffer);
+ while (byteBuffer.hasRemaining())
+ {
+ byteChannel.write(byteBuffer);
+ }
+ }
+ catch (IOException e)
+ {
+ flushLock.unlock();
+ throw e;
}
byteBuffer.clear();
}
--
Gitblit v1.10.0