felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r1773926 - in /felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline: Activator.java Shell.java
Date Tue, 13 Dec 2016 07:12:01 GMT
Author: gnodet
Date: Tue Dec 13 07:12:01 2016
New Revision: 1773926

URL: http://svn.apache.org/viewvc?rev=1773926&view=rev
Log:
[FELIX-5077] Gogo shell prints out nasty error on shutdown

Modified:
    felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
    felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java

Modified: felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java?rev=1773926&r1=1773925&r2=1773926&view=diff
==============================================================================
--- felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java (original)
+++ felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java Tue Dec
13 07:12:01 2016
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.gogo.jline;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashSet;
@@ -25,6 +27,7 @@ import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.felix.gogo.jline.Shell.Context;
 import org.apache.felix.gogo.jline.SingleServiceTracker.SingleServiceListener;
@@ -37,13 +40,15 @@ import org.jline.terminal.Terminal;
 import org.jline.terminal.TerminalBuilder;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
 import org.osgi.framework.ServiceRegistration;
 
 public class Activator implements BundleActivator, SingleServiceListener {
     private final Set<ServiceRegistration<?>> regs = new HashSet<>();
     private BundleContext context;
     private SingleServiceTracker<CommandProcessor> commandProcessorTracker;
-    private Thread thread;
+
+    private Runnable closer;
 
     public Activator() {
     }
@@ -66,7 +71,11 @@ public class Activator implements Bundle
 
     @Override
     public void serviceFound() {
-        startShell(context, commandProcessorTracker.getService());
+        try {
+            closer = startShell(context, commandProcessorTracker.getService());
+        } catch (Exception e) {
+            // Ignore
+        }
     }
 
     @Override
@@ -80,7 +89,7 @@ public class Activator implements Bundle
         serviceFound();
     }
 
-    private void startShell(BundleContext context, CommandProcessor processor) {
+    private Runnable startShell(BundleContext context, CommandProcessor processor) throws
Exception {
         Dictionary<String, Object> dict = new Hashtable<>();
         dict.put(CommandProcessor.COMMAND_SCOPE, "gogo");
 
@@ -102,23 +111,76 @@ public class Activator implements Bundle
         dict.put(CommandProcessor.COMMAND_FUNCTION, Shell.functions);
         regs.add(context.registerService(Shell.class.getName(), shell, dict));
 
+        Terminal terminal = TerminalBuilder.builder()
+                .system(true)
+                .nativeSignals(true)
+                .signalHandler(Terminal.SignalHandler.SIG_IGN)
+                .build();
+        CommandSession session = processor.createSession(terminal.input(), terminal.output(),
terminal.output());
+        AtomicBoolean closing = new AtomicBoolean();
+
+        Thread thread = new Thread(() -> {
+            String errorMessage = "gogo: unable to create console";
+            try {
+                session.put(Shell.VAR_TERMINAL, terminal);
+                try {
+                    List<String> args = new ArrayList<>();
+                    args.add("--login");
+                    String argstr = shell.getContext().getProperty("gosh.args");
+                    if (argstr != null) {
+                        Tokenizer tokenizer = new Tokenizer(argstr);
+                        Token token;
+                        while ((token = tokenizer.next()) != null) {
+                            args.add(token.toString());
+                        }
+                    }
+                    shell.gosh(session, args.toArray(new String[args.size()]));
+                } catch (Throwable e) {
+                    Object loc = session.get(".location");
+                    if (null == loc || !loc.toString().contains(":")) {
+                        loc = "gogo";
+                    }
+                    errorMessage = loc.toString();
+                    throw e;
+                }
+            } catch (Throwable e) {
+                if (!closing.get()) {
+                    System.err.println(errorMessage + e.getClass().getSimpleName() + ": "
+ e.getMessage());
+                    e.printStackTrace();
+                }
+            }
+        }, "Gogo shell");
         // start shell on a separate thread...
-        thread = new Thread(() -> doStartShell(processor, shell), "Gogo shell");
         thread.start();
-    }
 
-    private void stopShell() {
-        if (thread != null && thread.isAlive()) {
-            thread.interrupt();
+        return () -> {
+            closing.set(true);
+            shell.stop();
+            try {
+                terminal.close();
+            } catch (IOException e) {
+                // Ignore
+            }
             try {
-                thread.join(5000);
-                if (thread.isAlive()) {
-                    System.err.println("!!! FAILED TO STOP EXECUTOR !!!");
+                long t0 = System.currentTimeMillis();
+                while (thread.isAlive()) {
+                    thread.interrupt();
+                    thread.join(10);
+                    if (System.currentTimeMillis() - t0 > 5000) {
+                        System.err.println("!!! FAILED TO STOP EXECUTOR !!!");
+                        break;
+                    }
                 }
             } catch (InterruptedException e) {
                 // Restore administration...
                 Thread.currentThread().interrupt();
             }
+        };
+    }
+
+    private void stopShell() {
+        if (closer != null) {
+            closer.run();
         }
         while (!regs.isEmpty()) {
             ServiceRegistration<?> reg = regs.iterator().next();
@@ -127,41 +189,6 @@ public class Activator implements Bundle
         }
     }
 
-    private void doStartShell(CommandProcessor processor, Shell shell) {
-        String errorMessage = "gogo: unable to create console";
-        try (Terminal terminal = TerminalBuilder.builder()
-                .system(true)
-                .nativeSignals(true)
-                .signalHandler(Terminal.SignalHandler.SIG_IGN)
-                .build();
-             CommandSession session = processor.createSession(terminal.input(), terminal.output(),
terminal.output())) {
-            session.put(Shell.VAR_TERMINAL, terminal);
-            try {
-                List<String> args = new ArrayList<>();
-                args.add("--login");
-                String argstr = shell.getContext().getProperty("gosh.args");
-                if (argstr != null) {
-                    Tokenizer tokenizer = new Tokenizer(argstr);
-                    Token token;
-                    while ((token = tokenizer.next()) != null) {
-                        args.add(token.toString());
-                    }
-                }
-                shell.gosh(session, args.toArray(new String[args.size()]));
-            } catch (Exception e) {
-                Object loc = session.get(".location");
-                if (null == loc || !loc.toString().contains(":")) {
-                    loc = "gogo";
-                }
-                errorMessage = loc.toString();
-                throw e;
-            }
-        } catch (Exception e) {
-            System.err.println(errorMessage + e.getClass().getSimpleName() + ": " + e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
     private class ShellContext implements Context {
         public String getProperty(String name) {
             return context.getProperty(name);

Modified: felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java?rev=1773926&r1=1773925&r2=1773926&view=diff
==============================================================================
--- felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java (original)
+++ felix/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java Tue Dec 13
07:12:01 2016
@@ -87,6 +87,8 @@ public class Shell {
     private final Context context;
     private final CommandProcessor processor;
 
+    private AtomicBoolean stopping = new AtomicBoolean();
+
     public Shell(Context context, CommandProcessor processor) {
         this(context, processor, null);
     }
@@ -208,6 +210,10 @@ public class Shell {
         return null;
     }
 
+    public void stop() {
+        stopping.set(true);
+    }
+
     public Object gosh(final CommandSession session, String[] argv) throws Exception {
         final String[] usage = {
                 "gosh - execute script with arguments in a new session",
@@ -369,7 +375,7 @@ public class Shell {
                 String status = current.name().toLowerCase();
                 terminal.writer().write(getStatusLine(job, width, status));
                 terminal.flush();
-                if (reading.get()) {
+                if (reading.get() && !stopping.get()) {
                     ((LineReaderImpl) reader).redrawLine();
                     ((LineReaderImpl) reader).redisplay();
                 }
@@ -389,11 +395,16 @@ public class Shell {
         });
         Object result = null;
         try {
-            while (true) {
+            while (!stopping.get()) {
                 try {
                     reading.set(true);
                     try {
-                        reader.readLine(Shell.getPrompt(session), Shell.getRPrompt(session),
null, null);
+                        String prompt = Shell.getPrompt(session);
+                        String rprompt = Shell.getRPrompt(session);
+                        if (stopping.get()) {
+                            break;
+                        }
+                        reader.readLine(prompt, rprompt, null, null);
                     } finally {
                         reading.set(false);
                     }



Mime
View raw message