]> git.argeo.org Git - lgpl/argeo-commons.git/blob - GogoShellKiller.java
a8c901644b13e21cb9d63f565efac5832c35d1ea
[lgpl/argeo-commons.git] / GogoShellKiller.java
1 package org.argeo.cms.internal.osgi;
2
3 /**
4 * Workaround for killing Gogo shell by system shutdown.
5 *
6 * @see https://issues.apache.org/jira/browse/FELIX-4208
7 */
8 class GogoShellKiller extends Thread {
9
10 public GogoShellKiller() {
11 super("Gogo Shell Killer");
12 setDaemon(true);
13 }
14
15 @Override
16 public void run() {
17 ThreadGroup rootTg = getRootThreadGroup(null);
18 Thread gogoShellThread = findGogoShellThread(rootTg);
19 if (gogoShellThread == null) // no need to bother if it is not here
20 return;
21 while (getNonDaemonCount(rootTg) > 2) {
22 try {
23 Thread.sleep(100);
24 } catch (InterruptedException e) {
25 // silent
26 }
27 }
28 gogoShellThread = findGogoShellThread(rootTg);
29 if (gogoShellThread == null)
30 return;
31 System.exit(0);
32 // No non-deamon threads left, forcibly halting the VM
33 //Runtime.getRuntime().halt(0);
34 }
35
36 private ThreadGroup getRootThreadGroup(ThreadGroup tg) {
37 if (tg == null)
38 tg = Thread.currentThread().getThreadGroup();
39 if (tg.getParent() == null)
40 return tg;
41 else
42 return getRootThreadGroup(tg.getParent());
43 }
44
45 private int getNonDaemonCount(ThreadGroup rootThreadGroup) {
46 Thread[] threads = new Thread[rootThreadGroup.activeCount()];
47 rootThreadGroup.enumerate(threads);
48 int nonDameonCount = 0;
49 for (Thread t : threads)
50 if (t != null && !t.isDaemon())
51 nonDameonCount++;
52 return nonDameonCount;
53 }
54
55 private Thread findGogoShellThread(ThreadGroup rootThreadGroup) {
56 Thread[] threads = new Thread[rootThreadGroup.activeCount()];
57 rootThreadGroup.enumerate(threads, true);
58 for (Thread thread : threads) {
59 if (thread.getName().equals("pipe-gosh --login --noshutdown"))
60 return thread;
61 }
62 return null;
63 }
64
65 }