synchronized SpdyStream removeStream(int streamId) { SpdyStream stream = streams.remove(streamId); if (stream != null && streams.isEmpty()) { setIdle(true); } return stream; }
private void close(ErrorCode connectionCode, ErrorCode streamCode) throws IOException { assert (!Thread.holdsLock(this)); IOException thrown = null; try { shutdown(connectionCode); } catch (IOException e) { thrown = e; } SpdyStream[] streamsToClose = null; Ping[] pingsToCancel = null; synchronized (this) { if (!streams.isEmpty()) { streamsToClose = streams.values().toArray(new SpdyStream[streams.size()]); streams.clear(); setIdle(false); } if (pings != null) { pingsToCancel = pings.values().toArray(new Ping[pings.size()]); pings = null; } } if (streamsToClose != null) { for (SpdyStream stream : streamsToClose) { try { stream.close(streamCode); } catch (IOException e) { if (thrown != null) thrown = e; } } } if (pingsToCancel != null) { for (Ping ping : pingsToCancel) { ping.cancel(); } } try { frameReader.close(); } catch (IOException e) { thrown = e; } try { frameWriter.close(); } catch (IOException e) { if (thrown == null) thrown = e; } if (thrown != null) throw thrown; }
private SpdyStream newStream( int associatedStreamId, List<Header> requestHeaders, boolean out, boolean in) throws IOException { boolean outFinished = !out; boolean inFinished = !in; int priority = -1; // TODO: permit the caller to specify a priority? int slot = 0; // TODO: permit the caller to specify a slot? SpdyStream stream; int streamId; synchronized (frameWriter) { synchronized (this) { if (shutdown) { throw new IOException("shutdown"); } streamId = nextStreamId; nextStreamId += 2; stream = new SpdyStream(streamId, this, outFinished, inFinished, priority, requestHeaders); if (stream.isOpen()) { streams.put(streamId, stream); setIdle(false); } } if (associatedStreamId == 0) { frameWriter.synStream( outFinished, inFinished, streamId, associatedStreamId, priority, slot, requestHeaders); } else if (client) { throw new IllegalArgumentException("client streams shouldn't have associated stream IDs"); } else { // HTTP/2 has a PUSH_PROMISE frame. frameWriter.pushPromise(associatedStreamId, streamId, requestHeaders); } } if (!out) { frameWriter.flush(); } return stream; }