/** Non blocking if the socket is not blocking. */ private boolean _drain() { while (true) { synchronized (outQueue) { if (out == null) { out = prioriyQueue.poll(); if (out == null) { out = outQueue.poll(); } if (out == null) { return false; } if (goAway < out.streamId) { // TODO } try { if (!out.c) { // late: IDs are assigned as we send ( priorities may affect // the transmission order ) if (out.stream != null) { out.streamId = out.stream.getRequest().streamId; } } else if (out.type == TYPE_SYN_STREAM) { out.fixNV(18); if (compressSupport != null) { compressSupport.compress(out, 18); } } else if (out.type == TYPE_SYN_REPLY || out.type == TYPE_HEADERS) { out.fixNV(14); if (compressSupport != null) { compressSupport.compress(out, 14); } } } catch (IOException ex) { abort("Compress error"); return false; } if (out.type == TYPE_SYN_STREAM) { out.streamId = outStreamId; outStreamId += 2; synchronized (channels) { channels.put(Integer.valueOf(out.streamId), out.stream); } } out.serializeHead(); } if (out.endData == out.off) { out = null; continue; } } if (SpdyContext.debug) { trace("> " + out); } try { int toWrite = out.endData - out.off; int wr; while (toWrite > 0) { wr = write(out.data, out.off, toWrite); if (wr < 0) { return false; } if (wr == 0) { return true; // non blocking or to } if (wr <= toWrite) { out.off += wr; toWrite -= wr; } } synchronized (channels) { if (out.stream != null) { if (out.isHalfClose()) { out.stream.finSent = true; } if (out.stream.finRcvd && out.stream.finSent) { channels.remove(Integer.valueOf(out.streamId)); } } } out = null; } catch (IOException e) { // connection closed - abort all streams e.printStackTrace(); onClose(); return false; } } }