Example #1
0
 private int fillReadBuffer(boolean block) throws IOException {
   int nRead;
   NioChannel channel = getSocket();
   socketBufferHandler.configureReadBufferForWrite();
   if (block) {
     Selector selector = null;
     try {
       selector = pool.get();
     } catch (IOException x) {
       // Ignore
     }
     try {
       NioEndpoint.NioSocketWrapper att = (NioEndpoint.NioSocketWrapper) channel.getAttachment();
       if (att == null) {
         throw new IOException("Key must be cancelled.");
       }
       nRead =
           pool.read(
               socketBufferHandler.getReadBuffer(), channel, selector, att.getReadTimeout());
     } finally {
       if (selector != null) {
         pool.put(selector);
       }
     }
   } else {
     nRead = channel.read(socketBufferHandler.getReadBuffer());
     if (nRead == -1) {
       throw new EOFException();
     }
   }
   return nRead;
 }
Example #2
0
 /**
  * Registers a newly created socket with the poller.
  *
  * @param socket The newly created socket
  */
 public void register(final NioChannel socket) {
   socket.setPoller(this);
   NioSocketWrapper ka = new NioSocketWrapper(socket, NioEndpoint.this);
   socket.setSocketWrapper(ka);
   ka.setPoller(this);
   ka.setReadTimeout(getSocketProperties().getSoTimeout());
   ka.setWriteTimeout(getSocketProperties().getSoTimeout());
   ka.setKeepAliveLeft(NioEndpoint.this.getMaxKeepAliveRequests());
   ka.setSecure(isSSLEnabled());
   ka.setReadTimeout(getSoTimeout());
   ka.setWriteTimeout(getSoTimeout());
   PollerEvent r = eventCache.pop();
   ka.interestOps(SelectionKey.OP_READ); // this is what OP_REGISTER turns into.
   if (r == null) r = new PollerEvent(socket, ka, OP_REGISTER);
   else r.reset(socket, ka, OP_REGISTER);
   addEvent(r);
 }
Example #3
0
 /**
  * Add specified socket and associated pool to the poller. The socket will be added to a
  * temporary array, and polled first after a maximum amount of time equal to pollTime (in most
  * cases, latency will be much lower, however).
  *
  * @param socket to add to the poller
  * @param interestOps Operations for which to register this socket with the Poller
  */
 public void add(final NioChannel socket, final int interestOps) {
   PollerEvent r = eventCache.pop();
   if (r == null) r = new PollerEvent(socket, null, interestOps);
   else r.reset(socket, null, interestOps);
   addEvent(r);
   if (close) {
     NioEndpoint.NioSocketWrapper ka = (NioEndpoint.NioSocketWrapper) socket.getAttachment();
     processSocket(ka, SocketEvent.STOP, false);
   }
 }
Example #4
0
 private void close(NioChannel socket, SelectionKey key) {
   try {
     if (socket.getPoller().cancelledKey(key) != null) {
       // SocketWrapper (attachment) was removed from the
       // key - recycle the key. This can only happen once
       // per attempted closure so it is used to determine
       // whether or not to return the key to the cache.
       // We do NOT want to do this more than once - see BZ
       // 57340 / 57943.
       if (running && !paused) {
         if (!nioChannels.push(socket)) {
           socket.free();
         }
       }
     }
   } catch (Exception x) {
     log.error("", x);
   }
 }
Example #5
0
  @Override
  public void deliver(Channel channel, byte[] bytes) {

    ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
    buffer.put(bytes);
    buffer.flip();
    int length = buffer.getInt();
    byte messageID = buffer.get();

    switch (messageID) {
      case 0:
        byte[] deliver_array = new byte[length - 9];
        int sender_id = buffer.getInt();
        int lamport_timestamp = buffer.getInt();
        buffer.get(deliver_array, 0, deliver_array.length);
        /*for (int i = 0; i < deliver_array.length; i++) {
        	System.out.print(deliver_array[i] + " ");
        }*/
        System.out.println("\n" + "---------------------------------------------------");
        break;

      case 3:
        sender_id = buffer.getInt();
        lamport_timestamp = buffer.getInt();

        /*Si on est à l'origine du BroadcastJoin, on envoie d'abord la liste des autres peers avant de nous même se bloquer*/
        if (engine.getId() == sender_id) {
          engine.setTimestamp(engine.getTimestamp() + 1);
          Message m =
              new MemberListMessage(engine.getTimestamp(), engine.getId(), engine.getPeersList());
          byte[] message_array = m.sendMessage();
          for (Channel other_channel : engine.getChannelList()) {
            if (((NioChannel) other_channel).isNouveauvenu()) {
              other_channel.send(message_array, 0, message_array.length);
              ((NioChannel) other_channel).setNouveauvenu(false);
            }
          }
        }
        ((NioChannel) channel).setBlocked(true);
        break;
    }
  }
Example #6
0
  /**
   * Process the specified connection.
   *
   * @param socket The socket channel
   * @return <code>true</code> if the socket was correctly configured and processing may continue,
   *     <code>false</code> if the socket needs to be close immediately
   */
  protected boolean setSocketOptions(SocketChannel socket) {
    // Process the connection
    try {
      // disable blocking, APR style, we are gonna be polling it
      socket.configureBlocking(false);
      Socket sock = socket.socket();
      socketProperties.setProperties(sock);

      NioChannel channel = nioChannels.pop();
      if (channel == null) {
        SocketBufferHandler bufhandler =
            new SocketBufferHandler(
                socketProperties.getAppReadBufSize(),
                socketProperties.getAppWriteBufSize(),
                socketProperties.getDirectBuffer());
        if (isSSLEnabled()) {
          channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
        } else {
          channel = new NioChannel(socket, bufhandler);
        }
      } else {
        channel.setIOChannel(socket);
        channel.reset();
      }
      getPoller0().register(channel);
    } catch (Throwable t) {
      ExceptionUtils.handleThrowable(t);
      try {
        log.error("", t);
      } catch (Throwable tt) {
        ExceptionUtils.handleThrowable(tt);
      }
      // Tell to close the socket
      return false;
    }
    return true;
  }
Example #7
0
 @Override
 public void run() {
   if (interestOps == OP_REGISTER) {
     try {
       socket
           .getIOChannel()
           .register(socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);
     } catch (Exception x) {
       log.error(sm.getString("endpoint.nio.registerFail"), x);
     }
   } else {
     final SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
     try {
       if (key == null) {
         // The key was cancelled (e.g. due to socket closure)
         // and removed from the selector while it was being
         // processed. Count down the connections at this point
         // since it won't have been counted down when the socket
         // closed.
         socket.socketWrapper.getEndpoint().countDownConnection();
       } else {
         final NioSocketWrapper socketWrapper = (NioSocketWrapper) key.attachment();
         if (socketWrapper != null) {
           // we are registering the key to start with, reset the fairness counter.
           int ops = key.interestOps() | interestOps;
           socketWrapper.interestOps(ops);
           key.interestOps(ops);
         } else {
           socket.getPoller().cancelledKey(key);
         }
       }
     } catch (CancelledKeyException ckx) {
       try {
         socket.getPoller().cancelledKey(key);
       } catch (Exception ignore) {
       }
     }
   }
 }
Example #8
0
    public SendfileState processSendfile(
        SelectionKey sk, NioSocketWrapper socketWrapper, boolean calledByProcessor) {
      NioChannel sc = null;
      try {
        unreg(sk, socketWrapper, sk.readyOps());
        SendfileData sd = socketWrapper.getSendfileData();

        if (log.isTraceEnabled()) {
          log.trace("Processing send file for: " + sd.fileName);
        }

        if (sd.fchannel == null) {
          // Setup the file channel
          File f = new File(sd.fileName);
          if (!f.exists()) {
            cancelledKey(sk);
            return SendfileState.ERROR;
          }
          @SuppressWarnings("resource") // Closed when channel is closed
          FileInputStream fis = new FileInputStream(f);
          sd.fchannel = fis.getChannel();
        }

        // Configure output channel
        sc = socketWrapper.getSocket();
        // TLS/SSL channel is slightly different
        WritableByteChannel wc = ((sc instanceof SecureNioChannel) ? sc : sc.getIOChannel());

        // We still have data in the buffer
        if (sc.getOutboundRemaining() > 0) {
          if (sc.flushOutbound()) {
            socketWrapper.updateLastWrite();
          }
        } else {
          long written = sd.fchannel.transferTo(sd.pos, sd.length, wc);
          if (written > 0) {
            sd.pos += written;
            sd.length -= written;
            socketWrapper.updateLastWrite();
          } else {
            // Unusual not to be able to transfer any bytes
            // Check the length was set correctly
            if (sd.fchannel.size() <= sd.pos) {
              throw new IOException(
                  "Sendfile configured to " + "send more data than was available");
            }
          }
        }
        if (sd.length <= 0 && sc.getOutboundRemaining() <= 0) {
          if (log.isDebugEnabled()) {
            log.debug("Send file complete for: " + sd.fileName);
          }
          socketWrapper.setSendfileData(null);
          try {
            sd.fchannel.close();
          } catch (Exception ignore) {
          }
          // For calls from outside the Poller, the caller is
          // responsible for registering the socket for the
          // appropriate event(s) if sendfile completes.
          if (!calledByProcessor) {
            if (sd.keepAlive) {
              if (log.isDebugEnabled()) {
                log.debug("Connection is keep alive, registering back for OP_READ");
              }
              reg(sk, socketWrapper, SelectionKey.OP_READ);
            } else {
              if (log.isDebugEnabled()) {
                log.debug("Send file connection is being closed");
              }
              close(sc, sk);
            }
          }
          return SendfileState.DONE;
        } else {
          if (log.isDebugEnabled()) {
            log.debug("OP_WRITE for sendfile: " + sd.fileName);
          }
          if (calledByProcessor) {
            add(socketWrapper.getSocket(), SelectionKey.OP_WRITE);
          } else {
            reg(sk, socketWrapper, SelectionKey.OP_WRITE);
          }
          return SendfileState.PENDING;
        }
      } catch (IOException x) {
        if (log.isDebugEnabled()) log.debug("Unable to complete sendfile request:", x);
        if (!calledByProcessor && sc != null) {
          close(sc, sk);
        } else {
          cancelledKey(sk);
        }
        return SendfileState.ERROR;
      } catch (Throwable t) {
        log.error("", t);
        if (!calledByProcessor && sc != null) {
          close(sc, sk);
        } else {
          cancelledKey(sk);
        }
        return SendfileState.ERROR;
      }
    }
Example #9
0
    @Override
    protected void doRun() {
      NioChannel socket = socketWrapper.getSocket();
      SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());

      try {
        int handshake = -1;

        try {
          if (key != null) {
            // For STOP there is no point trying to handshake as the
            // Poller has been stopped.
            if (socket.isHandshakeComplete() || event == SocketEvent.STOP) {
              handshake = 0;
            } else {
              handshake = socket.handshake(key.isReadable(), key.isWritable());
              // The handshake process reads/writes from/to the
              // socket. status may therefore be OPEN_WRITE once
              // the handshake completes. However, the handshake
              // happens when the socket is opened so the status
              // must always be OPEN_READ after it completes. It
              // is OK to always set this as it is only used if
              // the handshake completes.
              event = SocketEvent.OPEN_READ;
            }
          }
        } catch (IOException x) {
          handshake = -1;
          if (log.isDebugEnabled()) log.debug("Error during SSL handshake", x);
        } catch (CancelledKeyException ckx) {
          handshake = -1;
        }
        if (handshake == 0) {
          SocketState state = SocketState.OPEN;
          // Process the request from this socket
          if (event == null) {
            state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
          } else {
            state = getHandler().process(socketWrapper, event);
          }
          if (state == SocketState.CLOSED) {
            close(socket, key);
          }
        } else if (handshake == -1) {
          close(socket, key);
        } else if (handshake == SelectionKey.OP_READ) {
          socketWrapper.registerReadInterest();
        } else if (handshake == SelectionKey.OP_WRITE) {
          socketWrapper.registerWriteInterest();
        }
      } catch (CancelledKeyException cx) {
        socket.getPoller().cancelledKey(key);
      } catch (VirtualMachineError vme) {
        ExceptionUtils.handleThrowable(vme);
      } catch (Throwable t) {
        log.error("", t);
        socket.getPoller().cancelledKey(key);
      } finally {
        socketWrapper = null;
        event = null;
        // return to cache
        if (running && !paused) {
          processorCache.push(this);
        }
      }
    }
Example #10
0
 public NioSocketWrapper(NioChannel channel, NioEndpoint endpoint) {
   super(channel, endpoint);
   pool = endpoint.getSelectorPool();
   socketBufferHandler = channel.getBufHandler();
 }