protected IStream createRemoteStream(int streamId) { // SPEC: exceeding max concurrent streams is treated as stream error. while (true) { int remoteCount = remoteStreamCount.get(); int maxCount = getMaxRemoteStreams(); if (maxCount >= 0 && remoteCount >= maxCount) { reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP); return null; } if (remoteStreamCount.compareAndSet(remoteCount, remoteCount + 1)) break; } IStream stream = newStream(streamId, false); // SPEC: duplicate stream is treated as connection error. if (streams.putIfAbsent(streamId, stream) == null) { updateLastStreamId(streamId); stream.setIdleTimeout(getStreamIdleTimeout()); flowControl.onStreamCreated(stream); if (LOG.isDebugEnabled()) LOG.debug("Created remote {}", stream); return stream; } else { close(ErrorCode.PROTOCOL_ERROR.code, "duplicate_stream", Callback.NOOP); return null; } }
protected IStream createLocalStream(int streamId, Promise<Stream> promise) { while (true) { int localCount = localStreamCount.get(); int maxCount = getMaxLocalStreams(); if (maxCount >= 0 && localCount >= maxCount) { promise.failed( new IllegalStateException("Max local stream count " + maxCount + " exceeded")); return null; } if (localStreamCount.compareAndSet(localCount, localCount + 1)) break; } IStream stream = newStream(streamId, true); if (streams.putIfAbsent(streamId, stream) == null) { stream.setIdleTimeout(getStreamIdleTimeout()); flowControl.onStreamCreated(stream); if (LOG.isDebugEnabled()) LOG.debug("Created local {}", stream); return stream; } else { promise.failed(new IllegalStateException("Duplicate stream " + streamId)); return null; } }