Fix a bug where SpdySession.getActiveStreams() returns incorrect set
Related issue: #2742 Motivation: When there are more than one stream with the same priority, the set returned by SpdySession.getActiveStream() will not include all of them, because it uses TreeSet and only compares the priority of streams. If two different streams have the same priority, one of them will be discarded by TreeSet. Modification: - Rename getActiveStreams() to activeStreams() - Replace PriorityComparator with StreamComparator Result: Two different streams with the same priority are compared correctly.
This commit is contained in:
parent
386a06dbfa
commit
2c17b75a99
@ -17,10 +17,10 @@ package org.jboss.netty.handler.codec.spdy;
|
||||
|
||||
import org.jboss.netty.channel.MessageEvent;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -33,9 +33,8 @@ final class SpdySession {
|
||||
|
||||
private final AtomicInteger activeLocalStreams = new AtomicInteger();
|
||||
private final AtomicInteger activeRemoteStreams = new AtomicInteger();
|
||||
private final Map<Integer, StreamState> activeStreams =
|
||||
new ConcurrentHashMap<Integer, StreamState>();
|
||||
|
||||
private final Map<Integer, StreamState> activeStreams = new ConcurrentHashMap<Integer, StreamState>();
|
||||
private final StreamComparator streamComparator = new StreamComparator();
|
||||
private final AtomicInteger sendWindowSize;
|
||||
private final AtomicInteger receiveWindowSize;
|
||||
|
||||
@ -61,10 +60,10 @@ final class SpdySession {
|
||||
}
|
||||
|
||||
// Stream-IDs should be iterated in priority order
|
||||
Set<Integer> getActiveStreams() {
|
||||
TreeSet<Integer> StreamIds = new TreeSet<Integer>(new PriorityComparator());
|
||||
StreamIds.addAll(activeStreams.keySet());
|
||||
return StreamIds;
|
||||
Map<Integer, StreamState> activeStreams() {
|
||||
Map<Integer, StreamState> streams = new TreeMap<Integer, StreamState>(streamComparator);
|
||||
streams.putAll(activeStreams);
|
||||
return streams;
|
||||
}
|
||||
|
||||
void acceptStream(
|
||||
@ -215,12 +214,12 @@ final class SpdySession {
|
||||
|
||||
MessageEvent getPendingWrite(int streamId) {
|
||||
if (streamId == SPDY_SESSION_STREAM_ID) {
|
||||
for (Integer id : getActiveStreams()) {
|
||||
StreamState state = activeStreams.get(id);
|
||||
for (Map.Entry<Integer, StreamState> e: activeStreams().entrySet()) {
|
||||
StreamState state = e.getValue();
|
||||
if (state.getSendWindowSize() > 0) {
|
||||
MessageEvent e = state.getPendingWrite();
|
||||
if (e != null) {
|
||||
return e;
|
||||
MessageEvent evt = state.getPendingWrite();
|
||||
if (evt != null) {
|
||||
return evt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -319,15 +318,22 @@ final class SpdySession {
|
||||
}
|
||||
}
|
||||
|
||||
private final class PriorityComparator implements Comparator<Integer> {
|
||||
private final class StreamComparator implements Comparator<Integer>, Serializable {
|
||||
|
||||
PriorityComparator() {
|
||||
}
|
||||
private static final long serialVersionUID = 1161471649740544848L;
|
||||
|
||||
StreamComparator() { }
|
||||
|
||||
public int compare(Integer id1, Integer id2) {
|
||||
StreamState state1 = activeStreams.get(id1);
|
||||
StreamState state2 = activeStreams.get(id2);
|
||||
return state1.getPriority() - state2.getPriority();
|
||||
|
||||
int result = state1.getPriority() - state2.getPriority();
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return id1 - id2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user