Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 346576

Summary: Table loops forever in Table.setItemCount
Product: [RT] RAP Reporter: Andrei Neshcheret <a.nesheret>
Component: RWTAssignee: Project Inbox <rap-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P1 CC: a.nesheret
Version: 1.4   
Target Milestone: 1.4 RC2   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Code to reproduce bug.
none
Proposed patch rsternberg: review+

Description Andrei Neshcheret CLA 2011-05-20 00:54:31 EDT
Build Identifier: M20110210-1200, RAP runtime 1.4 M7

Infinite loop in this code:
---
  public void setItemCount( int count ) {
    checkWidget();
    int newItemCount = Math.max( 0, count );
    if( newItemCount != itemCount ) {
      while( newItemCount < itemCount ) {  // infinite loop here
        TableItem item = items[ newItemCount ];
        if( item != null && !item.isDisposed() ) {
          item.dispose();
        } else {
          destroyItem( null, newItemCount );
        }
      }
...
---
Table control is in dispose state and destroyItem method does not decrease 'itemCount' member.

My fix is:
---
  final void destroyItem( TableItem item, int index ) {
    if( !isInDispose() ) {
      ... // unchached code
    }
    else 
      itemCount--;
  }
---


Reproducible: Always

Steps to Reproduce:
1. Run Application
2. Press 'Close' button.
Comment 1 Andrei Neshcheret CLA 2011-05-20 00:57:08 EDT
Created attachment 196179 [details]
Code to reproduce bug.
Comment 2 Ivan Furnadjiev CLA 2011-05-20 03:14:38 EDT
I can reproduce it with your snippet too. What bugs me, is the call to setItemCount in the dispose event (inputChanged is called in the dispose event). Is this working in RCP?
Comment 3 Ivan Furnadjiev CLA 2011-05-20 03:35:41 EDT
Test case that loops forever. Works fin in SWT.
public void testSetItemCountInDisposeListener() {
    Fixture.fakePhase( PhaseId.PROCESS_ACTION );
    final Table table = new Table( shell, SWT.VIRTUAL );
    table.setItemCount( 10 );
    table.addDisposeListener( new DisposeListener() {
      public void widgetDisposed( DisposeEvent e ) {
        table.setItemCount( 0 );
      }
    } );
    table.dispose();
  }
Comment 4 Ivan Furnadjiev CLA 2011-05-20 05:01:19 EDT
We should check the same scenario on Tree.
Comment 5 Ivan Furnadjiev CLA 2011-05-22 04:28:47 EDT
Created attachment 196290 [details]
Proposed patch

The solution is to not execute the code at all in Table#setItemCount if table is in dispose.
Comment 6 Ivan Furnadjiev CLA 2011-05-22 04:30:56 EDT
I checked Tree/TreeItem too and they are not affected - Tree/TreeItem#setItemCount does not rely on "hidden" decrementation of itemCount field.
Comment 7 Ralf Sternberg CLA 2011-05-22 05:05:21 EDT
+1 for the patch.
I agree that not executing setItemCount makes most sense and is safe.

But I'd suggest that we include a comment with the bug number in the first added test. Since it contains no asserts, it has the potential of being deleted if its meaning is unclear.
Comment 8 Ivan Furnadjiev CLA 2011-05-22 05:20:44 EDT
Applied patch to CVS HEAD and v14_Maintenance branch with additional comment on the first test as suggested in comment #7.