371 // while we build the Http2Connection |
371 // while we build the Http2Connection |
372 return Http2Connection.createAsync(e.connection(), |
372 return Http2Connection.createAsync(e.connection(), |
373 client.client2(), |
373 client.client2(), |
374 this, e::drainLeftOverBytes) |
374 this, e::drainLeftOverBytes) |
375 .thenCompose((Http2Connection c) -> { |
375 .thenCompose((Http2Connection c) -> { |
376 c.putConnection(); |
376 boolean cached = c.offerConnection(); |
377 Stream<T> s = c.getStream(1); |
377 Stream<T> s = c.getStream(1); |
|
378 |
378 if (s == null) { |
379 if (s == null) { |
379 // s can be null if an exception occurred |
380 // s can be null if an exception occurred |
380 // asynchronously while sending the preface. |
381 // asynchronously while sending the preface. |
381 Throwable t = c.getRecordedCause(); |
382 Throwable t = c.getRecordedCause(); |
382 if (t != null) { |
383 if (t != null) { |
|
384 if (!cached) |
|
385 c.close(); |
383 return MinimalFuture.failedFuture( |
386 return MinimalFuture.failedFuture( |
384 new IOException("Can't get stream 1: " + t, t)); |
387 new IOException("Can't get stream 1: " + t, t)); |
385 } |
388 } |
386 } |
389 } |
|
390 if (!cached) |
|
391 s.closeConnectionOnCompletion(); |
387 exchImpl.released(); |
392 exchImpl.released(); |
388 Throwable t; |
393 Throwable t; |
389 // There's a race condition window where an external |
394 // There's a race condition window where an external |
390 // thread (SelectorManager) might complete the |
395 // thread (SelectorManager) might complete the |
391 // exchange in timeout at the same time where we're |
396 // exchange in timeout at the same time where we're |