Bug 122457 [Viewers] IllegalThreadStateException in BackgroundContentProvider
Since Eclipse 3.2M4 (it works unchanged with Eclipse 3.1.1), the DeferredContentProvider does not work as expected in my JFace dialog. Instead, an IllegalThreadStateException occures when a TableViewer's input is set in method "createDialogArea" of my "TitleAreaDialog" (see stack trace at the very end of this description). The source code that throws this exception is in method "makeDirty" in class BackgroundContentProvider. This method is called twice when the input of a TableViewer with a DeferredContentProvider changes (on "setLimit" and on "setFilter" in method "inputChanged"). "makeDirty" starts the sortThread - so when this method is called for the second time, the sortThread has already been started and maybe it has already terminated. In either case, makeDirty waits for the sortThread to die (sortThread.join()) before starting it. But according to the JDK API Specs, it is illegal to start a thread twice! This seems to cause the IllegalThreadStateException! (See code and exception below) So even if I made a mistake somewhere in my code, in my point of view, "makeDirty" is not correctly implemented. <code> private void makeDirty() { sortMon.cancel(); // make sure the sort thread is not running try { sortThread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } /* MW: Create a new Thread object here??? */ sortThread.start(); } </code> <exception> java.lang.IllegalThreadStateException at java.lang.Thread.start(Unknown Source) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider.makeDirty(BackgroundContentProvider.java:460) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider.setContents(BackgroundContentProvider.java:490) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider.access$2(BackgroundContentProvider.java:488) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider$1.setContents(BackgroundContentProvider.java:110) at com.dgr.profi.stamm.ui.dialogs.StammdatenSearchDialog$ListConcurrentModel.requestUpdate(StammdatenSearchDialog.java:50) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider.refresh(BackgroundContentProvider.java:174) at org.eclipse.jface.viewers.deferred.BackgroundContentProvider.setFilter(BackgroundContentProvider.java:406) at org.eclipse.jface.viewers.deferred.DeferredContentProvider.inputChanged(DeferredContentProvider.java:149) at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:245) at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1417) at com.dgr.profi.stamm.ui.dialogs.KundeSearchDialog.createResultArea(KundeSearchDialog.java:196) at com.dgr.profi.stamm.ui.dialogs.StammdatenSearchDialog.createContentArea(StammdatenSearchDialog.java:98) at com.dgr.profi.ui.dialogs.RunnableContextDialog.createDialogArea(RunnableContextDialog.java:138) at org.eclipse.jface.dialogs.TitleAreaDialog.createContents(TitleAreaDialog.java:157) at org.eclipse.jface.window.Window.create(Window.java:417) at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1051) at org.eclipse.jface.window.Window.open(Window.java:775) at com.dgr.profi.stamm.internal.ui.ShowKundenSearchDialog.run(ShowKundenSearchDialog.java:38) at org.eclipse.ui.internal.PluginAction.runWithEvent(PluginAction.java:251) ...more lines skipped... </exception>
bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/deferred/BackgroundContentProvider.java
/**
     * Sets the maximum table size. Based on the current sort order,
     * the table will be truncated if it grows beyond this size.
     * Using a limit improves memory usage and performance, and is
     * strongly recommended for large tables. 
     * 
     * @param limit maximum rows to show in the table or -1 if unbounded
     */
    public void setLimit(int limit) {
        this.limit = limit;
        refresh();
    }
    
    /**
     * Returns the maximum table size or -1 if unbounded
     * 
     * @return the maximum number of rows in the table or -1 if unbounded
     */
    public int getLimit() {
        return limit;
    }
    
    /**
     * Checks if currently visible range has changed, and triggers and update
     * and resort if necessary. Must be called in the UI thread, typically
     * within a SWT.SetData callback.
     * @param includeIndex the index that should be included in the visible range.
     */
    public void checkVisibleRange(int includeIndex) {