Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Lucene: Java-Dev

deadlock in TestCrash

 

 

Lucene java-dev RSS feed   Index | Next | Previous | View Threaded


lucene at mikemccandless

Nov 27, 2009, 8:37 AM

Post #1 of 3 (300 views)
Permalink
deadlock in TestCrash

RAMFile has this method:

final synchronized byte[] addBuffer(int size) {
byte[] buffer = newBuffer(size);
if (directory!=null)
synchronized (directory) { // Ensure addition of
buffer and adjustment to directory size are atomic wrt directory
buffers.add(buffer);
directory.sizeInBytes += size;
sizeInBytes += size;
}
else
buffers.add(buffer);
return buffer;
}

But in working on LUCENE-2095, I'm seeing a deadlock, because that
method first syncs on RAMFile and then tries to sync on directory,
while the MockRAMDirectory.crash method, and I think maybe other
places, do the reverse. I remember also hitting a different deadlock
from this in the past, and working around it.

I'd like to break the deadlock by changing RAMFile to this:

final byte[] addBuffer(int size) {
byte[] buffer = newBuffer(size);
synchronized(this) {
buffers.add(buffer);
sizeInBytes += size;
}

if (directory != null) {
synchronized (directory) {
directory.sizeInBytes += size;
}
}
return buffer;
}

But, then, the addition of the buffer and the change of sizeInBytes is
no longer atomic wrt the directory (as the comment says).

So my question is... is this change OK? Why is/was it so crucial that
the sizeInBytes & RAMFile's buffers really change only atomically?
Ie, it seems harmless if RAMDirectory.sizeInBytes() might not include
a buffer that's in the process of being added...?

(I do see TestRAMDirectory.testRAMDirectorySize requires this
atomicity, but, I can fix the test to only check the size in the
end...).

Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
For additional commands, e-mail: java-dev-help [at] lucene


jason.rutherglen at gmail

Nov 27, 2009, 9:56 AM

Post #2 of 3 (273 views)
Permalink
Re: deadlock in TestCrash [In reply to]

If syncing on directory is not important, then sizeInBytes can be an AtomicLong?

On Fri, Nov 27, 2009 at 8:37 AM, Michael McCandless
<lucene [at] mikemccandless> wrote:
> RAMFile has this method:
>
>  final synchronized byte[] addBuffer(int size) {
>    byte[] buffer = newBuffer(size);
>    if (directory!=null)
>      synchronized (directory) {             // Ensure addition of
> buffer and adjustment to directory size are atomic wrt directory
>        buffers.add(buffer);
>        directory.sizeInBytes += size;
>        sizeInBytes += size;
>      }
>    else
>      buffers.add(buffer);
>    return buffer;
>  }
>
> But in working on LUCENE-2095, I'm seeing a deadlock, because that
> method first syncs on RAMFile and then tries to sync on directory,
> while the MockRAMDirectory.crash method, and I think maybe other
> places, do the reverse.  I remember also hitting a different deadlock
> from this in the past, and working around it.
>
> I'd like to break the deadlock by changing RAMFile to this:
>
>  final byte[] addBuffer(int size) {
>    byte[] buffer = newBuffer(size);
>    synchronized(this) {
>      buffers.add(buffer);
>      sizeInBytes += size;
>    }
>
>    if (directory != null) {
>      synchronized (directory) {
>        directory.sizeInBytes += size;
>      }
>    }
>    return buffer;
>  }
>
> But, then, the addition of the buffer and the change of sizeInBytes is
> no longer atomic wrt the directory (as the comment says).
>
> So my question is... is this change OK?  Why is/was it so crucial that
> the sizeInBytes & RAMFile's buffers really change only atomically?
> Ie, it seems harmless if RAMDirectory.sizeInBytes() might not include
> a buffer that's in the process of being added...?
>
> (I do see TestRAMDirectory.testRAMDirectorySize requires this
> atomicity, but, I can fix the test to only check the size in the
> end...).
>
> Mike
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
> For additional commands, e-mail: java-dev-help [at] lucene
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
For additional commands, e-mail: java-dev-help [at] lucene


lucene at mikemccandless

Nov 27, 2009, 10:29 AM

Post #3 of 3 (270 views)
Permalink
Re: deadlock in TestCrash [In reply to]

True... I'll make that change too.

Mike

On Fri, Nov 27, 2009 at 12:56 PM, Jason Rutherglen
<jason.rutherglen [at] gmail> wrote:
> If syncing on directory is not important, then sizeInBytes can be an AtomicLong?
>
> On Fri, Nov 27, 2009 at 8:37 AM, Michael McCandless
> <lucene [at] mikemccandless> wrote:
>> RAMFile has this method:
>>
>>  final synchronized byte[] addBuffer(int size) {
>>    byte[] buffer = newBuffer(size);
>>    if (directory!=null)
>>      synchronized (directory) {             // Ensure addition of
>> buffer and adjustment to directory size are atomic wrt directory
>>        buffers.add(buffer);
>>        directory.sizeInBytes += size;
>>        sizeInBytes += size;
>>      }
>>    else
>>      buffers.add(buffer);
>>    return buffer;
>>  }
>>
>> But in working on LUCENE-2095, I'm seeing a deadlock, because that
>> method first syncs on RAMFile and then tries to sync on directory,
>> while the MockRAMDirectory.crash method, and I think maybe other
>> places, do the reverse.  I remember also hitting a different deadlock
>> from this in the past, and working around it.
>>
>> I'd like to break the deadlock by changing RAMFile to this:
>>
>>  final byte[] addBuffer(int size) {
>>    byte[] buffer = newBuffer(size);
>>    synchronized(this) {
>>      buffers.add(buffer);
>>      sizeInBytes += size;
>>    }
>>
>>    if (directory != null) {
>>      synchronized (directory) {
>>        directory.sizeInBytes += size;
>>      }
>>    }
>>    return buffer;
>>  }
>>
>> But, then, the addition of the buffer and the change of sizeInBytes is
>> no longer atomic wrt the directory (as the comment says).
>>
>> So my question is... is this change OK?  Why is/was it so crucial that
>> the sizeInBytes & RAMFile's buffers really change only atomically?
>> Ie, it seems harmless if RAMDirectory.sizeInBytes() might not include
>> a buffer that's in the process of being added...?
>>
>> (I do see TestRAMDirectory.testRAMDirectorySize requires this
>> atomicity, but, I can fix the test to only check the size in the
>> end...).
>>
>> Mike
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
>> For additional commands, e-mail: java-dev-help [at] lucene
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
> For additional commands, e-mail: java-dev-help [at] lucene
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe [at] lucene
For additional commands, e-mail: java-dev-help [at] lucene

Lucene java-dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.