@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); } flush(); }
@Override public Stream syn(SynInfo synInfo, StreamFrameListener listener) throws ExecutionException, InterruptedException, TimeoutException { FuturePromise<Stream> result = new FuturePromise<>(); syn(synInfo, listener, result); if (synInfo.getTimeout() > 0) return result.get(synInfo.getTimeout(), synInfo.getUnit()); else return result.get(); }