Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7061525

A thread synchronization issue in com.sun.corba.se.impl.transport.SelectorImpl

    • x86
    • windows_7

      FULL PRODUCT VERSION :
      java version "1.6.0_26"
      Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
      Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      The system has 8 cores (twin quad core processors).

      A DESCRIPTION OF THE PROBLEM :
      I intermittently get the following exception:-

      com.sun.corba.se.impl.transport.SelectorImpl.startSelector(Unknown Source),
      com.sun.corba.se.impl.transport.SelectorImpl.registerForEvent(Unknown Source),
      com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source),
      com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source),
      org.omg.CORBA.portable.ObjectImpl._request(Unknown Source),
      org.omg.CosTransactions._ResourceStub.prepare(_ResourceStub.java:149),
      com.coda.common.app.transaction.ots.CodaRootCoordinator$PreparingState.enter(CodaRootCoordinator.java:356),
      com.coda.common.app.transaction.ots.CodaRootCoordinator$ActiveState.commit(CodaRootCoordinator.java:50),
      com.coda.common.app.transaction.ots.CodaRootCoordinator.commit(CodaRootCoordinator.java:625),
      com.coda.common.app.transaction.ots.CodaTerminator.commit(CodaTerminator.java:34),
      com.coda.common.app.transaction.ots.CodaCurrent.commit(CodaCurrent.java:84),
      com.coda.common.app.transaction.AppTransactionsImpl.commit(AppTransactionsImpl.java:124),
      com.coda.common.core.transaction.Transactions.commit(Transactions.java:109),
      com.coda.common.core.transaction.TransactionScope$NewStrategy.dispose(TransactionScope.java:276),
      com.coda.common.core.transaction.TransactionScope.dispose(TransactionScope.java:182),
      com.coda.pim.app.matching.background.BackgroundMatchingEngine$GroupProcess.run(BackgroundMatchingEngine.java:180),
      com.coda.common.app.server.ThreadInitialiser$InitialiserHelper.run(ThreadInitialiser.java:99),
      java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source),
      java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source),
      java.lang.Thread.run(Unknown Source)

      This seems to be caused by several (~16) worker threads sharing an ORB and hence sharing the same SelectorImpl. SelectorImpt is a thread and the registerForEvent() method checks to see if it has been started before calling startSelector(); e.g.

      if (! selectorStarted) {
      startSelector();
      }

      Inside startSelector() the thread is started and the selectorStarted boolean is set; e.g.

      setDaemon(true);
      start();
      selectorStarted = true;

      There is no synchronization round this code and hence there is a window during which two threads can get inside the "if" at the same time and the second thread will fail on setDaemon(true) because the thread has already started.
      This is a small window of opportunity but our 8 core server machine is running a pool or worker threads and manages to hit it quite often.
      I'm guessing the fix would be something like:-
       Move the "if" into startSelector() and synchronize the method; e.g.

      private synchronized void startSelector()
      {
      if (selectorStarted)
      return;
      ...
      setDaemon(true);
      start();
      selectorStarted = true;
      ...
      }


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Any method which calls startSelector() on the same SelectorImpl from several threads at the same time. In this case committing distributed transactions from a pool of worker threads.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I was expecting to commit a distributed transaction.
      ACTUAL -
      A HeuristicHazard exception caused by an IllegalThreadStateException.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.Thread.setDaemon(Unknown Source),
      com.sun.corba.se.impl.transport.SelectorImpl.startSelector(Unknown Source),
      com.sun.corba.se.impl.transport.SelectorImpl.registerForEvent(Unknown Source),
      com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source),
      com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source),
      org.omg.CORBA.portable.ObjectImpl._request(Unknown Source),
      org.omg.CosTransactions._ResourceStub.prepare(_ResourceStub.java:149),
      com.coda.common.app.transaction.ots.CodaRootCoordinator$PreparingState.enter(CodaRootCoordinator.java:356),
      com.coda.common.app.transaction.ots.CodaRootCoordinator$ActiveState.commit(CodaRootCoordinator.java:50),
      com.coda.common.app.transaction.ots.CodaRootCoordinator.commit(CodaRootCoordinator.java:625),
      com.coda.common.app.transaction.ots.CodaTerminator.commit(CodaTerminator.java:34),
      com.coda.common.app.transaction.ots.CodaCurrent.commit(CodaCurrent.java:84),
      com.coda.common.app.transaction.AppTransactionsImpl.commit(AppTransactionsImpl.java:124),
      com.coda.common.core.transaction.Transactions.commit(Transactions.java:109),
      com.coda.common.core.transaction.TransactionScope$NewStrategy.dispose(TransactionScope.java:276),
      com.coda.common.core.transaction.TransactionScope.dispose(TransactionScope.java:182),
      com.coda.pim.app.matching.background.BackgroundMatchingEngine$GroupProcess.run(BackgroundMatchingEngine.java:180),
      com.coda.common.app.server.ThreadInitialiser$InitialiserHelper.run(ThreadInitialiser.java:99),
      java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source),
      java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source),
      java.lang.Thread.run(Unknown Source)


      REPRODUCIBILITY :
      This bug can be reproduced occasionally.

      ---------- BEGIN SOURCE ----------
      I don't have a standalone test case.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I think I have a temporary workaround - synchronising the commit code of the worker threads (though this is a much larger synchronization block than I would like). There is still a risk that other threads may interact with the worker threads.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: