mturk       2005/02/05 04:34:47

  Added:       jni/examples/org/apache/tomcat/jni Echo.java Echo.properties
  Log:
  Add simpe Echo server with pollset for nonblocking
  call after the first message is read.
  
  Revision  Changes    Path
  1.1                  
jakarta-tomcat-connectors/jni/examples/org/apache/tomcat/jni/Echo.java
  
  Index: Echo.java
  ===================================================================
  /*
   *  Copyright 1999-2004 The Apache Software Foundation
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  
  package org.apache.tomcat.jni;
  
  import java.util.Properties;
  
  import java.io.*;
  import java.net.*;
  import java.lang.*;
  
  /** Echo server example
   *
   * @author Mladen Turk
   * @version $Revision: 1.1 $, $Date: 2005/02/05 12:34:47 $
   */
  
  public class Echo {
  
      public static String echoEcho = null;
      public static String echoAddr = null;
      public static int echoPort    = 0;
      public static int echoNmax    = 0;
      public static int echoNrun    = 0;
      public static long echoPool   = 0;
  
      private static Poller echoPoller     = null;
      private static Acceptor echoAcceptor = null;
  
      private static Object threadLock = new Object();
  
      static {
  
          try {
              InputStream is = Echo.class.getResourceAsStream
                  ("/org/apache/tomcat/jni/Echo.properties");
              Properties props = new Properties();
              props.load(is);
              is.close();
              echoAddr = props.getProperty("echo.ip", "127.0.0.1");
              echoPort = Integer.decode(props.getProperty("echo.port", "23"));
              echoNmax = Integer.decode(props.getProperty("echo.max", "1"));
          }
          catch (Throwable t) {
              ; // Nothing
          }
      }
  
      /* Acceptor thread. Listens for new connections */
      private class Acceptor extends Thread {
          private long serverSock = 0;
          private long inetAddress = 0;
          private long pool = 0;
          public Acceptor() {
              try {
  
                  pool = Pool.create(Echo.echoPool);
                  System.out.println("Accepting: " +  Echo.echoAddr + ":" +
                                     Echo.echoPort);
                  inetAddress = Address.info(Echo.echoAddr, Socket.APR_INET,
                                             Echo.echoPort, 0,
                                             pool);
                  serverSock = Socket.create(Socket.APR_INET, 
Socket.SOCK_STREAM,
                                             Socket.APR_PROTO_TCP, pool);
                  Socket.bind(serverSock, inetAddress);
                  Socket.listen(serverSock, 5);
              }
              catch( Exception ex ) {
                  ex.printStackTrace();
              }
          }
  
          public void run() {
              int i = 0;
              try {
                  while (true) {
                      long clientSock = Socket.accept(serverSock, pool);
                      System.out.println("Accepted id: " +  i);
                      Worker worker = new Worker(clientSock, i++,
                                                 this.getClass().getName());
                      Echo.incThreads();
                      worker.start();
                  }
              }
              catch( Exception ex ) {
                  ex.printStackTrace();
              }
          }
      }
  
      /* Poller thread. Listens for new recycled connections */
      private class Poller extends Thread {
          private long serverPollset = 0;
          private long pool = 0;
          private int nsocks = 0;
          public Poller() {
              try {
  
                  pool = Pool.create(Echo.echoPool);
                  serverPollset = Poll.create(16, pool, 0);
              }
              catch( Exception ex ) {
                  ex.printStackTrace();
              }
          }
  
          public void add(long socket, int workerId) {
              int rv = Poll.add(serverPollset, socket, workerId,
                                Poll.APR_POLLIN, 0);
              if (rv == Status.APR_SUCCESS) {
                  System.out.println("Added worker " + workerId + " to 
pollset");
                  nsocks++;
              }
          }
  
          public void remove(long socket, int workerId) {
              int rv = Poll.remove(serverPollset, socket);
              if (rv == Status.APR_SUCCESS) {
                 nsocks--;
                 System.out.println("Removed worker " + workerId + " from 
pollset");
              }
              else {
                 System.out.println("Failed removing worker " + workerId + " 
from pollset");
              }
          }
  
          public void run() {
              while (true) {
                  try {
                      if (nsocks < 1) {
                          Thread.sleep(1);
                          continue;
                      }
                      long [] desc = new long[16];
                      /* USe 1 second poll timeout */
                      int rv = Poll.poll(serverPollset, 1000000, desc);
                      for (int n = 0; n < rv; n++) {
                          long clientSock = Poll.socket(desc[n]);
                          int  workerId   = (int)Poll.data(desc[n]);
                          remove(clientSock, workerId);
                          Worker worker = new Worker(clientSock, workerId,
                                                     this.getClass().getName());
                          Echo.incThreads();
                          worker.start();
                      }
                  }
                  catch(Error err ) {
                      if (Status.APR_STATUS_IS_TIMEUP(err.getError())) {
                          /* TODO: deal with timeout */
                      }
                      else {
                          err.printStackTrace();
                          break;
                      }
                  }
                  catch( Exception ex ) {
                      ex.printStackTrace();
                      break;
                  }
              }
          }
      }
  
      private class Worker extends Thread {
          private int workerId = 0;
          private long clientSock = 0;
          private byte [] wellcomeMsg = null;
          public Worker(long clientSocket, int workerId, String from) {
              this.clientSock = clientSocket;
              this.workerId = workerId;
              wellcomeMsg = ("Echo server id: " + this.workerId + " from " +
                             from + "\r\n").getBytes();
          }
  
          public void run() {
              boolean doClose = false;
              try {
                  Socket.send(clientSock, wellcomeMsg, wellcomeMsg.length);
                  /* Do a blocking read byte at a time */
                  byte [] buf = new byte[1];
                  while (Socket.recv(clientSock, buf, 1) == 1) {
                      if (buf[0] == '\n')
                          break;
                      else if (buf[0] == 'Q') {
                          doClose = true;
                          break;
                      }
                  }
                  if (doClose) {
                      try {
                          byte [] msg = ("Bye from worker: " + workerId + 
"\r\n").getBytes();
                          Socket.send(clientSock, msg, msg.length);
                      } catch(Exception e) { }
  
                      Socket.close(clientSock);
                  }
                  else {
                      try {
                          byte [] msg = ("Recycling worker: " + workerId + 
"\r\n").getBytes();
                          Socket.send(clientSock, msg, msg.length);
                      } catch(Exception e) { }
                      /* Put the socket to the keep-alive poll */
                      Echo.echoPoller.add(clientSock, workerId);
                  }
              } catch (Exception e) {
                  Socket.close(clientSock);
                  e.printStackTrace();
              }
              Echo.decThreads();
              System.out.println("Worker: " +  workerId + " finished");
          }
      }
  
      public Echo()
      {
          int i;
          echoPool = Pool.create(0);
          echoAcceptor = new Acceptor();
          echoAcceptor.start();
          echoPoller = new Poller();
          echoPoller.start();
  
      }
  
      public static void incThreads() {
          synchronized(threadLock) {
              echoNrun++;
          }
      }
  
      public static void decThreads() {
          synchronized(threadLock) {
              echoNrun--;
          }
      }
  
      public static void main(String [] args) {
          try {
              Library.initialize(null);
              System.out.println("Starting Native Echo server example on port " 
+
                                 echoAddr + ":" + echoPort);
              Echo echo = new Echo();
          } catch (Exception e) {
              e.printStackTrace();
          }
  
      }
  }
  
  
  
  1.1                  
jakarta-tomcat-connectors/jni/examples/org/apache/tomcat/jni/Echo.properties
  
  Index: Echo.properties
  ===================================================================
  # Telnet properties
  echo.port=23
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to