WebSocket - making flush loop and callback notify more consistent

This commit is contained in:
Joakim Erdfelt 2013-08-23 10:57:05 -07:00
parent bfd68d7e61
commit 098b1e174b
1 changed files with 44 additions and 37 deletions

View File

@ -209,39 +209,37 @@ public class WriteBytesProvider implements Callback
public void failAll(Throwable t) public void failAll(Throwable t)
{ {
boolean notified = false; // Collect entries for callback
List<FrameEntry> callbacks = new ArrayList<>();
synchronized (this)
{
// fail active (if set) // fail active (if set)
if (active != null) if (active != null)
{ {
FrameEntry entry = active; FrameEntry entry = active;
active = null; active = null;
entry.notifyFailure(t); callbacks.add(entry);
notified = true;
} }
failure = t; callbacks.addAll(past);
callbacks.addAll(queue);
// fail past past.clear();
while (!past.isEmpty()) queue.clear();
{
FrameEntry entry = past.pop();
entry.notifyFailure(t);
notified = true;
} }
// fail others
while (!queue.isEmpty())
{
FrameEntry entry = queue.pop();
entry.notifyFailure(t);
notified = true;
}
if (notified)
{
// notify flush callback // notify flush callback
if (!callbacks.isEmpty())
{
// TODO: always notify instead?
flushCallback.failed(t); flushCallback.failed(t);
// notify entry callbacks
for (FrameEntry entry : callbacks)
{
entry.notifyFailure(t);
}
} }
} }
@ -362,23 +360,32 @@ public class WriteBytesProvider implements Callback
*/ */
@Override @Override
public void succeeded() public void succeeded()
{
// Collect entries for callback
List<FrameEntry> callbacks = new ArrayList<>();
synchronized (this)
{ {
if ((active != null) && (active.frame.remaining() <= 0)) if ((active != null) && (active.frame.remaining() <= 0))
{ {
// All done with active FrameEntry // All done with active FrameEntry
FrameEntry entry = active; FrameEntry entry = active;
active = null; active = null;
entry.notifySucceeded(); callbacks.add(entry);
} }
while (!past.isEmpty()) callbacks.addAll(past);
{ past.clear();
FrameEntry entry = past.pop();
entry.notifySucceeded();
} }
// notify flush callback // notify flush callback
flushCallback.succeeded(); flushCallback.succeeded();
// notify entry callbacks outside of synchronize
for (FrameEntry entry : callbacks)
{
entry.notifySucceeded();
}
} }
@Override @Override