commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From patri...@apache.org
Subject cvs commit: jakarta-commons-sandbox/daemon/src/java/org/apache/commons/launcher NonBlockingInputStream.java ChildMain.java
Date Wed, 21 Aug 2002 03:09:04 GMT
patrickl    2002/08/20 20:09:04

  Modified:    daemon/src/java/org/apache/commons/launcher ChildMain.java
  Added:       daemon/src/java/org/apache/commons/launcher
                        NonBlockingInputStream.java
  Log:
  Eliminate blocking of the entire child JVM when the target application reads System.in.
This blocking can happen on certain Windows platforms.
  
  Revision  Changes    Path
  1.8       +12 -2     jakarta-commons-sandbox/daemon/src/java/org/apache/commons/launcher/ChildMain.java
  
  Index: ChildMain.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/daemon/src/java/org/apache/commons/launcher/ChildMain.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ChildMain.java	22 Jul 2002 04:59:06 -0000	1.7
  +++ ChildMain.java	21 Aug 2002 03:09:04 -0000	1.8
  @@ -194,9 +194,20 @@
           // Invoke the target application
           try {
   
  +            String osname = System.getProperty("os.name").toLowerCase();
  +            boolean windows = false;
  +            if (osname.indexOf("windows") >= 0)
  +                windows = true;
  +
               // Start the thread to check if the parent JVM exits.
               boolean waitForChild = false;
               if (System.getProperty(ChildMain.WAIT_FOR_CHILD_PROP_NAME) != null) {
  +                // Swap in a non-blocking input stream for System.in since
  +                // reading System.in can block the entire process on some
  +                // Windows platforms
  +                if (windows)
  +                    System.setIn(new NonBlockingInputStream(System.in));
  +
                   waitForChild = true;
                   String heartbeatFile = System.getProperty(ChildMain.HEARTBEAT_FILE_PROP_NAME);
                   ParentListener heartbeat = new ParentListener(heartbeatFile);
  @@ -236,8 +247,7 @@
               boolean displayMinimizedWindow = false;
               if (System.getProperty(ChildMain.DISPLAY_MINIMIZED_WINDOW_PROP_NAME) != null)
                   displayMinimizedWindow = true;
  -            String osname = System.getProperty("os.name").toLowerCase();
  -            if (displayMinimizedWindow && osname.indexOf("windows") >= 0) {
  +            if (displayMinimizedWindow && windows) {
                   try {
                       frame = new Frame();
                       String title = System.getProperty(ChildMain.MINIMIZED_WINDOW_TITLE_PROP_NAME);
  
  
  
  1.1                  jakarta-commons-sandbox/daemon/src/java/org/apache/commons/launcher/NonBlockingInputStream.java
  
  Index: NonBlockingInputStream.java
  ===================================================================
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
   *                                                                           *
   *             Copyright (c) 2002 The Apache Software Foundation.            *
   *                           All rights reserved.                            *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * Redistribution and use in source and binary forms,  with or without modi- *
   * fication, are permitted provided that the following conditions are met:   *
   *                                                                           *
   * 1. Redistributions of source code  must retain the above copyright notice *
   *    notice, this list of conditions and the following disclaimer.          *
   *                                                                           *
   * 2. Redistributions  in binary  form  must  reproduce the  above copyright *
   *    notice,  this list of conditions  and the following  disclaimer in the *
   *    documentation and/or other materials provided with the distribution.   *
   *                                                                           *
   * 3. The end-user documentation  included with the redistribution,  if any, *
   *    must include the following acknowlegement:                             *
   *                                                                           *
   *       "This product includes  software developed  by the Apache  Software *
   *        Foundation <http://www.apache.org/>."                              *
   *                                                                           *
   *    Alternately, this acknowlegement may appear in the software itself, if *
   *    and wherever such third-party acknowlegements normally appear.         *
   *                                                                           *
   * 4. The names  "The Jakarta  Project",  and  "Apache  Software Foundation" *
   *    must not  be used  to endorse  or promote  products derived  from this *
   *    software without  prior written  permission.  For written  permission, *
   *    please contact <apache@apache.org>.                                    *
   *                                                                           *
   * 5. Products derived from this software may not be called "Apache" nor may *
   *    "Apache" appear in their names without prior written permission of the *
   *    Apache Software Foundation.                                            *
   *                                                                           *
   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES *
   * INCLUDING, BUT NOT LIMITED TO,  THE IMPLIED WARRANTIES OF MERCHANTABILITY *
   * AND FITNESS FOR  A PARTICULAR PURPOSE  ARE DISCLAIMED.  IN NO EVENT SHALL *
   * THE APACHE  SOFTWARE  FOUNDATION OR  ITS CONTRIBUTORS  BE LIABLE  FOR ANY *
   * DIRECT,  INDIRECT,   INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL *
   * DAMAGES (INCLUDING,  BUT NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE GOODS *
   * OR SERVICES;  LOSS OF USE,  DATA,  OR PROFITS;  OR BUSINESS INTERRUPTION) *
   * HOWEVER CAUSED AND  ON ANY  THEORY  OF  LIABILITY,  WHETHER IN  CONTRACT, *
   * STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF  ADVISED  OF THE *
   * POSSIBILITY OF SUCH DAMAGE.                                               *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * This software  consists of voluntary  contributions made  by many indivi- *
   * duals on behalf of the  Apache Software Foundation.  For more information *
   * on the Apache Software Foundation, please see <http://www.apache.org/>.   *
   *                                                                           *
   * ========================================================================= */
  
  package org.apache.commons.launcher;
  
  import java.io.BufferedInputStream;
  import java.io.InputStream;
  import java.io.IOException;
  
   /**
   * A class that prevents blocking reads. This class is usually used to prevent
   * native blocking reads of System.in on Windows platforms since on some
   * Windows platforms, reading System.in will cause the entire JVM to block.
   *
   * @author Patrick Luby
   */
  public class NonBlockingInputStream extends BufferedInputStream {
  
      protected InputStream in = null;
  
      //------------------------------------------------------------ Constructors
  
      /**
       * Creates a <code>NonBlockingInputStream</code> by using the
       * {@link BufferedInputStream} as the underlying input stream.
       *
       * @param in the underlying input stream
       */
      public NonBlockingInputStream(InputStream in) {
  
          super(in);
  
      }
  
      //----------------------------------------------------------------- Methods
  
      /**
       * Reads the next byte of data from this input stream. This method invokes
       * the superclass' {@link BufferedInputStream#read()} method if the number
       * of available bytes is greater than 0.
       *
       * @return the next byte of data, or -1 if the end of the stream is reached
       * @throws IOExeption if an I/O error occurs
       */
      public synchronized int read() throws IOException {
  
          int available = waitForAvailable();
          if (available > 0)
              return super.read();
          else
              return available;
  
      }
  
      /**
       * Reads some number of bytes from the input stream and stores them into the     * specified
buffer. This method invokes the superclass'
       * {@link BufferedInputStream#read(byte[])} method if the number of
       * available bytes is greater than 0.
       *
       * @param b the buffer into which the data is read
       * @return the total number of bytes read into the buffer, or -1 if the end
       *  of the stream is reached
       * @throws IOExeption if an I/O error occurs
       */
      public synchronized int read(byte[] b) throws IOException {
  
          int available = waitForAvailable();
          if (available > 0)
              return super.read(b, 0, available);
          else
              return available;
  
      }
  
      /**
       * Reads up to <code>len</code> bytes from the input stream and stores them
       * into the specified buffer. This method invokes the superclass'
       * {@link BufferedInputStream#read(byte[], int, int)} method if the number
       * of available bytes is greater than 0.
       *
       * @param b the buffer into which the data is read
       * @param off the start offset in array b at which the data is written
       * @param len the maximum number of bytes to read 
       * @return the total number of bytes read into the buffer, or -1 if the end
       *  of the stream is reached
       * @throws IOExeption if an I/O error occurs
       */
      public synchronized int read(byte[] b, int off, int len)
          throws IOException
      {
  
          int available = waitForAvailable();
          if (available > 0) {
              if (available < len)
                  len = available;
              return super.read(b, off, len);
          } else {
              return available;
          }
  
      }
  
      /**
       * Skips over and discards <code>n</code> bytes of data from this input
       * stream. This method invokes the superclass'
       * {@link BufferedInputStream#skip(long)} method if the number of
       * available bytes is greater than 0.
       *
       * @param n the number of bytes to be skipped
       * @return the actual number of bytes skipped
       * @throws IOExeption if an I/O error occurs
       */
      public synchronized long skip(long n) throws IOException {
  
          int available = waitForAvailable();
          if (available > 0) {
              if (available < n)
                  n = available;
              return super.skip(n);
          } else {
              return available;
          }
  
      }
  
      /**
       * Block until the {@link #available()} method returns something other
       * than 0. This method emulates the blocking. Of course, this method
       * is not nearly as efficient as native blocking. However, it is the
       * only alternative on some Windows platforms where I/0 operations cause 
       * the entire JVM to block.
       *
       * @return the number of bytes that can read from this input stream
       *  without any native blocking
       * @throws IOExeption if an I/O error occurs
       */
      protected int waitForAvailable() throws IOException {
  
          int available = 0;
          while ((available = available()) == 0) {
              try {
                  Thread.currentThread().sleep(100);
              } catch (Exception e) {}
          }
          return available;
  
      }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message