@Override public void syn(SynInfo synInfo, StreamFrameListener listener, Promise<Stream> promise) { // Synchronization is necessary. // SPEC v3, 2.3.1 requires that the stream creation be monotonically crescent // so we cannot allow thread1 to create stream1 and thread2 create stream3 and // have stream3 hit the network before stream1, not only to comply with the spec // but also because the compression context for the headers would be wrong, as the // frame with a compression history will come before the first compressed frame. int associatedStreamId = 0; if (synInfo instanceof PushSynInfo) associatedStreamId = ((PushSynInfo)synInfo).getAssociatedStreamId(); synchronized (this) { int streamId = streamIds.getAndAdd(2); // TODO: for SPDYv3 we need to support the "slot" argument SynStreamFrame synStream = new SynStreamFrame(version, synInfo.getFlags(), streamId, associatedStreamId, synInfo.getPriority(), (short)0, synInfo.getHeaders()); IStream stream = createStream(synStream, listener, true, promise); if (stream == null) return; generateAndEnqueueControlFrame(stream, synStream, synInfo.getTimeout(), synInfo.getUnit(), stream); } }
@Override public void push(PushInfo pushInfo, Promise<Stream> promise) { notIdle(); if (isClosed() || isReset()) { close(); promise.failed(new StreamException(getId(), StreamStatus.STREAM_ALREADY_CLOSED, "Stream: " + this + " already closed or reset!")); return; } PushSynInfo pushSynInfo = new PushSynInfo(getId(), pushInfo); session.syn(pushSynInfo, null, new StreamPromise(promise)); }