You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by gn...@apache.org on 2013/11/29 16:30:55 UTC

svn commit: r1546581 - in /felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio: Marker.java ThreadIOImpl.java ThreadInputStream.java ThreadPrintStream.java

Author: gnodet
Date: Fri Nov 29 15:30:55 2013
New Revision: 1546581

URL: http://svn.apache.org/r1546581
Log:
[FELIX-4336] Use smarter thread locals for ThreadIo so that streams that have been deactivated won't be used and delegate to the previous stream instead

Modified:
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadInputStream.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadPrintStream.java

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java?rev=1546581&r1=1546580&r2=1546581&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/Marker.java Fri Nov 29 15:30:55 2013
@@ -23,26 +23,41 @@ import java.io.PrintStream;
 
 public class Marker
 {
-    Marker previous;
+    final Marker previous;
     InputStream in;
     PrintStream out;
     PrintStream err;
-    ThreadIOImpl parent;
+    volatile boolean deactivated;
 
-    public Marker(ThreadIOImpl parent, InputStream in, PrintStream out, PrintStream err, Marker previous)
+    public Marker(InputStream in, PrintStream out, PrintStream err, Marker previous)
     {
         this.previous = previous;
-        this.parent = parent;
         this.in = in;
         this.out = out;
         this.err = err;
     }
 
-    Marker activate()
+    public InputStream getIn()
     {
-        parent.in.setStream(in);
-        parent.out.setStream(out);
-        parent.err.setStream(err);
-        return previous;
+        return deactivated ? previous.getIn() : in;
+    }
+
+    public PrintStream getOut()
+    {
+        return deactivated ? previous.getOut() : out;
+    }
+
+    public PrintStream getErr()
+    {
+        return deactivated ? previous.getErr() : err;
+    }
+
+    void deactivate()
+    {
+        deactivated = true;
+        // Set to null for garbage collection
+        in = null;
+        out = null;
+        err = null;
     }
 }

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java?rev=1546581&r1=1546580&r2=1546581&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadIOImpl.java Fri Nov 29 15:30:55 2013
@@ -28,10 +28,19 @@ import java.util.logging.Logger;
 public class ThreadIOImpl implements ThreadIO
 {
     static private final Logger log = Logger.getLogger(ThreadIOImpl.class.getName());
-    ThreadPrintStream err = new ThreadPrintStream(System.err);
-    ThreadPrintStream out = new ThreadPrintStream(System.out);
-    ThreadInputStream in = new ThreadInputStream(System.in);
-    ThreadLocal<Marker> current = new InheritableThreadLocal<Marker>();
+
+    final Marker defaultMarker = new Marker(System.in, System.out, System.err, null);
+    final ThreadPrintStream err = new ThreadPrintStream(this, System.err, true);
+    final ThreadPrintStream out = new ThreadPrintStream(this, System.out, false);
+    final ThreadInputStream in = new ThreadInputStream(this, System.in);
+    final ThreadLocal<Marker> current = new InheritableThreadLocal<Marker>()
+    {
+        @Override
+        protected Marker initialValue()
+        {
+            return defaultMarker;
+        }
+    };
 
     public void start()
     {
@@ -46,9 +55,9 @@ public class ThreadIOImpl implements Thr
 
     public void stop()
     {
-        System.setErr(err.dflt);
-        System.setOut(out.dflt);
-        System.setIn(in.dflt);
+        System.setErr(defaultMarker.err);
+        System.setOut(defaultMarker.out);
+        System.setIn(defaultMarker.in);
     }
 
     private void checkIO()
@@ -72,6 +81,20 @@ public class ThreadIOImpl implements Thr
         }
     }
 
+    Marker current()
+    {
+        Marker m = current.get();
+        if (m.deactivated)
+        {
+            while (m.deactivated)
+            {
+                m = m.previous;
+            }
+            current.set(m);
+        }
+        return m;
+    }
+
     public void close()
     {
         checkIO(); // derek
@@ -80,18 +103,10 @@ public class ThreadIOImpl implements Thr
         {
             throw new IllegalStateException("No thread io active");
         }
-
-        Marker previous = top.previous;
-        if (previous == null)
-        {
-            in.end();
-            out.end();
-            err.end();
-        }
-        else
+        if (top != defaultMarker)
         {
-            this.current.set(previous);
-            previous.activate();
+            top.deactivate();
+            this.current.set(top.previous);
         }
     }
 
@@ -101,8 +116,7 @@ public class ThreadIOImpl implements Thr
         assert out != null;
         assert err != null;
         checkIO(); // derek
-        Marker marker = new Marker(this, in, out, err, current.get());
+        Marker marker = new Marker(in, out, err, current.get());
         this.current.set(marker);
-        marker.activate();
     }
 }

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadInputStream.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadInputStream.java?rev=1546581&r1=1546580&r2=1546581&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadInputStream.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadInputStream.java Fri Nov 29 15:30:55 2013
@@ -23,39 +23,19 @@ import java.io.InputStream;
 
 public class ThreadInputStream extends InputStream
 {
-    ThreadLocal<InputStream> map = new InheritableThreadLocal<InputStream>();
-    InputStream dflt;
+    final InputStream dflt;
+    final ThreadIOImpl io;
 
-    public ThreadInputStream(InputStream in)
+    public ThreadInputStream(ThreadIOImpl threadIO, InputStream in)
     {
+        io = threadIO;
         dflt = in;
     }
 
     private InputStream getCurrent()
     {
-        InputStream in = map.get();
-        if (in != null)
-        {
-            return in;
-        }
-        return dflt;
-    }
-
-    public void setStream(InputStream in)
-    {
-        if (in != dflt && in != this)
-        {
-            map.set(in);
-        }
-        else
-        {
-            map.remove();
-        }
-    }
-
-    public void end()
-    {
-        map.remove();
+        Marker marker = io.current();
+        return marker.getIn();
     }
 
     /**

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadPrintStream.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadPrintStream.java?rev=1546581&r1=1546580&r2=1546581&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadPrintStream.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/threadio/ThreadPrintStream.java Fri Nov 29 15:30:55 2013
@@ -25,40 +25,22 @@ import java.util.Locale;
 
 public class ThreadPrintStream extends PrintStream
 {
-    PrintStream dflt;
-    ThreadLocal<PrintStream> map = new InheritableThreadLocal<PrintStream>();
+    final PrintStream dflt;
+    final ThreadIOImpl io;
+    final boolean errorStream;
 
-    public ThreadPrintStream(PrintStream out)
+    public ThreadPrintStream(ThreadIOImpl threadIO, PrintStream out, boolean error)
     {
         super(out);
         dflt = out;
+        io = threadIO;
+        errorStream = error;
     }
 
     public PrintStream getCurrent()
     {
-        PrintStream out = map.get();
-        if (out != null)
-        {
-            return out;
-        }
-        return dflt;
-    }
-
-    public void setStream(PrintStream out)
-    {
-        if (out != dflt && out != this)
-        {
-            map.set(out);
-        }
-        else
-        {
-            map.remove();
-        }
-    }
-
-    public void end()
-    {
-        map.remove();
+        Marker marker = io.current();
+        return errorStream ? marker.getErr() : marker.getOut();
     }
 
     /**