Automated merge with http://hg.netbeans.org/netigso
authorffjre@netbeans.org
Fri, 19 Jun 2009 03:44:33 +0400
changeset 9219b35ddc3fdb0
parent 920 e169ba9ab6e6
parent 794 e17978bf2b27
child 922 32eafc9ea617
Automated merge with http://hg.netbeans.org/netigso
     1.1 --- a/openide.util/apichanges.xml	Wed Jun 17 03:52:56 2009 +0400
     1.2 +++ b/openide.util/apichanges.xml	Fri Jun 19 03:44:33 2009 +0400
     1.3 @@ -49,6 +49,21 @@
     1.4      <apidef name="actions">Actions API</apidef>
     1.5  </apidefs>
     1.6  <changes>
     1.7 +    <change id="enableStackTraces">
     1.8 +        <api name="util"/>
     1.9 +        <summary>Added constructor <code>RequestProcessor(String name, int throughput, boolean interruptThread, boolean enableStackTraces)</code></summary>
    1.10 +        <version major="7" minor="24"/>
    1.11 +        <date day="8" month="6" year="2009"/>
    1.12 +        <author login="rmichalsky"/>
    1.13 +        <compatibility addition="yes"/>
    1.14 +        <description>
    1.15 +            <p>
    1.16 +                Newly added constructor allows to disable (slow) filling stack traces before posting each task. 
    1.17 +            </p>
    1.18 +        </description>
    1.19 +        <class package="org.openide.util" name="RequestProcessor"/>
    1.20 +        <issue number="165862"/>
    1.21 +    </change>
    1.22      <change id="ImageUtilities.loadImageIcon">
    1.23          <api name="util"/>
    1.24          <summary>Added <code>loadImageIcon(String resource, boolean localized)</code></summary>
     2.1 --- a/openide.util/nbproject/project.properties	Wed Jun 17 03:52:56 2009 +0400
     2.2 +++ b/openide.util/nbproject/project.properties	Fri Jun 19 03:44:33 2009 +0400
     2.3 @@ -42,7 +42,7 @@
     2.4  module.jar.dir=lib
     2.5  cp.extra=${nb_all}/apisupport.harness/external/openjdk-javac-6-b12.jar
     2.6  
     2.7 -spec.version.base=7.23.0
     2.8 +spec.version.base=7.24.0
     2.9  
    2.10  # For XMLSerializer, needed for XMLUtil.write to work w/ namespaces under JDK 1.4:
    2.11  
     3.1 --- a/openide.util/src/org/openide/util/RequestProcessor.java	Wed Jun 17 03:52:56 2009 +0400
     3.2 +++ b/openide.util/src/org/openide/util/RequestProcessor.java	Fri Jun 19 03:44:33 2009 +0400
     3.3 @@ -173,6 +173,8 @@
     3.4      
     3.5      /** support for interrupts or not? */
     3.6      private boolean interruptThread;
     3.7 +    /** fill stacktraces when task is posted? */
     3.8 +    private boolean enableStackTraces;
     3.9  
    3.10      /** Creates new RequestProcessor with automatically assigned unique name. */
    3.11      public RequestProcessor() {
    3.12 @@ -221,11 +223,34 @@
    3.13       * @since 6.3
    3.14       */
    3.15      public RequestProcessor(String name, int throughput, boolean interruptThread) {
    3.16 +        this(name, throughput, interruptThread, SLOW);
    3.17 +    }
    3.18 +
    3.19 +    /** Creates a new named <code>RequestProcessor</code> that allows to disable stack trace filling.
    3.20 +     * By default, when assertions are on, each task posted on <code>RequestProcessor</code> stores
    3.21 +     * the stack trace at the time of posting. When an exception is later thrown from the task,
    3.22 +     * it allows to print not only stack trace of the task but also stack trace of the code that posted it.
    3.23 +     * However this may be a performance bottleneck in cases when hundreds of short task are scheduled.
    3.24 +     * This constructor then allows to create <code>RequestProcessor</code> which never stores stack traces
    3.25 +     * at the time of posting.
    3.26 +     * <p>
    3.27 +     * See constructor {@link #RequestProcessor(String, int, boolean)} for details of <code>interruptThread</code>
    3.28 +     * parameter.
    3.29 +     * </p>
    3.30 +     * @param name the name to use for the request processor thread
    3.31 +     * @param throughput the maximal count of requests allowed to run in parallel
    3.32 +     * @param interruptThread true if {@link RequestProcessor.Task#cancel} shall interrupt the thread
    3.33 +     * @param enableStackTraces <code>false</code> when request processor should not fill stack traces when task is posted.
    3.34 +     *              Default is <code>true</code> when assertions are enabled, <code>false</code> otherwise.
    3.35 +     * @since 7.24
    3.36 +     */
    3.37 +    public RequestProcessor(String name, int throughput, boolean interruptThread, boolean enableStackTraces) {
    3.38          this.throughput = throughput;
    3.39          this.name = (name != null) ? name : ("OpenIDE-request-processor-" + (counter++));
    3.40          this.interruptThread = interruptThread;
    3.41 +        this.enableStackTraces = enableStackTraces;
    3.42      }
    3.43 -    
    3.44 +
    3.45      
    3.46      /** The getter for the shared instance of the <CODE>RequestProcessor</CODE>.
    3.47       * This instance is shared by anybody who
    3.48 @@ -627,7 +652,9 @@
    3.49                      item.clear(null);
    3.50                  }
    3.51  
    3.52 -                item = new Item(this, RequestProcessor.this);
    3.53 +                item = enableStackTraces ?
    3.54 +                    new SlowItem(this, RequestProcessor.this) :
    3.55 +                    new FastItem(this, RequestProcessor.this);
    3.56                  localItem = item;
    3.57              }
    3.58  
    3.59 @@ -813,8 +840,8 @@
    3.60      /* One item representing the task pending in the pending queue */
    3.61      private static class Item extends Exception {
    3.62          private final RequestProcessor owner;
    3.63 -        private Object action;
    3.64 -        private boolean enqueued;
    3.65 +        Object action;
    3.66 +        boolean enqueued;
    3.67          String message;
    3.68  
    3.69          Item(Task task, RequestProcessor rp) {
    3.70 @@ -849,33 +876,46 @@
    3.71              return getTask().getPriority();
    3.72          }
    3.73  
    3.74 -        @Override
    3.75 -        public Throwable fillInStackTrace() {
    3.76 -            if (SLOW) {
    3.77 -                Throwable ret = super.fillInStackTrace();
    3.78 -                StackTraceElement[] arr = ret.getStackTrace();
    3.79 -                for (int i = 1; i < arr.length; i++) {
    3.80 -                    if (arr[i].getClassName().startsWith("java.lang")) {
    3.81 -                        continue;
    3.82 -                    }
    3.83 -                    if (arr[i].getClassName().startsWith(RequestProcessor.class.getName())) {
    3.84 -                        continue;
    3.85 -                    }
    3.86 -                    ret.setStackTrace(Arrays.asList(arr).subList(i - 1, arr.length).toArray(new StackTraceElement[0]));
    3.87 -                    break;
    3.88 -                }
    3.89 -                return ret;
    3.90 -            } else {
    3.91 -                return this;
    3.92 -            }
    3.93 -        }
    3.94 -
    3.95          public @Override String getMessage() {
    3.96              return message;
    3.97          }
    3.98  
    3.99      }
   3.100  
   3.101 +    private static class FastItem extends Item {
   3.102 +        FastItem(Task task, RequestProcessor rp) {
   3.103 +            super(task, rp);
   3.104 +        }
   3.105 +
   3.106 +        @Override
   3.107 +        public Throwable fillInStackTrace() {
   3.108 +            return this;
   3.109 +        }
   3.110 +    }
   3.111 +    private static class SlowItem extends Item {
   3.112 +
   3.113 +        SlowItem(Task task, RequestProcessor rp) {
   3.114 +            super(task, rp);
   3.115 +        }
   3.116 +
   3.117 +        @Override
   3.118 +        public Throwable fillInStackTrace() {
   3.119 +            Throwable ret = super.fillInStackTrace();
   3.120 +            StackTraceElement[] arr = ret.getStackTrace();
   3.121 +            for (int i = 1; i < arr.length; i++) {
   3.122 +                if (arr[i].getClassName().startsWith("java.lang")) {
   3.123 +                    continue;
   3.124 +                }
   3.125 +                if (arr[i].getClassName().startsWith(RequestProcessor.class.getName())) {
   3.126 +                    continue;
   3.127 +                }
   3.128 +                ret.setStackTrace(Arrays.asList(arr).subList(i - 1, arr.length).toArray(new StackTraceElement[0]));
   3.129 +                break;
   3.130 +            }
   3.131 +            return ret;
   3.132 +        }
   3.133 +    }
   3.134 +
   3.135      //------------------------------------------------------------------------------
   3.136      // The Processor management implementation
   3.137      //------------------------------------------------------------------------------
     4.1 --- a/openide.util/test/unit/src/org/openide/util/RequestProcessorTest.java	Wed Jun 17 03:52:56 2009 +0400
     4.2 +++ b/openide.util/test/unit/src/org/openide/util/RequestProcessorTest.java	Fri Jun 19 03:44:33 2009 +0400
     4.3 @@ -45,6 +45,7 @@
     4.4  import java.util.logging.Handler;
     4.5  import java.util.logging.LogRecord;
     4.6  import java.util.logging.Level;
     4.7 +import java.util.logging.Logger;
     4.8  import junit.framework.Test;
     4.9  import org.openide.ErrorManager;
    4.10  import org.netbeans.junit.*;
    4.11 @@ -1346,7 +1347,80 @@
    4.12              x.notifyAll();
    4.13          }
    4.14      }
    4.15 -    
    4.16 +
    4.17 +    private static class TestHandler extends Handler {
    4.18 +        boolean stFilled = false;
    4.19 +        boolean exceptionCaught = false;
    4.20 +
    4.21 +        @Override
    4.22 +        public void publish(LogRecord rec) {
    4.23 +            if (rec.getThrown() != null) {
    4.24 +                for (StackTraceElement elem : rec.getThrown().getStackTrace()) {
    4.25 +                    if (elem.getMethodName().contains("testStackTraceFillingDisabled")) {
    4.26 +                        stFilled = true;
    4.27 +                        break;
    4.28 +                    }
    4.29 +                }
    4.30 +                exceptionCaught = true;
    4.31 +            }
    4.32 +        }
    4.33 +
    4.34 +        public void clear() {
    4.35 +            stFilled = false;
    4.36 +            exceptionCaught = false;
    4.37 +        }
    4.38 +
    4.39 +        @Override
    4.40 +        public void flush() {
    4.41 +        }
    4.42 +
    4.43 +        @Override
    4.44 +        public void close() throws SecurityException {
    4.45 +        }
    4.46 +    }
    4.47 +
    4.48 +    public void testStackTraceFillingDisabled() throws InterruptedException {
    4.49 +        boolean ea = false;
    4.50 +        assert (ea = true);
    4.51 +        assertTrue("Test must be run with enabled assertions", ea);
    4.52 +        Logger l = RequestProcessor.logger();
    4.53 +        TestHandler handler = new TestHandler();
    4.54 +        l.addHandler(handler);
    4.55 +        try {
    4.56 +            RequestProcessor rp = new RequestProcessor("test rp #1", 1);
    4.57 +            Task t = rp.post(new Runnable() {
    4.58 +
    4.59 +                public void run() {
    4.60 +                    throw new RuntimeException("Testing filled stacktrace");
    4.61 +                }
    4.62 +            });
    4.63 +//            t.waitFinished(); // does not work, thread gets notified before the exception is logged
    4.64 +            int timeout = 0;
    4.65 +            while (! handler.exceptionCaught && timeout++ < 100) {
    4.66 +                Thread.sleep(50);
    4.67 +            }
    4.68 +            assertTrue("Waiting for task timed out", timeout < 100);
    4.69 +            assertTrue("Our testing method not found in stack trace", handler.stFilled);
    4.70 +
    4.71 +            handler.clear();
    4.72 +            timeout = 0;
    4.73 +            rp = new RequestProcessor("test rp #2", 1, false, false);
    4.74 +            t = rp.post(new Runnable() {
    4.75 +
    4.76 +                public void run() {
    4.77 +                    throw new RuntimeException("Testing 'short' stacktrace");
    4.78 +                }
    4.79 +            });
    4.80 +            while (! handler.exceptionCaught && timeout++ < 100) {
    4.81 +                Thread.sleep(50);
    4.82 +            }
    4.83 +            assertTrue("Waiting for task timed out", timeout < 100);
    4.84 +            assertFalse("Our testing method found in stack trace", handler.stFilled);
    4.85 +        } finally {
    4.86 +            l.removeHandler(handler);
    4.87 +        }
    4.88 +    }
    4.89 +
    4.90      private static void doGc (int count, Reference toClear) {
    4.91          java.util.ArrayList<byte[]> l = new java.util.ArrayList<byte[]> (count);
    4.92          while (count-- > 0) {