SF1603631:

concurrent modification of ROT (adding or removing thread tables) causes VM crash.  The simple fix is to sychronize all accessors to the ROT.  Performance impact has not been analyzed
This commit is contained in:
clay_shooter
2006-12-08 12:42:37 +00:00
parent 5ac71b76b4
commit 3b524074a6

View File

@@ -59,15 +59,16 @@ public abstract class ROT {
* adds a new thread storage area to rot * adds a new thread storage area to rot
* @return Map corresponding to the thread that this call was made in * @return Map corresponding to the thread that this call was made in
*/ */
protected static Map addThread() { protected synchronized static Map addThread() {
// should use the id here instead of the name because the name can be changed
String t_name = Thread.currentThread().getName(); String t_name = Thread.currentThread().getName();
if ( rot.containsKey( t_name ) ) { if ( rot.containsKey( t_name ) ) {
// nothing to do // nothing to do
} else { } else {
Map tab = null; Map tab = null;
if ( JacobObject.isDebugEnabled() ) { if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug("ROT: Automatic GC flag == "+ USE_AUTOMATIC_GARBAGE_COLLECTION JacobObject.debug( "ROT: Automatic GC flag == " + USE_AUTOMATIC_GARBAGE_COLLECTION );
);} }
if ( !USE_AUTOMATIC_GARBAGE_COLLECTION ) { if ( !USE_AUTOMATIC_GARBAGE_COLLECTION ) {
tab = new HashMap(); tab = new HashMap();
} else { } else {
@@ -78,14 +79,13 @@ public abstract class ROT {
return getThreadObjects( false ); return getThreadObjects( false );
} }
/** /**
* returns the pool for this thread if it exists. can create a new * returns the pool for this thread if it exists. can create a new
* one if you wish by passing in TRUE * one if you wish by passing in TRUE
* @param createIfDoesNotExist * @param createIfDoesNotExist
* @return Map the collection that holds the objects created in the current thread * @return Map the collection that holds the objects created in the current thread
*/ */
protected static Map getThreadObjects(boolean createIfDoesNotExist) { protected synchronized static Map getThreadObjects( boolean createIfDoesNotExist ) {
String t_name = Thread.currentThread().getName(); String t_name = Thread.currentThread().getName();
if ( !rot.containsKey( t_name ) && createIfDoesNotExist ) { if ( !rot.containsKey( t_name ) && createIfDoesNotExist ) {
addThread(); addThread();
@@ -102,7 +102,7 @@ public abstract class ROT {
* This is called by COMThread in the tear down and provides a * This is called by COMThread in the tear down and provides a
* synchronous way of releasing memory * synchronous way of releasing memory
*/ */
protected static void clearObjects() { protected synchronized static void clearObjects() {
Map tab = getThreadObjects( false ); Map tab = getThreadObjects( false );
if ( JacobObject.isDebugEnabled() ) { if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: " + rot.keySet().size() + " thread tables exist" ); JacobObject.debug( "ROT: " + rot.keySet().size() + " thread tables exist" );
@@ -147,7 +147,9 @@ public abstract class ROT {
JacobObject.debug( "ROT: thread table cleared and removed" ); JacobObject.debug( "ROT: thread table cleared and removed" );
} }
} else { } else {
if (JacobObject.isDebugEnabled()){ JacobObject.debug("ROT: nothing to clear!");} if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( "ROT: nothing to clear!" );
}
} }
} }
@@ -187,7 +189,7 @@ public abstract class ROT {
* This will remove an object from the ROT * This will remove an object from the ROT
* @param o * @param o
*/ */
protected static void removeObject(JacobObject o) { protected synchronized static void removeObject( JacobObject o ) {
String t_name = Thread.currentThread().getName(); String t_name = Thread.currentThread().getName();
Map tab = (Map) rot.get( t_name ); Map tab = (Map) rot.get( t_name );
if ( tab != null ) { if ( tab != null ) {
@@ -200,7 +202,7 @@ public abstract class ROT {
* adds an object to the HashMap for the current thread * adds an object to the HashMap for the current thread
* @param o * @param o
*/ */
protected static void addObject(JacobObject o) { protected synchronized static void addObject( JacobObject o ) {
Map tab = getThreadObjects( false ); Map tab = getThreadObjects( false );
if ( tab == null ) { if ( tab == null ) {
// this thread has not been initialized as a COM thread // this thread has not been initialized as a COM thread
@@ -211,7 +213,8 @@ public abstract class ROT {
if ( JacobObject.isDebugEnabled() ) { if ( JacobObject.isDebugEnabled() ) {
JacobObject.debug( JacobObject.debug(
"ROT: adding " + o + "->" + o.getClass().getName() + "ROT: adding " + o + "->" + o.getClass().getName() +
" table size prior to addition:" +tab.size());} " table size prior to addition:" + tab.size() );
}
if ( tab != null ) { if ( tab != null ) {
tab.put( getMapKey( tab, o ), getMapValue( tab, o ) ); tab.put( getMapKey( tab, o ), getMapValue( tab, o ) );
} }
@@ -226,3 +229,4 @@ public abstract class ROT {
} }
} }