Merge "Issue #2968 fix buffer thread safety issues" into development

Former-commit-id: 30eee9a48d797c2e6cd509fd878b1b2ee759c105
This commit is contained in:
Nate Jensen 2014-04-08 09:46:11 -05:00 committed by Gerrit Code Review
commit a03ca229e7
4 changed files with 75 additions and 16 deletions

View file

@ -22,9 +22,6 @@ package com.raytheon.uf.viz.remote.graphics.events.colormap;
import java.nio.Buffer;
import com.raytheon.uf.common.colormap.image.ColorMapData;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
@ -39,7 +36,8 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 9, 2012 mschenke Initial creation
* Mar 09, 2012 mschenke Initial creation
* Apr 07, 2014 2968 njensen Improved efficiency
*
* </pre>
*
@ -73,17 +71,8 @@ public class ColorMapDataEvent extends AbstractDispatchingObjectEvent {
// Copy data via serialization
this.dimensions = colorMapData.getDimensions();
this.dataType = colorMapData.getDataType();
try {
// Copy the buffer since it is the same buffer that will be used for
// rendering in a separate thread and serializing Buffer access is
// not thread safe
this.buffer = (Buffer) SerializationUtil
.transformFromThrift(SerializationUtil
.transformToThrift(colorMapData.getBuffer()));
} catch (SerializationException e) {
throw new RuntimeException("Error copying data Buffer: "
+ e.getLocalizedMessage(), e);
}
// serializing buffers is thread safe now so just directly use it
this.buffer = colorMapData.getBuffer();
}
/**

View file

@ -23,6 +23,8 @@ import java.nio.Buffer;
import javax.media.opengl.GL;
import com.raytheon.uf.common.util.BufferUtil;
/**
* Abstract gl data format object for colormapped data
*
@ -35,6 +37,7 @@ import javax.media.opengl.GL;
* Nov 21, 2011 mschenke Initial creation
* Oct 16, 2013 2333 mschenke Removed Buffer from GLColorMapData
* Nov 18, 2013 2543 bsteffen Add more buffer compatibility checks.
* Apr 07, 2014 2968 njensen Duplicate buffer in formatForGL()
*
* </pre>
*
@ -166,6 +169,7 @@ public abstract class AbstractGLColorMapDataFormat {
* @return
*/
public Buffer formatForGL(Buffer buffer, GLColorMapData data) {
buffer = BufferUtil.duplicate(buffer);
buffer = handleBufferSizing(data, buffer);
if (!buffer.isDirect() && !buffer.hasArray()) {
/*

View file

@ -31,6 +31,7 @@ import com.raytheon.uf.common.serialization.IDeserializationContext;
import com.raytheon.uf.common.serialization.ISerializationContext;
import com.raytheon.uf.common.serialization.ISerializationTypeAdapter;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.util.BufferUtil;
/**
* Serialization adapter that handles java.nio.Buffer objects. Buffers are not
@ -45,6 +46,7 @@ import com.raytheon.uf.common.serialization.SerializationException;
* ------------ ---------- ----------- --------------------------
* May 03, 2012 mschenke Initial creation
* Jul 23, 2013 2215 njensen Updated for thrift 0.9.0
* Apr 07, 2014 2968 njensen Fixed thread safety issues with serialize()
*
* </pre>
*
@ -65,6 +67,7 @@ public class BufferAdapter implements ISerializationTypeAdapter<Buffer> {
@Override
public void serialize(ISerializationContext serializer, Buffer buffer)
throws SerializationException {
buffer = BufferUtil.asReadOnly(buffer);
serializer.writeBool(buffer.isDirect());
buffer.position(0);
ByteBuffer bb = null;

View file

@ -20,9 +20,13 @@
package com.raytheon.uf.common.util;
import java.awt.Rectangle;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
/**
@ -33,7 +37,8 @@ import java.nio.ShortBuffer;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 1, 2010 mschenke Initial creation
* Mar 01, 2010 mschenke Initial creation
* Apr 07, 2014 2968 njensen Added asReadOnly() and duplicate()
*
* </pre>
*
@ -176,4 +181,62 @@ public class BufferUtil {
}
}
/**
* Returns a new read-only view into a buffer
*
* @param buffer
* @return
*/
public static Buffer asReadOnly(Buffer buffer) {
Buffer ret = null;
if (buffer instanceof ByteBuffer) {
ret = ((ByteBuffer) buffer).asReadOnlyBuffer();
} else if (buffer instanceof ShortBuffer) {
ret = ((ShortBuffer) buffer).asReadOnlyBuffer();
} else if (buffer instanceof IntBuffer) {
ret = ((IntBuffer) buffer).asReadOnlyBuffer();
} else if (buffer instanceof LongBuffer) {
ret = ((LongBuffer) buffer).asReadOnlyBuffer();
} else if (buffer instanceof FloatBuffer) {
ret = ((FloatBuffer) buffer).asReadOnlyBuffer();
} else if (buffer instanceof DoubleBuffer) {
ret = ((DoubleBuffer) buffer).asReadOnlyBuffer();
} else {
throw new IllegalArgumentException(
"Cannot create read only buffer of type "
+ buffer.getClass().getName());
}
return ret;
}
/**
* Creates a new view into a buffer with an independent position and mark
*
* @param buffer
* @return
*/
public static Buffer duplicate(Buffer buffer) {
Buffer ret = null;
if (buffer instanceof ByteBuffer) {
ret = ((ByteBuffer) buffer).duplicate();
} else if (buffer instanceof ShortBuffer) {
ret = ((ShortBuffer) buffer).duplicate();
} else if (buffer instanceof IntBuffer) {
ret = ((IntBuffer) buffer).duplicate();
} else if (buffer instanceof LongBuffer) {
ret = ((LongBuffer) buffer).duplicate();
} else if (buffer instanceof FloatBuffer) {
ret = ((FloatBuffer) buffer).duplicate();
} else if (buffer instanceof DoubleBuffer) {
ret = ((DoubleBuffer) buffer).duplicate();
} else {
throw new IllegalArgumentException(
"Cannot create duplicate buffer of type "
+ buffer.getClass().getName());
}
return ret;
}
}