[infinispan-commits] Infinispan SVN: r2555 - in trunk: cachestore/cassandra/src/main/java/org/infinispan/loaders/cassandra and 15 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Thu Oct 21 11:21:40 EDT 2010


Author: galder.zamarreno at jboss.com
Date: 2010-10-21 11:21:39 -0400 (Thu, 21 Oct 2010)
New Revision: 2555

Modified:
   trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/InternalCacheEntryBinding.java
   trunk/cachestore/cassandra/src/main/java/org/infinispan/loaders/cassandra/CassandraCacheStore.java
   trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
   trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java
   trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/JdbcUtil.java
   trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java
   trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
   trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java
   trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmSerializer.java
   trunk/client/hotrod-client/src/main/java/org/infinispan/client/hotrod/impl/RemoteCacheImpl.java
   trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java
   trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java
   trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
   trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
   trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java
   trunk/core/src/main/java/org/infinispan/marshall/AbstractMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/StreamingMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
   trunk/core/src/main/java/org/infinispan/util/Util.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/locks/StripedLock.java
Log:
ISPN-699 - NullPointerException when unmarshalling after eviction thread has been cancelled - Merged changes from 4.2.x (rev 2554)

Modified: trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/InternalCacheEntryBinding.java
===================================================================
--- trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/InternalCacheEntryBinding.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/bdbje/src/main/java/org/infinispan/loaders/bdbje/InternalCacheEntryBinding.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -31,6 +31,9 @@
          b = m.objectToByteBuffer(object);
       } catch (IOException e) {
          throw new RuntimeExceptionWrapper(e);
+      } catch (InterruptedException ie) {
+         Thread.currentThread().interrupt();
+         throw new RuntimeExceptionWrapper(ie);
       }
       entry.setData(b);
    }

Modified: trunk/cachestore/cassandra/src/main/java/org/infinispan/loaders/cassandra/CassandraCacheStore.java
===================================================================
--- trunk/cachestore/cassandra/src/main/java/org/infinispan/loaders/cassandra/CassandraCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/cassandra/src/main/java/org/infinispan/loaders/cassandra/CassandraCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -293,7 +293,7 @@
 		addMutation(mutationMap, key, config.entryColumnFamily, null, null);
 	}
 
-	private byte[] marshall(InternalCacheEntry entry) throws IOException {
+	private byte[] marshall(InternalCacheEntry entry) throws IOException, InterruptedException {
 		return getMarshaller().objectToByteBuffer(entry.toInternalCacheValue());
 	}
 
@@ -326,10 +326,15 @@
 		if (trace)
 			log.trace("store(\"{0}\") ", key);
 		String cassandraKey = CassandraCacheStore.hashKey(key);
-		addMutation(mutationMap, cassandraKey, config.entryColumnFamily, entryColumnPath.getColumn(), marshall(entry));
-		if (entry.canExpire()) {
-			addExpiryEntry(cassandraKey, entry.getExpiryTime(), mutationMap);
-		}
+      try {
+         addMutation(mutationMap, cassandraKey, config.entryColumnFamily, entryColumnPath.getColumn(), marshall(entry));
+         if (entry.canExpire()) {
+            addExpiryEntry(cassandraKey, entry.getExpiryTime(), mutationMap);
+         }
+      } catch (InterruptedException ie) {
+         if (trace) log.trace("Interrupted while trying to marshall entry");
+         Thread.currentThread().interrupt();
+      }
 	}
 	
 	private void addExpiryEntry(String cassandraKey, long expiryTime, Map<String, Map<String, List<Mutation>>> mutationMap) {		
@@ -376,7 +381,10 @@
 			throw new CacheLoaderException(e);
 		} catch (ClassNotFoundException e) {
 			throw new CacheLoaderException(e);
-		}
+		} catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while reading from stream");
+         Thread.currentThread().interrupt();
+      }
 	}
 
 	/**

Modified: trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java
===================================================================
--- trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/cloud/src/main/java/org/infinispan/loaders/cloud/CloudCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -361,9 +361,11 @@
                   .valueOf(earliestExpiryTime));
             blob.getMetadata().setUserMetadata(md);
          }
-
       } catch (IOException e) {
          throw new CacheLoaderException(e);
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while writing blob");
+         Thread.currentThread().interrupt();
       }
    }
 

Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/DataManipulationHelper.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -115,6 +115,9 @@
          logAndThrow(e, "SQL failure while integrating state into store");
       } catch (ClassNotFoundException e) {
          logAndThrow(e, "Unexpected failure while integrating state into store");
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while reading from stream"); 
+         Thread.currentThread().interrupt();
       } finally {
          JdbcUtil.safeClose(ps);
          connectionFactory.releaseConnection(conn);
@@ -264,7 +267,8 @@
 
    protected abstract void toStreamProcess(ResultSet rs, InputStream is, ObjectOutput objectOutput) throws CacheLoaderException, SQLException, IOException;
 
-   protected abstract boolean fromStreamProcess(Object objFromStream, PreparedStatement ps, ObjectInput objectInput) throws SQLException, CacheLoaderException, IOException, ClassNotFoundException;
+   protected abstract boolean fromStreamProcess(Object objFromStream, PreparedStatement ps, ObjectInput objectInput)
+         throws SQLException, CacheLoaderException, IOException, ClassNotFoundException, InterruptedException;
 
    public static void logAndThrow(Exception e, String message) throws CacheLoaderException {
       log.error(message, e);

Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/JdbcUtil.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/JdbcUtil.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/JdbcUtil.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -73,7 +73,7 @@
       }
    }
 
-   public static ByteBuffer marshall(StreamingMarshaller marshaller, Object bucket) throws CacheLoaderException {
+   public static ByteBuffer marshall(StreamingMarshaller marshaller, Object bucket) throws CacheLoaderException, InterruptedException {
       try {
          return marshaller.objectToBuffer(bucket);
       } catch (IOException e) {

Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/binary/JdbcBinaryCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -127,7 +127,8 @@
             marshaller.objectToObjectStream(bucket, objectOutput);
          }
 
-         public boolean fromStreamProcess(Object bucketName, PreparedStatement ps, ObjectInput objectInput) throws SQLException, CacheLoaderException, IOException, ClassNotFoundException {
+         public boolean fromStreamProcess(Object bucketName, PreparedStatement ps, ObjectInput objectInput)
+               throws SQLException, CacheLoaderException, IOException, ClassNotFoundException, InterruptedException {
             if (bucketName instanceof String) {
                Bucket bucket = (Bucket) marshaller.objectFromObjectStream(objectInput);
                ByteBuffer buffer = JdbcUtil.marshall(getMarshaller(), bucket);
@@ -169,6 +170,9 @@
          }
       } catch (SQLException ex) {
          logAndThrow(ex, "sql failure while inserting bucket: " + bucket);
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while marshalling to insert a bucket");
+         Thread.currentThread().interrupt();
       } finally {
          JdbcUtil.safeClose(ps);
          connectionFactory.releaseConnection(conn);
@@ -195,6 +199,9 @@
          }
       } catch (SQLException e) {
          logAndThrow(e, "sql failure while updating bucket: " + bucket);
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while marshalling to update a bucket");
+         Thread.currentThread().interrupt();
       } finally {
          JdbcUtil.safeClose(ps);
          connectionFactory.releaseConnection(conn);
@@ -342,6 +349,9 @@
          releaseLocks(emptyBuckets);
          connectionFactory.releaseConnection(conn);
          logAndThrow(ex, "Failed clearing JdbcBinaryCacheStore");
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while marshalling to purge expired entries");
+         Thread.currentThread().interrupt();
       } finally {
          //release locks for the updated buckets.This won't include empty buckets, as these were migrated to emptyBuckets
          releaseLocks(expiredBuckets);

Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -150,7 +150,7 @@
             marshaller.objectToObjectStream(icv.toInternalCacheEntry(key), objectOutput);
          }
 
-         public boolean fromStreamProcess(Object objFromStream, PreparedStatement ps, ObjectInput objectInput) throws SQLException, CacheLoaderException {
+         public boolean fromStreamProcess(Object objFromStream, PreparedStatement ps, ObjectInput objectInput) throws SQLException, CacheLoaderException, InterruptedException {
             if (objFromStream instanceof InternalCacheEntry) {
                InternalCacheEntry se = (InternalCacheEntry) objFromStream;
                ByteBuffer buffer = JdbcUtil.marshall(getMarshaller(), se.toInternalCacheValue());
@@ -195,8 +195,9 @@
          log.trace("Running sql '" + sql + "' on " + ed + ". Key string is '" + lockingKey + "'");
       Connection connection = null;
       PreparedStatement ps = null;
-      ByteBuffer byteBuffer = JdbcUtil.marshall(getMarshaller(), ed.toInternalCacheValue());
+      ByteBuffer byteBuffer = null;
       try {
+         byteBuffer = JdbcUtil.marshall(getMarshaller(), ed.toInternalCacheValue());
          connection = connectionFactory.getConnection();
          ps = connection.prepareStatement(sql);
          ps.setBinaryStream(1, byteBuffer.getStream(), byteBuffer.getLength());
@@ -204,7 +205,10 @@
          ps.setString(3, lockingKey);
          ps.executeUpdate();
       } catch (SQLException ex) {
-         logAndThrow(ex, "Error while storing string key to database; key: '"+lockingKey+"', buffer size of value: " + byteBuffer.getLength() + " bytes");
+         logAndThrow(ex, "Error while storing string key to database; key: '" + lockingKey + "', buffer size of value: " + byteBuffer.getLength() + " bytes");
+      } catch (InterruptedException e) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while marshalling to store");
+         Thread.currentThread().interrupt();
       } finally {
          JdbcUtil.safeClose(ps);
          connectionFactory.releaseConnection(connection);

Modified: trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java
===================================================================
--- trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -269,7 +269,7 @@
       commit();
    }
 
-   private byte[] marshall(InternalCacheEntry entry) throws IOException {
+   private byte[] marshall(InternalCacheEntry entry) throws IOException, InterruptedException {
       return getMarshaller().objectToByteBuffer(entry.toInternalCacheValue());
    }
 
@@ -291,6 +291,9 @@
             addNewExpiry(entry);
       } catch (IOException e) {
          throw new CacheLoaderException(e);
+      } catch (InterruptedException ie) {
+         if (trace) log.trace("Interrupted while marshalling entry");
+         Thread.currentThread().interrupt();
       }
    }
 
@@ -350,6 +353,9 @@
          throw new CacheLoaderException(e);
       } catch (ClassNotFoundException e) {
          throw new CacheLoaderException(e);
+      } catch (InterruptedException ie) {
+         if (log.isTraceEnabled()) log.trace("Interrupted while reading from stream"); 
+         Thread.currentThread().interrupt();
       }
    }
 

Modified: trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmSerializer.java
===================================================================
--- trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmSerializer.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/cachestore/jdbm/src/main/java/org/infinispan/loaders/jdbm/JdbmSerializer.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -5,6 +5,8 @@
 import org.infinispan.marshall.StreamingMarshaller;
 
 import jdbm.helper.Serializer;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
 
 /**
  * Uses the configured (runtime) {@link org.infinispan.marshall.StreamingMarshaller} of the cache.
@@ -14,6 +16,7 @@
  */
 @SuppressWarnings("serial")
 public class JdbmSerializer implements Serializer {
+    private static final Log log = LogFactory.getLog(JdbmSerializer.class);
     
     private transient StreamingMarshaller marshaller;
 
@@ -35,7 +38,13 @@
     }
 
     public byte[] serialize(Object obj) throws IOException {
-        return marshaller.objectToByteBuffer(obj);
+       try {
+          return marshaller.objectToByteBuffer(obj);
+       } catch (InterruptedException e) {
+          if (log.isTraceEnabled()) log.trace("Interrupted while serializing object"); 
+          Thread.currentThread().interrupt();
+          throw new IOException(e);
+       }
     }
 
 }

Modified: trunk/client/hotrod-client/src/main/java/org/infinispan/client/hotrod/impl/RemoteCacheImpl.java
===================================================================
--- trunk/client/hotrod-client/src/main/java/org/infinispan/client/hotrod/impl/RemoteCacheImpl.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/client/hotrod-client/src/main/java/org/infinispan/client/hotrod/impl/RemoteCacheImpl.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -358,6 +358,9 @@
          return marshaller.objectToByteBuffer(o, isKey ? estimateKeySize : estimateValueSize);
       } catch (IOException ioe) {
          throw new TransportException("Unable to marshall object of type [" + o.getClass().getName() + "]", ioe);
+      } catch (InterruptedException ie) {
+         Thread.currentThread().interrupt();
+         return null;
       }
    }
 

Modified: trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java
===================================================================
--- trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -74,7 +74,7 @@
       hotrodServer.stop();
    }
 
-   public void testPut() throws IOException {
+   public void testPut() throws Exception {
       assert null == remoteCache.put("aKey", "aValue");
       assertCacheContains(cache, "aKey", "aValue");
       assert null == defaultRemote.put("otherKey", "otherValue");
@@ -85,7 +85,7 @@
       assert defaultRemote.get("otherKey").equals("otherValue");
    }
 
-   public void testRemove() throws IOException {
+   public void testRemove() throws Exception {
       assert null == remoteCache.put("aKey", "aValue");
       assertCacheContains(cache, "aKey", "aValue");
 
@@ -187,7 +187,7 @@
       assert cache.isEmpty();
    }
 
-   private void assertCacheContains(Cache cache, String key, String value) throws IOException {
+   private void assertCacheContains(Cache cache, String key, String value) throws Exception {
       Marshaller marshaller = new JBossMarshaller();
       byte[] keyBytes = marshaller.objectToByteBuffer(key, 64);
       byte[] valueBytes = marshaller.objectToByteBuffer(value, 64);

Modified: trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java
===================================================================
--- trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -42,7 +42,7 @@
       BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1), cache(2));
    }
 
-   public void testGet() throws ClassNotFoundException, IOException {
+   public void testGet() throws Exception {
       log.info("Starting actual test");
       Object key = generateKeyAndShutdownServer();
       //now make sure that next call won't fail
@@ -50,60 +50,60 @@
       assertEquals(remoteCache.get(key), "v");
    }
 
-   public void testPut() throws ClassNotFoundException, IOException {
+   public void testPut() throws Exception {
       Object key = generateKeyAndShutdownServer();
       log.info("Here it starts");
       assertEquals(remoteCache.put(key, "v0"), "v");
    }
 
-   public void testRemove() throws ClassNotFoundException, IOException {
+   public void testRemove() throws Exception {
       Object key = generateKeyAndShutdownServer();
       assertEquals("v", remoteCache.remove(key));
    }
 
-   public void testContains() throws ClassNotFoundException, IOException {
+   public void testContains() throws Exception {
       Object key = generateKeyAndShutdownServer();
       resetStats();
       assertEquals(true, remoteCache.containsKey(key));
    }
 
-   public void testGetWithVersion() throws ClassNotFoundException, IOException {
+   public void testGetWithVersion() throws Exception {
       Object key = generateKeyAndShutdownServer();
       resetStats();
       VersionedValue value = remoteCache.getVersioned(key);
       assertEquals("v", value.getValue());
    }
 
-   public void testPutIfAbsent() throws ClassNotFoundException, IOException {
+   public void testPutIfAbsent() throws Exception {
       Object key = generateKeyAndShutdownServer();
       assertEquals(null, remoteCache.putIfAbsent("noSuchKey", "someValue"));
       assertEquals("someValue", remoteCache.get("noSuchKey"));
    }
 
-   public void testReplace() throws ClassNotFoundException, IOException {
+   public void testReplace() throws Exception {
       Object key = generateKeyAndShutdownServer();
       assertEquals("v", remoteCache.replace(key, "v2"));
    }
 
-   public void testReplaceIfUnmodified() throws ClassNotFoundException, IOException {
+   public void testReplaceIfUnmodified() throws Exception {
       Object key = generateKeyAndShutdownServer();
       assertEquals(false, remoteCache.replaceWithVersion(key, "v2", 12));
    }
 
-   public void testRemoveIfUnmodified() throws ClassNotFoundException, IOException {
+   public void testRemoveIfUnmodified() throws Exception {
       Object key = generateKeyAndShutdownServer();
       resetStats();
       assertEquals(false, remoteCache.removeWithVersion(key, 12));
    }
 
-   public void testClear() throws ClassNotFoundException, IOException {
+   public void testClear() throws Exception {
       Object key = generateKeyAndShutdownServer();
       resetStats();
       remoteCache.clear();
       assertEquals(false, remoteCache.containsKey(key));
    }
 
-   private Object generateKeyAndShutdownServer() throws IOException, ClassNotFoundException {
+   private Object generateKeyAndShutdownServer() throws IOException, ClassNotFoundException, InterruptedException {
       resetStats();
       Cache<Object,Object> cache = manager(1).getCache();
       KeyAffinityService kaf = KeyAffinityServiceFactory.newKeyAffinityService(cache, Executors.newSingleThreadExecutor(), new ByteKeyGenerator(), 2, true);
@@ -142,6 +142,8 @@
             return sm.objectToByteBuffer(result, 64);
          } catch (IOException e) {
             throw new RuntimeException(e);
+         } catch (InterruptedException e) {
+            throw new RuntimeException(e);
          }
       }
 

Modified: trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/eviction/EvictionManagerImpl.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -45,10 +45,7 @@
    private LockManager lockManager;
    private PassivationManager passivator;
    private InvocationContextContainer ctxContainer;
-
-
    private boolean enabled;
-   volatile CountDownLatch startLatch = new CountDownLatch(1);
 
    @Inject
    public void initialize(@ComponentName(KnownComponentNames.EVICTION_SCHEDULED_EXECUTOR) ScheduledExecutorService executor,
@@ -82,48 +79,41 @@
                                                            configuration.getEvictionWakeUpInterval(), TimeUnit.MILLISECONDS);
          }
       }
-      startLatch.countDown();
    }
 
    public void processEviction() {
-      try {
-         startLatch.await();
-      } catch (InterruptedException e) {
-         Thread.currentThread().interrupt();
-      }
-
-      if (!enabled) {
-         return;
-      }
-
       long start = 0;
-      try {
-         if (trace) {
-            log.trace("Purging data container of expired entries");
-            start = System.currentTimeMillis();
-         }
-         dataContainer.purgeExpired();
-         if (trace) {
-            log.trace("Purging data container completed in {0}", Util.prettyPrintTime(System.currentTimeMillis() - start));
-         }
-      } catch (Exception e) {
-         log.warn("Caught exception purging data container!", e);
-      }
-
-      if (cacheStore != null) {
+      if (!Thread.currentThread().isInterrupted()) {
          try {
             if (trace) {
-               log.trace("Purging cache store of expired entries");
+               log.trace("Purging data container of expired entries");
                start = System.currentTimeMillis();
             }
-            cacheStore.purgeExpired();
+            dataContainer.purgeExpired();
             if (trace) {
-               log.trace("Purging cache store completed in {0}", Util.prettyPrintTime(System.currentTimeMillis() - start));
+               log.trace("Purging data container completed in {0}", Util.prettyPrintTime(System.currentTimeMillis() - start));
             }
          } catch (Exception e) {
-            log.warn("Caught exception purging cache store!", e);
+            log.warn("Caught exception purging data container!", e);
          }
       }
+
+      if (!Thread.currentThread().isInterrupted()) {
+         if (cacheStore != null) {
+            try {
+               if (trace) {
+                  log.trace("Purging cache store of expired entries");
+                  start = System.currentTimeMillis();
+               }
+               cacheStore.purgeExpired();
+               if (trace) {
+                  log.trace("Purging cache store completed in {0}", Util.prettyPrintTime(System.currentTimeMillis() - start));
+               }
+            } catch (Exception e) {
+               log.warn("Caught exception purging cache store!", e);
+            }
+         }
+      }
    }
 
    public boolean isEnabled() {
@@ -132,10 +122,8 @@
 
    @Stop(priority = 5)
    public void stop() {
-      startLatch = new CountDownLatch(1);
-      if (evictionTask != null) {
+      if (evictionTask != null)
          evictionTask.cancel(true);
-      }
    }
 
    class ScheduledTask implements Runnable {

Modified: trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/loaders/LockSupportCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -82,8 +82,8 @@
    /**
     * Based on the supplied param, acquires a global read(false) or write (true) lock.
     */
-   protected final void acquireGlobalLock(boolean exclusive) throws CacheLoaderException {
-      locks.aquireGlobalLock(exclusive, globalLockTimeoutMillis);
+   protected final boolean acquireGlobalLock(boolean exclusive) throws CacheLoaderException {
+      return locks.aquireGlobalLock(exclusive, globalLockTimeoutMillis);
    }
 
    /**

Modified: trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/loaders/file/FileCacheStore.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -47,9 +47,14 @@
    }
    
    protected void loopOverBuckets(BucketHandler handler) throws CacheLoaderException {
-      for (File bucketFile : root.listFiles()) {
-         Bucket bucket = loadBucket(bucketFile);
-         if (handler.handle(bucket)) break;
+      try {
+         for (File bucketFile : root.listFiles()) {
+            Bucket bucket = loadBucket(bucketFile);
+            if (handler.handle(bucket)) break;
+         }
+      } catch (InterruptedException ie) {
+         if (log.isDebugEnabled()) log.debug("Interrupted, so stop looping over buckets.");
+         Thread.currentThread().interrupt();
       }
    }
 
@@ -140,38 +145,52 @@
 
    protected void purgeInternal() throws CacheLoaderException {
       if (trace) log.trace("purgeInternal()");
-      acquireGlobalLock(false);
-      try {
-         for (final File bucketFile : root.listFiles()) {
-            if (multiThreadedPurge) {
-               purgerService.execute(new Runnable() {
-                  @Override
-                  public void run() {
-                     Bucket bucket;
-                     try {
-                        if ((bucket = loadBucket(bucketFile)) != null && bucket.removeExpiredEntries())
-                           updateBucket(bucket);
-                     } catch (CacheLoaderException e) {
-                        log.warn("Problems purging file " + bucketFile, e);
+      if (acquireGlobalLock(false)) {
+         try {
+            for (final File bucketFile : root.listFiles()) {
+               if (multiThreadedPurge) {
+                  purgerService.execute(new Runnable() {
+                     @Override
+                     public void run() {
+                        Bucket bucket;
+                        try {
+                           if ((bucket = loadBucket(bucketFile)) != null && bucket.removeExpiredEntries())
+                              updateBucket(bucket);
+                        } catch (InterruptedException ie) {
+                           if (log.isDebugEnabled()) log.debug("Interrupted, so finish work.");
+                        } catch (CacheLoaderException e) {
+                           log.warn("Problems purging file " + bucketFile, e);
+                        }
                      }
-                  }
-               });
-            } else {
-               Bucket bucket;
-               if ((bucket = loadBucket(bucketFile)) != null && bucket.removeExpiredEntries()) updateBucket(bucket);
+                  });
+               } else {
+                  Bucket bucket;
+                  if ((bucket = loadBucket(bucketFile)) != null && bucket.removeExpiredEntries()) updateBucket(bucket);
+               }
             }
+         } catch (InterruptedException ie) {
+            if (log.isDebugEnabled()) log.debug("Interrupted, so stop loading and finish with purging.");
+            Thread.currentThread().interrupt();
+         } finally {
+            releaseGlobalLock(false);
+            if (trace) log.trace("Exit purgeInternal()");
          }
-      } finally {
-         releaseGlobalLock(false);
-         if (trace) log.trace("Exit purgeInternal()");
+      } else {
+         log.warn("Unable to acquire global lock to purge cache store");
       }
    }
 
    protected Bucket loadBucket(String bucketName) throws CacheLoaderException {
-      return loadBucket(new File(root, bucketName));
+      try {
+         return loadBucket(new File(root, bucketName));
+      } catch (InterruptedException ie) {
+         if (log.isDebugEnabled()) log.debug("Interrupted, so stop loading bucket and return null.");
+         Thread.currentThread().interrupt();
+         return null;
+      }
    }
 
-   protected Bucket loadBucket(File bucketFile) throws CacheLoaderException {
+   protected Bucket loadBucket(File bucketFile) throws CacheLoaderException, InterruptedException {
       Bucket bucket = null;
       if (bucketFile.exists()) {
          if (log.isTraceEnabled()) log.trace("Found bucket file: '" + bucketFile + "'");
@@ -179,6 +198,8 @@
          try {
             is = new FileInputStream(bucketFile);
             bucket = (Bucket) objectFromInputStreamInReentrantMode(is);
+         } catch (InterruptedException ie) {
+            throw ie;
          } catch (Exception e) {
             String message = "Error while reading from file: " + bucketFile.getAbsoluteFile();
             log.error(message, e);
@@ -211,6 +232,9 @@
          } catch (IOException ex) {
             log.error("Exception while saving bucket " + b, ex);
             throw new CacheLoaderException(ex);
+         } catch (InterruptedException ie) {
+            if (trace) log.trace("Interrupted while marshalling a bucket");
+            Thread.currentThread().interrupt(); // Restore interrupted status
          }
          finally {
             safeClose(fos);
@@ -249,7 +273,7 @@
       return f.delete();
    }
 
-   private Object objectFromInputStreamInReentrantMode(InputStream is) throws IOException, ClassNotFoundException {
+   private Object objectFromInputStreamInReentrantMode(InputStream is) throws IOException, ClassNotFoundException, InterruptedException {
       int len = is.available();
       ExposedByteArrayOutputStream bytes = new ExposedByteArrayOutputStream(len);
       byte[] buf = new byte[Math.min(len, 1024)];

Modified: trunk/core/src/main/java/org/infinispan/marshall/AbstractMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/AbstractMarshaller.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/marshall/AbstractMarshaller.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -24,20 +24,20 @@
     * @return a ByteBuffer
     * @throws Exception
     */
-   protected abstract ByteBuffer objectToBuffer(Object o, int estimatedSize) throws IOException;
+   protected abstract ByteBuffer objectToBuffer(Object o, int estimatedSize) throws IOException, InterruptedException;
 
    @Override
-   public ByteBuffer objectToBuffer(Object obj) throws IOException {
+   public ByteBuffer objectToBuffer(Object obj) throws IOException, InterruptedException {
       return objectToBuffer(obj, DEFAULT_BUF_SIZE);
    }
 
    @Override
-   public byte[] objectToByteBuffer(Object o) throws IOException {
+   public byte[] objectToByteBuffer(Object o) throws IOException, InterruptedException {
       return objectToByteBuffer(o, DEFAULT_BUF_SIZE);
    }
 
    @Override
-   public byte[] objectToByteBuffer(Object obj, int estimatedSize) throws IOException {
+   public byte[] objectToByteBuffer(Object obj, int estimatedSize) throws IOException, InterruptedException {
       ByteBuffer b = objectToBuffer(obj, estimatedSize);
       byte[] bytes = new byte[b.getLength()];
       System.arraycopy(b.getBuf(), b.getOffset(), bytes, 0, b.getLength());

Modified: trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/marshall/Marshaller.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -32,27 +32,31 @@
     *
     * @param obj           object to convert to a byte array.  Must not be null.
     * @param estimatedSize an estimate of how large the resulting byte array may be
-    * @return a byte array
-    * @throws IOException
+    * @return a byte array with the marshalled form of the object
+    * @throws IOException if marshalling cannot complete due to some I/O error
+    * @throws InterruptedException if the marshalling was interrupted. Clients should take this as a sign that
+    * the marshaller is no longer available, maybe due to shutdown, and so no more unmarshalling should be attempted.
     */
-   byte[] objectToByteBuffer(Object obj, int estimatedSize) throws IOException;
+   byte[] objectToByteBuffer(Object obj, int estimatedSize) throws IOException, InterruptedException;
 
    /**
     * Marshalls an object to a byte array.
     *
     * @param obj object to convert to a byte array.  Must not be null.
     * @return a byte array
-    * @throws IOException
+    * @throws IOException if marshalling cannot complete due to some I/O error
+    * @throws InterruptedException if the marshalling process was interrupted. Clients should take this as a sign that
+    * the marshaller is no longer available, maybe due to shutdown, and so no more marshalling should be attempted.
     */
-   byte[] objectToByteBuffer(Object obj) throws IOException;
+   byte[] objectToByteBuffer(Object obj) throws IOException, InterruptedException;
 
    /**
     * Unmarshalls an object from a byte array.
     *
     * @param buf byte array containing the binary representation of an object.  Must not be null.
     * @return an object
-    * @throws IOException
-    * @throws ClassNotFoundException
+    * @throws IOException if unmarshalling cannot complete due to some I/O error
+    * @throws ClassNotFoundException if the class of the object trying to unmarshall is unknown
     */
    Object objectFromByteBuffer(byte[] buf) throws IOException, ClassNotFoundException;
 
@@ -63,8 +67,8 @@
     * @param offset point in buffer to start reading
     * @param length number of bytes to consider
     * @return an object
-    * @throws IOException
-    * @throws ClassNotFoundException
+    * @throws IOException if unmarshalling cannot complete due to some I/O error
+    * @throws ClassNotFoundException if the class of the object trying to unmarshall is unknown
     */
    Object objectFromByteBuffer(byte[] buf, int offset, int length) throws IOException, ClassNotFoundException;
 
@@ -74,9 +78,11 @@
     *
     * @param o object to marshall
     * @return a ByteBuffer
-    * @throws Exception
+    * @throws IOException if marshalling cannot complete due to some I/O error
+    * @throws InterruptedException if the marshalling process was interrupted. Clients should take this as a sign that
+    * the marshaller is no longer available, maybe due to shutdown, and so no more marshalling should be attempted.
     */
-   ByteBuffer objectToBuffer(Object o) throws IOException;
+   ByteBuffer objectToBuffer(Object o) throws IOException, InterruptedException;
 
    /**
     * A method that checks whether the given object is marshallable as per the rules of this marshaller.

Modified: trunk/core/src/main/java/org/infinispan/marshall/StreamingMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/StreamingMarshaller.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/marshall/StreamingMarshaller.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -121,8 +121,12 @@
     * Unmarshalls an object from an {@link java.io.ObjectInput}
     *
     * @param in stream to unmarshall from
+    * @throws IOException if unmarshalling cannot complete due to some I/O error
+    * @throws ClassNotFoundException if the class of the object trying to unmarshall is unknown
+    * @throws InterruptedException if the unmarshalling was interrupted. Clients should take this as a sign that
+    * the marshaller is no longer available, maybe due to shutdown, and so no more unmarshalling should be attempted.
     */
-   Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException;
+   Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException, InterruptedException;
 
    Object objectFromInputStream(InputStream is) throws IOException, ClassNotFoundException;
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/marshall/VersionAwareMarshaller.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -86,7 +86,7 @@
    }
 
    @Override
-   protected ByteBuffer objectToBuffer(Object obj, int estimatedSize) throws IOException {
+   protected ByteBuffer objectToBuffer(Object obj, int estimatedSize) throws IOException, InterruptedException {
       ExposedByteArrayOutputStream baos = new ExposedByteArrayOutputStream(estimatedSize);
       ObjectOutput out = startObjectOutput(baos, false);
       try {
@@ -96,7 +96,10 @@
          throw new org.infinispan.marshall.NotSerializableException(nse.getMessage(), nse.getCause());
       } catch (IOException ioe) {
          if (log.isTraceEnabled()) log.trace("Exception while marshalling object", ioe);
-         throw ioe;
+         if (ioe.getCause() instanceof InterruptedException)
+            throw (InterruptedException) ioe.getCause();
+         else
+            throw ioe;
       } finally {
          finishObjectOutput(out);
       }
@@ -169,7 +172,7 @@
    }
 
    @Override   
-   public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException {
+   public Object objectFromObjectStream(ObjectInput in) throws IOException, ClassNotFoundException, InterruptedException {
       /* No need to read version here. Clients should either be calling either:
        * - startObjectInput() -> objectFromObjectStream() -> finishObjectInput()
        * or
@@ -177,7 +180,15 @@
        * So, there's only need to read version during the start. 
        * First option is preferred when multiple objects are gonna be written.
        */
-      return defaultMarshaller.objectFromObjectStream(in);
+      try {
+         return defaultMarshaller.objectFromObjectStream(in);
+      } catch (IOException ioe) {
+         if (trace) log.trace("Log exception reported", ioe); 
+         if (ioe.getCause() instanceof InterruptedException)
+            throw (InterruptedException) ioe.getCause();
+         else
+            throw ioe;
+      }
    }
 
    @Override

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -84,6 +84,7 @@
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.ObjectTable;
 import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.river.RiverUnmarshaller;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -189,6 +190,8 @@
     */
    private final Map<Integer, ExternalizerAdapter> readers = new HashMap<Integer, ExternalizerAdapter>();
 
+   private volatile boolean started;
+
    public void start(RemoteCommandsFactory cmdFactory, StreamingMarshaller ispnMarshaller) {
       HashSet<Integer> ids = new HashSet<Integer>();
 
@@ -237,19 +240,64 @@
             }
          }
       }
+
+      started = true;
+
+      if (log.isTraceEnabled())
+         log.trace("Constant object table was started and contains these externalizer readers: {0}", readers);
    }
 
    public void stop() {
       writers.clear();
       readers.clear();
+      started = false;
+      if (log.isTraceEnabled())
+         log.trace("Externalizer reader and writer maps have been cleared and constant object table was stopped");
    }
 
    public Writer getObjectWriter(Object o) throws IOException {
-      return writers.get(o.getClass());
+      Class clazz = o.getClass();
+      Writer writer = writers.get(clazz);
+      if (writer == null && (MARSHALLABLES.contains(clazz.getName()) || JDK_EXTERNALIZERS.containsKey(clazz.getName()))) {
+         if (log.isTraceEnabled())
+            log.trace("Either the marshaller has stopped or hasn't started. Write externalizers are not propery populated: {0}", writers);
+
+         if (Thread.currentThread().isInterrupted())
+            throw new IOException("Cache manager is shutting down, " +
+                  "so type write externalizer for type=" + clazz.getName() + " cannot be resolved. " +
+                  "Interruption being pushed up.", new InterruptedException());
+         else
+            throw new IllegalStateException("No write externalizer available for: " + clazz.getName() +
+                  ", either marshaller is stopped or has not started up yet.");
+      }
+      return writer;
    }
 
    public Object readObject(Unmarshaller input) throws IOException, ClassNotFoundException {
-      ExternalizerAdapter adapter = readers.get(input.readUnsignedByte());
+      int readerIndex = input.readUnsignedByte();
+      ExternalizerAdapter adapter = readers.get(readerIndex);
+      if (adapter == null) {
+         if (!started) {
+            if (log.isTraceEnabled())
+               log.trace("Either the marshaller has stopped or hasn't started. Read externalizers are not propery populated: {0}", readers);
+
+            if (Thread.currentThread().isInterrupted())
+               throw new IOException("Cache manager is shutting down, " +
+                     "so type (id=" + readerIndex + ") cannot be resolved. Interruption being pushed up.", new InterruptedException());
+            else
+               throw new CacheException("Cache manager is either starting up or shutting down but it's not interrupted, " +
+                     "so type (id=" + readerIndex + ") cannot be resolved.");
+         } else {
+            if (log.isTraceEnabled()) {
+               log.trace("Unknown type. Input stream has {0} to read", input.available());
+               log.trace("Check contents of read externalizers: {0}", readers);
+            }
+
+            throw new CacheException("Type of data read is unknown. Id=" + readerIndex + " " +
+                  "is not amongst known reader indexes.");
+         }
+      }
+
       return adapter.readObject(input);
    }
 
@@ -270,5 +318,11 @@
          output.write(id);
          externalizer.writeObject(output, object);
       }
+
+      @Override
+      public String toString() {
+         // Each adapter is represented by the externalizer it delegates to, so just return the class name
+         return externalizer.getClass().getName();
+      }
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/util/Util.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/Util.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/util/Util.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -27,11 +27,19 @@
 import java.io.InputStream;
 import java.io.ObjectOutput;
 import java.io.OutputStream;
+import java.lang.management.LockInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.HashMap;
+import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
@@ -363,4 +371,102 @@
          }
       }
    }
+
+   private static String INDENT = "    ";
+
+   public static String threadDump() {
+      StringBuilder threadDump = new StringBuilder();
+      ThreadMXBean threadMx = ManagementFactory.getThreadMXBean();
+      if (threadMx.isObjectMonitorUsageSupported() && threadMx.isSynchronizerUsageSupported()) {
+         // Print lock info if, and only if, both object monitor usage and synchronizer usage are supported.
+          dumpThreadInfo(threadDump, true, threadMx);
+      } else {
+         dumpThreadInfo(threadDump, false, threadMx);
+      }
+      return threadDump.toString();
+   }
+
+   private static void dumpThreadInfo(StringBuilder threadDump, boolean withLocks, ThreadMXBean threadMx) {
+      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+      String timestamp = dateFormat.format(new Date());
+      threadDump.append(timestamp);
+      threadDump.append("\nFull thread dump ");
+      threadDump.append("\n");
+
+      if (withLocks) {
+         ThreadInfo[] threadInfos = threadMx.dumpAllThreads(true, true);
+         for (ThreadInfo threadInfo : threadInfos) {
+            printThreadInfo(threadInfo, threadDump);
+            LockInfo[] syncs = threadInfo.getLockedSynchronizers();
+            printLockInfo(syncs, threadDump);
+         }
+         threadDump.append("\n");
+      } else {
+         long[] threadIds= threadMx.getAllThreadIds();
+         ThreadInfo[] threadInfos = threadMx.getThreadInfo(threadIds, Integer.MAX_VALUE);
+         for (ThreadInfo threadInfo : threadInfos)
+            printThreadInfo(threadInfo, threadDump);
+      }
+   }
+
+   private static void printThreadInfo(ThreadInfo threadInfo, StringBuilder threadDump) {
+      // Print thread information
+      printThread(threadInfo, threadDump);
+      // print stack trace with locks
+      StackTraceElement[] stacktrace = threadInfo.getStackTrace();
+      MonitorInfo[] monitors = threadInfo.getLockedMonitors();
+      for (int i = 0; i < stacktrace.length; i++) {
+          StackTraceElement ste = stacktrace[i];
+          threadDump.append(INDENT + "at " + ste.toString());
+          threadDump.append("\n");
+          for (int j = 1; j < monitors.length; j++) {
+              MonitorInfo mi = monitors[j];
+              if (mi.getLockedStackDepth() == i) {
+                  threadDump.append(INDENT + "  - locked " + mi);
+                  threadDump.append("\n");
+              }
+          }
+      }
+      threadDump.append("\n");
+   }
+
+   private static void printLockInfo(LockInfo[] locks, StringBuilder threadDump) {
+      threadDump.append(INDENT + "Locked synchronizers: count = " + locks.length);
+      threadDump.append("\n");
+      for (int i = 0; i < locks.length; i++) {
+          LockInfo li = locks[i];
+          threadDump.append(INDENT + "  - " + li);
+          threadDump.append("\n");
+      }
+      threadDump.append("\n");
+   }
+
+   private static void printThread(ThreadInfo threadInfo, StringBuilder threadDump) {
+      StringBuilder sb = new StringBuilder(
+            "\"" + threadInfo.getThreadName() + "\"" +
+            " nid=" + threadInfo.getThreadId() + " state=" +
+            threadInfo.getThreadState());
+      if (threadInfo.getLockName() != null && threadInfo.getThreadState() != Thread.State.BLOCKED) {
+          String[] lockInfo = threadInfo.getLockName().split("@");
+          sb.append("\n" + INDENT +"- waiting on <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
+          sb.append("\n" + INDENT +"- locked <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
+      } else if (threadInfo.getLockName() != null && threadInfo.getThreadState() == Thread.State.BLOCKED) {
+          String[] lockInfo = threadInfo.getLockName().split("@");
+          sb.append("\n" + INDENT +"- waiting to lock <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
+      }
+      if (threadInfo.isSuspended())
+          sb.append(" (suspended)");
+
+      if (threadInfo.isInNative())
+          sb.append(" (running in native)");
+
+      threadDump.append(sb.toString());
+      threadDump.append("\n");
+      if (threadInfo.getLockOwnerName() != null) {
+           threadDump.append(INDENT + " owned by " + threadInfo.getLockOwnerName() +
+                              " id=" + threadInfo.getLockOwnerId());
+           threadDump.append("\n");
+      }
+   }
+
 }

Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/StripedLock.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/StripedLock.java	2010-10-21 15:16:13 UTC (rev 2554)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/StripedLock.java	2010-10-21 15:21:39 UTC (rev 2555)
@@ -197,6 +197,7 @@
          } catch (InterruptedException e) {
             if (log.isTraceEnabled()) log.trace("Cought InterruptedException while trying to aquire global lock", e);
             success = false;
+            Thread.currentThread().interrupt(); // Restore interrupted status
          } finally {
             if (!success) {
                for (int j = 0; j < i; j++) {



More information about the infinispan-commits mailing list