예제 #1
0
  static void write(
      OioDatagramChannel channel,
      ChannelFuture future,
      Object message,
      SocketAddress remoteAddress) {
    try {
      ChannelBuffer buf = (ChannelBuffer) message;
      int length = buf.readableBytes();
      ByteBuffer nioBuf = buf.toByteBuffer();
      DatagramPacket packet;
      if (nioBuf.hasArray()) {
        // Avoid copy if the buffer is backed by an array.
        packet = new DatagramPacket(nioBuf.array(), nioBuf.arrayOffset(), length);
      } else {
        // Otherwise it will be expensive.
        byte[] arrayBuf = new byte[length];
        buf.getBytes(0, arrayBuf);
        packet = new DatagramPacket(arrayBuf, length);
      }

      if (remoteAddress != null) {
        packet.setSocketAddress(remoteAddress);
      }
      channel.socket.send(packet);
      fireWriteComplete(channel, length);
      future.setSuccess();
    } catch (Throwable t) {
      future.setFailure(t);
      fireExceptionCaught(channel, t);
    }
  }
예제 #2
0
파일: NioWorker.java 프로젝트: brl/netifera
  private static void writeNow(NioSocketChannel channel, int writeSpinCount) {

    boolean open = true;
    boolean addOpWrite = false;
    boolean removeOpWrite = false;

    MessageEvent evt;
    ChannelBuffer buf;
    int bufIdx;
    int writtenBytes = 0;

    Queue<MessageEvent> writeBuffer = channel.writeBuffer;
    synchronized (channel.writeLock) {
      channel.inWriteNowLoop = true;
      evt = channel.currentWriteEvent;
      for (; ; ) {
        if (evt == null) {
          evt = writeBuffer.poll();
          if (evt == null) {
            channel.currentWriteEvent = null;
            removeOpWrite = true;
            break;
          }

          evt = consolidateComposite(evt);
          buf = (ChannelBuffer) evt.getMessage();
          bufIdx = buf.readerIndex();
        } else {
          buf = (ChannelBuffer) evt.getMessage();
          bufIdx = channel.currentWriteIndex;
        }

        try {
          for (int i = writeSpinCount; i > 0; i--) {
            int localWrittenBytes =
                buf.getBytes(bufIdx, channel.socket, buf.writerIndex() - bufIdx);

            if (localWrittenBytes != 0) {
              bufIdx += localWrittenBytes;
              writtenBytes += localWrittenBytes;
              break;
            }
          }

          if (bufIdx == buf.writerIndex()) {
            // Successful write - proceed to the next message.
            channel.currentWriteEvent = null;
            evt.getFuture().setSuccess();
            evt = null;
          } else {
            // Not written fully - perhaps the kernel buffer is full.
            channel.currentWriteEvent = evt;
            channel.currentWriteIndex = bufIdx;
            addOpWrite = true;
            break;
          }
        } catch (AsynchronousCloseException e) {
          // Doesn't need a user attention - ignore.
          channel.currentWriteEvent = evt;
          channel.currentWriteIndex = bufIdx;
        } catch (Throwable t) {
          channel.currentWriteEvent = null;
          evt.getFuture().setFailure(t);
          evt = null;
          fireExceptionCaught(channel, t);
          if (t instanceof IOException) {
            open = false;
            close(channel, succeededFuture(channel));
          }
        }
      }
      channel.inWriteNowLoop = false;
    }

    fireWriteComplete(channel, writtenBytes);

    if (open) {
      if (addOpWrite) {
        setOpWrite(channel);
      } else if (removeOpWrite) {
        clearOpWrite(channel);
      }
    }
  }