[ 
https://issues.apache.org/jira/browse/DIRMINA-452?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Trustin Lee updated DIRMINA-452:
--------------------------------

    Fix Version/s:     (was: 2.0.0-M1)
                   1.0.7

> IdentittyHashMap Iterator has bug in it.
> ----------------------------------------
>
>                 Key: DIRMINA-452
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-452
>             Project: MINA
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.1.0, 1.0.4, 1.1.1, 1.0.5, 
> 1.1.2
>         Environment: Java, all 1.5 and 1.6 versions at least.
>            Reporter: Rupert Smith
>             Fix For: 1.1.4, 1.0.7
>
>
> There is a bug in IdentityHashMap Iterator which causes an infinite loop. 
> This can manifest itself anywhere that the iterator.remove() method is 
> called, in conjunction with the put() method. In particular this has been 
> observed in the VmPipeIdleStatus checker.
> Certain sequences of puts/iterator.removes cause the map to allow put() to be 
> called with a full table. The code then loops round the table forever looking 
> for a free slot to add the new entry to.
> A bug report has been submitted to Sun for this problem.
> Suggested work arounds:
> Use HashMap instead of IdentityHashMap.
> Do not use the remove() method on the iterator, find all elements to remove 
> in one step, then remove in another.
> Here is some sample test code that exhibits the bug in isolation. Call it 
> repeatedly with n=1000, until it locks up:
>     public void testRandomPutRemove(final int n)
>     {
>         final Map<TestElement, TestElement> idMap = new 
> IdentityHashMap<TestElement, TestElement>();
>         final Random r = new Random();
>         final float removeProbability = r.nextFloat();
>         final float addProbability = r.nextFloat();
>         final Queue<String> opSequence = new LinkedList<String>();
>         Runnable tester =
>             new Runnable()
>             {
>                 public void run()
>                 {
>                     for (int i = 0; i < n; i++)
>                     {
>                         if (r.nextFloat() < addProbability)
>                         {
>                             synchronized (idMap)
>                             {
>                                 TestElement e = new TestElement();
>                                 idMap.put(e, e);
>                                 opSequence.offer("put");
>                             }
>                         }
>                         else
>                         {
>                             synchronized (idMap)
>                             {
>                                 Iterator it = idMap.keySet().iterator();
>                                 for (int j = 0; it.hasNext(); j++)
>                                 {
>                                     it.next();
>                                     if (r.nextFloat() < removeProbability)
>                                     {
>                                         it.remove();
>                                         opSequence.offer("remove " + j);
>                                     }
>                                 }
>                             }
>                         }
>                     }
>                 }
>             };
>         Thread testThread = new Thread(tester);
>         testThread.start();
>         try
>         {
>             testThread.join(5000);
>         }
>         catch (InterruptedException e)
>         {
>             fail("Test interrupted.");
>         }
>         if (testThread.getState() == Thread.State.RUNNABLE)
>         {
>             System.out.println("opSequence = " + opSequence);
>             System.out.println("removeProbability = " + removeProbability);
>             System.out.println("addProbability = " + addProbability);
>             // Wait forever here, to give an opportunity to take thread/heap 
> dumps etc.
>             try
>             {
>                 testThread.join();
>             }
>             catch (InterruptedException e)
>             {
>                 // Ignore.
>             }
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to