Changeset 5887


Ignore:
Timestamp:
2003-11-19T10:54:23+13:00 (20 years ago)
Author:
jmt12
Message:

Changed the process stream readers to try and avoid the deadlock between java reading from one stream while the process is writing to the other.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/shell/GShell.java

    r5840 r5887  
    8989    /** Element in process type name enumeration */
    9090    static public String GSHELL_EXPORT = "gshell_export";
     91
     92    /** Determine if the given process is still executing. It does this by attempting to throw an exception - not the most efficient way, but the only one as far as I know
     93     * @param process the Process to test
     94     * @return true if it is still executing, false otherwise
     95     */
     96    static public boolean processRunning(Process process) {
     97    boolean process_running = false;
     98    try {
     99        process.exitValue(); // This will throw an exception if the process hasn't ended yet.
     100    }
     101    catch(IllegalThreadStateException itse) {
     102        process_running = true;
     103    }
     104    catch(Exception exception) {
     105        Gatherer.printStackTrace(exception);
     106    }
     107    return process_running;
     108    }
    91109   
    92110    /** Constructor gatherer all the data required to create a new process, and emit meaningfull messages.
     
    161179        Process prcs = rt.exec(args);
    162180        InputStreamReader eisr = new InputStreamReader( prcs.getErrorStream() );
    163         InputStreamReader stdinisr = new InputStreamReader( prcs.getInputStream() );
    164         BufferedReader ebr = new BufferedReader( eisr );
    165         BufferedReader stdinbr = new BufferedReader( stdinisr );
     181        InputStreamReader stdisr = new InputStreamReader( prcs.getInputStream() );
     182        //BufferedReader ebr = new BufferedReader( eisr );
     183        //BufferedReader stdinbr = new BufferedReader( stdinisr );
    166184        // Captures the std err of a program and pipes it into std in of java
     185       
     186        StringBuffer eline_buffer = new StringBuffer();
     187        StringBuffer stdline_buffer = new StringBuffer();
     188        while(processRunning(prcs) && !hasSignalledStop()) {
     189        // Hopefully this doesn't block if the process is trying to write to STDOUT.
     190        if(eisr.ready()) {
     191            int c = eisr.read();
     192            if(c == '\n' || c == '\r') {
     193            if(eline_buffer.length() > 0) {
     194                String eline = eline_buffer.toString();
     195                System.err.print("*");
     196                if(progress != null) {
     197                progress.parse(eline);
     198                }
     199                if(bos != null) {
     200                try {
     201                    bos.write(eline.getBytes(), 0, eline.length());
     202                }
     203                catch(Exception error) {
     204                    Gatherer.printStackTrace(error);
     205                }
     206                }
     207                fireMessage(type, typeAsString(type) + "> " + eline, status);
     208                eline = null;
     209                eline_buffer = new StringBuffer();
     210            }
     211            }
     212            else {
     213            eline_buffer.append((char)c);
     214            }
     215        }
     216        // Hopefully this won't block if the process is trying to write to STDERR
     217        if(stdisr.ready()) {
     218            int c = stdisr.read();
     219            if(c == '\n' || c == '\r') {
     220            if(stdline_buffer.length() > 0) {
     221                String stdline = stdline_buffer.toString();
     222                System.err.print("+");
     223                fireMessage(type, typeAsString(type) + "> " + stdline, status);
     224                stdline = null;
     225                stdline_buffer = new StringBuffer();
     226            }
     227            }
     228            else {
     229            stdline_buffer.append((char)c);
     230            }
     231        }
     232        }
     233
     234        /** This causes Phind to deadlock
    167235        String eline = null;
    168236        String stdinline = null;
    169         while (((eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !hasSignalledStop()) {
     237        while ((( eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !hasSignalledStop()) {
    170238        if(eline != null) {
     239            System.err.print("*");
    171240            if(progress != null) {
    172241            progress.parse(eline);
     
    183252        }
    184253        if(stdinline != null) {
     254            System.err.print("+");
    185255            fireMessage(type, typeAsString(type) + "> " + stdinline, status);
    186256        }
    187257        }
     258        */
    188259
    189260        if(!hasSignalledStop()) {
     
    203274        // I need to somehow kill the child process. Unfortunately Thread.stop() and Process.destroy() both fail to do this. But now, thankx to the magic of Michaels 'close the stream suggestion', it works fine (no it doesn't!)
    204275        prcs.getInputStream().close();
     276        prcs.getErrorStream().close();
    205277        prcs.getOutputStream().close();
    206278        prcs.destroy();
Note: See TracChangeset for help on using the changeset viewer.