424847 - Deadlock in deflate-frame (webkit binary)
+ Moving notification flows to outside of the synchronization blocks
This commit is contained in:
parent
8720fb213c
commit
f0eeb27921
|
@ -19,6 +19,8 @@
|
|||
package org.eclipse.jetty.websocket.common.extensions.compress;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
|
@ -45,8 +47,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
|
||||
private static final int OVERHEAD = 64;
|
||||
/** Tail Bytes per Spec */
|
||||
private static final byte[] TAIL = new byte[]
|
||||
{ 0x00, 0x00, (byte)0xFF, (byte)0xFF };
|
||||
private static final byte[] TAIL = new byte[] { 0x00, 0x00, (byte)0xFF, (byte)0xFF };
|
||||
private int bufferSize = 64 * 1024;
|
||||
private Deflater compressor;
|
||||
private Inflater decompressor;
|
||||
|
@ -58,7 +59,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized void incomingFrame(Frame frame)
|
||||
public void incomingFrame(Frame frame)
|
||||
{
|
||||
if (OpCode.isControlFrame(frame.getOpCode()) || !frame.isRsv1())
|
||||
{
|
||||
|
@ -80,7 +81,6 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
byte compressed[] = new byte[inlen + TAIL.length];
|
||||
payload.get(compressed,0,inlen);
|
||||
System.arraycopy(TAIL,0,compressed,inlen,TAIL.length);
|
||||
decompressor.setInput(compressed,0,compressed.length);
|
||||
|
||||
// Since we don't track text vs binary vs continuation state, just grab whatever is the greater value.
|
||||
int maxSize = Math.max(getPolicy().getMaxTextMessageSize(),getPolicy().getMaxBinaryMessageBufferSize());
|
||||
|
@ -89,6 +89,10 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
DataFrame out = new DataFrame(frame);
|
||||
out.setRsv1(false); // Unset RSV1
|
||||
|
||||
synchronized (decompressor)
|
||||
{
|
||||
decompressor.setInput(compressed,0,compressed.length);
|
||||
|
||||
// Perform decompression
|
||||
while (decompressor.getRemaining() > 0 && !decompressor.finished())
|
||||
{
|
||||
|
@ -118,6 +122,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
throw new BadPayloadException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Forward on the frame
|
||||
out.setPayload(accumulator.getByteBuffer(getBufferPool()));
|
||||
|
@ -136,7 +141,7 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized void outgoingFrame(Frame frame, WriteCallback callback)
|
||||
public void outgoingFrame(Frame frame, WriteCallback callback)
|
||||
{
|
||||
if (OpCode.isControlFrame(frame.getOpCode()))
|
||||
{
|
||||
|
@ -160,7 +165,10 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
|
||||
// Prime the compressor
|
||||
byte uncompressed[] = BufferUtil.toArray(frame.getPayload());
|
||||
List<DataFrame> dframes = new ArrayList<>();
|
||||
|
||||
synchronized (compressor)
|
||||
{
|
||||
// Perform the compression
|
||||
if (!compressor.finished())
|
||||
{
|
||||
|
@ -205,13 +213,23 @@ public class DeflateFrameExtension extends AbstractExtension
|
|||
{
|
||||
// this is fragmented
|
||||
out.setFin(false);
|
||||
nextOutgoingFrame(out,null); // non final frames have no callback
|
||||
}
|
||||
dframes.add(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notify outside of synchronize
|
||||
for (DataFrame df : dframes)
|
||||
{
|
||||
if (df.isFin())
|
||||
{
|
||||
nextOutgoingFrame(df,callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// pass through the callback
|
||||
nextOutgoingFrame(out,callback);
|
||||
}
|
||||
// non final frames have no callback
|
||||
nextOutgoingFrame(df,null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue