-
Bug
-
Resolution: Won't Fix
-
P4
-
6u26
-
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.
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.