Merge pull request #687 from JavaSaBr/fix_lwjgl_buffer_2

added synchronizing during freeing memory from a deallocator.
fix-456
empirephoenix 8 years ago committed by GitHub
commit b21cff5cfa
  1. 49
      jme3-lwjgl3/src/main/java/com/jme3/util/LWJGLBufferAllocator.java

@ -56,6 +56,11 @@ public class LWJGLBufferAllocator implements BufferAllocator {
stampedLock.unlockWrite(stamp); stampedLock.unlockWrite(stamp);
} }
} }
@Override
Deallocator createDeallocator(final Long address, final ByteBuffer byteBuffer) {
return new ConcurrentDeallocator(byteBuffer, DUMMY_QUEUE, address, stampedLock);
}
} }
/** /**
@ -66,12 +71,12 @@ public class LWJGLBufferAllocator implements BufferAllocator {
/** /**
* The LWJGL byte buffer deallocator. * The LWJGL byte buffer deallocator.
*/ */
private static class Deallocator extends PhantomReference<ByteBuffer> { static class Deallocator extends PhantomReference<ByteBuffer> {
/** /**
* The address of LWJGL byte buffer. * The address of LWJGL byte buffer.
*/ */
private volatile Long address; volatile Long address;
Deallocator(final ByteBuffer referent, final ReferenceQueue<? super ByteBuffer> queue, final Long address) { Deallocator(final ByteBuffer referent, final ReferenceQueue<? super ByteBuffer> queue, final Long address) {
super(referent, queue); super(referent, queue);
@ -90,9 +95,37 @@ public class LWJGLBufferAllocator implements BufferAllocator {
*/ */
void free() { void free() {
if (address == null) return; if (address == null) return;
MemoryUtil.nmemFree(address); freeMemory();
DEALLOCATORS.remove(address); DEALLOCATORS.remove(address);
} }
void freeMemory() {
MemoryUtil.nmemFree(address);
}
}
/**
* The LWJGL byte buffer deallocator.
*/
static class ConcurrentDeallocator extends Deallocator {
final StampedLock stampedLock;
ConcurrentDeallocator(final ByteBuffer referent, final ReferenceQueue<? super ByteBuffer> queue,
final Long address, final StampedLock stampedLock) {
super(referent, queue, address);
this.stampedLock = stampedLock;
}
@Override
protected void freeMemory() {
final long stamp = stampedLock.writeLock();
try {
super.freeMemory();
} finally {
stampedLock.unlockWrite(stamp);
}
}
} }
/** /**
@ -114,7 +147,7 @@ public class LWJGLBufferAllocator implements BufferAllocator {
/** /**
* Free unnecessary LWJGL byte buffers. * Free unnecessary LWJGL byte buffers.
*/ */
private static void freeByteBuffers() { static void freeByteBuffers() {
try { try {
for (;;) { for (;;) {
final Deallocator deallocator = (Deallocator) DUMMY_QUEUE.remove(); final Deallocator deallocator = (Deallocator) DUMMY_QUEUE.remove();
@ -154,7 +187,7 @@ public class LWJGLBufferAllocator implements BufferAllocator {
* @param buffer the buffer. * @param buffer the buffer.
* @return the address or -1. * @return the address or -1.
*/ */
private long getAddress(final Buffer buffer) { long getAddress(final Buffer buffer) {
if (buffer instanceof ByteBuffer) { if (buffer instanceof ByteBuffer) {
return MemoryUtil.memAddress((ByteBuffer) buffer, 0); return MemoryUtil.memAddress((ByteBuffer) buffer, 0);
@ -179,7 +212,11 @@ public class LWJGLBufferAllocator implements BufferAllocator {
public ByteBuffer allocate(final int size) { public ByteBuffer allocate(final int size) {
final Long address = MemoryUtil.nmemAlloc(size); final Long address = MemoryUtil.nmemAlloc(size);
final ByteBuffer byteBuffer = MemoryUtil.memByteBuffer(address, size); final ByteBuffer byteBuffer = MemoryUtil.memByteBuffer(address, size);
DEALLOCATORS.put(address, new Deallocator(byteBuffer, DUMMY_QUEUE, address)); DEALLOCATORS.put(address, createDeallocator(address, byteBuffer));
return byteBuffer; return byteBuffer;
} }
Deallocator createDeallocator(final Long address, final ByteBuffer byteBuffer) {
return new Deallocator(byteBuffer, DUMMY_QUEUE, address);
}
} }

Loading…
Cancel
Save