Exemplo n.º 1
0
  /** 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;
      }
    }
  }