Skip to content
Snippets Groups Projects
Commit c6c114e5 authored by Lyubomir Marinov's avatar Lyubomir Marinov
Browse files

Addresses a media- and UI-related freeze.

parent a5be6c84
No related branches found
No related tags found
No related merge requests found
...@@ -252,7 +252,9 @@ public Object getControl(String controlType) ...@@ -252,7 +252,9 @@ public Object getControl(String controlType)
if ((control == null) if ((control == null)
&& BufferControl.class.getName().equals(controlType)) && BufferControl.class.getName().equals(controlType))
{
control = getBufferControl(); control = getBufferControl();
}
return control; return control;
} }
...@@ -281,11 +283,13 @@ public Object[] getControls() ...@@ -281,11 +283,13 @@ public Object[] getControls()
boolean bufferControlExists = false; boolean bufferControlExists = false;
for (Object control : controls) for (Object control : controls)
{
if (control instanceof BufferControl) if (control instanceof BufferControl)
{ {
bufferControlExists = true; bufferControlExists = true;
break; break;
} }
}
if (!bufferControlExists) if (!bufferControlExists)
{ {
BufferControl bufferControl = getBufferControl(); BufferControl bufferControl = getBufferControl();
...@@ -378,11 +382,11 @@ public void read(Buffer buffer) ...@@ -378,11 +382,11 @@ public void read(Buffer buffer)
{ {
if (readException != null) if (readException != null)
{ {
IOException ex = new IOException(); IOException ioe = new IOException();
ex.initCause(readException); ioe.initCause(readException);
readException = null; readException = null;
throw ex; throw ioe;
} }
buffer.setLength(0); buffer.setLength(0);
...@@ -553,30 +557,26 @@ private int read(Buffer input, Buffer output, int outputOffset) ...@@ -553,30 +557,26 @@ private int read(Buffer input, Buffer output, int outputOffset)
*/ */
public void setTransferHandler(BufferTransferHandler transferHandler) public void setTransferHandler(BufferTransferHandler transferHandler)
{ {
synchronized (cache) BufferTransferHandler substituteTransferHandler
{ = (transferHandler == null)
BufferTransferHandler substituteTransferHandler ? null
= (transferHandler == null) : new StreamSubstituteBufferTransferHandler(
? null transferHandler,
: new StreamSubstituteBufferTransferHandler( stream,
transferHandler, this)
stream, {
this) @Override
public void transferData(PushBufferStream stream)
{ {
@Override if (CachingPushBufferStream.this.stream == stream)
public void transferData(PushBufferStream stream) CachingPushBufferStream.this.transferData(this);
{
if (CachingPushBufferStream.this.stream super.transferData(stream);
== stream) }
{ };
CachingPushBufferStream.this.transferData(
this);
}
super.transferData(stream);
}
};
synchronized (cache)
{
stream.setTransferHandler(substituteTransferHandler); stream.setTransferHandler(substituteTransferHandler);
this.transferHandler = substituteTransferHandler; this.transferHandler = substituteTransferHandler;
cache.notifyAll(); cache.notifyAll();
...@@ -595,41 +595,98 @@ public void transferData(PushBufferStream stream) ...@@ -595,41 +595,98 @@ public void transferData(PushBufferStream stream)
*/ */
protected void transferData(BufferTransferHandler transferHandler) protected void transferData(BufferTransferHandler transferHandler)
{ {
/*
* Obviously, we cannot cache every Buffer because we will run out of
* memory. So wait for root to appear within cache (or for this instance
* to be stopped, of course).
*/
boolean interrupted = false;
boolean canWriteInCache = false;
synchronized (cache) synchronized (cache)
{ {
boolean interrupted = false;
while (true) while (true)
{ {
if (this.transferHandler != transferHandler) if (this.transferHandler != transferHandler)
return; {
if (canWriteInCache()) /*
* The specified transferHandler has already been
* obsoleted/replaced so it does not have the right to cause
* a read or a write.
*/
canWriteInCache = false;
break; break;
try }
else if (canWriteInCache())
{ {
cache.wait(); canWriteInCache = true;
break;
} }
catch (InterruptedException iex) else
{ {
interrupted = true; try
{
cache.wait(DEFAULT_BUFFER_LENGTH);
}
catch (InterruptedException iex)
{
interrupted = true;
}
} }
} }
if (interrupted) }
Thread.currentThread().interrupt(); if (interrupted)
{
Thread.currentThread().interrupt();
}
else if (canWriteInCache)
{
/*
* The protocol of PushBufferStream's #read(Buffer) method is that
* it does not block. The underlying implementation may be flawed
* though so we would better not take any chances. Besides, we have
* a report at the time of this writing which suggests that we may
* really be hitting a rogue implementation in a real-world
* scenario.
*/
Buffer buffer = new Buffer(); Buffer buffer = new Buffer();
IOException readException;
try try
{ {
stream.read(buffer); stream.read(buffer);
readException = null; readException = null;
} }
catch (IOException ioex) catch (IOException ioe)
{
readException = ioe;
}
if (readException == null)
{ {
readException = ioex; if (!buffer.isDiscard()
&& (buffer.getLength() != 0)
&& (buffer.getData() != null))
{
/*
* Well, we risk disagreeing with #canWriteInCache() because
* we have temporarily released the cache but we have read a
* Buffer from the stream so it is probably better to not
* throw it away.
*/
synchronized (cache)
{
cache.add(buffer);
cacheLengthInMillis += getLengthInMillis(buffer);
}
}
}
else
{
synchronized (cache)
{
this.readException = readException;
}
} }
cache.add(buffer);
cacheLengthInMillis += getLengthInMillis(buffer);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment