ignite-642 review
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/18c5edac Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/18c5edac Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/18c5edac Branch: refs/heads/ignite-642 Commit: 18c5edac0934d862f147ebc4e98858feb6ac3ddf Parents: b8fdb9d Author: Yakov Zhdanov <[email protected]> Authored: Thu Apr 14 18:52:07 2016 +0300 Committer: Yakov Zhdanov <[email protected]> Committed: Thu Apr 14 18:52:07 2016 +0300 ---------------------------------------------------------------------- .../ignite/internal/GridKernalContextImpl.java | 4 +- .../datastructures/GridCacheLockImpl.java | 58 ++++++++++++++------ .../datastructures/GridCacheSemaphoreImpl.java | 33 +++++++++++ .../IgniteSemaphoreAbstractSelfTest.java | 31 +++++++++++ .../distributed/GridCacheLockAbstractTest.java | 33 ++++++++++- 5 files changed, 138 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/18c5edac/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java index 753dbe8..7cff188 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java @@ -864,7 +864,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - stash.set(U.readString(in)); + U.readString(in); // Read for compatibility only. See #readResolve(). } /** @@ -875,7 +875,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable */ protected Object readResolve() throws ObjectStreamException { try { - return IgnitionEx.gridx(stash.get()).context(); + return IgnitionEx.localIgnite().context(); } catch (IllegalStateException e) { throw U.withCause(new InvalidObjectException(e.getMessage()), e); http://git-wip-us.apache.org/repos/asf/ignite/blob/18c5edac/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheLockImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheLockImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheLockImpl.java index 702a6cb..ff5e795 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheLockImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheLockImpl.java @@ -19,8 +19,10 @@ package org.apache.ignite.internal.processors.datastructures; import java.io.Externalizable; import java.io.IOException; +import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.io.ObjectStreamException; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -44,7 +46,7 @@ import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteInterruptedException; import org.apache.ignite.IgniteLock; import org.apache.ignite.IgniteLogger; -import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgnitionEx; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; @@ -52,7 +54,6 @@ import org.apache.ignite.internal.util.typedef.X; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; -import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.transactions.TransactionRollbackException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -69,12 +70,7 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable private static final long serialVersionUID = 0L; /** Deserialization stash. */ - private static final ThreadLocal<IgniteBiTuple<GridKernalContext, String>> stash = - new ThreadLocal<IgniteBiTuple<GridKernalContext, String>>() { - @Override protected IgniteBiTuple<GridKernalContext, String> initialValue() { - return new IgniteBiTuple<>(); - } - }; + private static final ThreadLocal<String> stash = new ThreadLocal<>(); /** Logger. */ private IgniteLogger log; @@ -416,7 +412,7 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable int nextc = c + acquires; if (nextc < 0) // overflow - throw new Error("Maximum lock count exceeded"); + throw new Error("Maximum lock count exceeded."); setState(nextc); @@ -563,7 +559,7 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable return false; } - catch (Error | Exception e) { + catch (Exception e) { if (interruptAll) { log.info("Node is stopped (or lock is broken in non-failover safe mode)," + " aborting transaction."); @@ -651,7 +647,7 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable return false; } - catch (Error | Exception e) { + catch (Exception e) { if (interruptAll) { log.info("Node is stopped (or lock is broken in non-failover safe mode)," + " aborting transaction."); @@ -804,16 +800,15 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable return true; } - catch (Error | Exception e) { + catch (Exception e) { if (interruptAll) { log.info("Node is stopped (or lock is broken in non-failover safe mode)," + " aborting transaction."); return true; } - else{ + else U.error(log, "Failed to release: " + this, e); - } throw e; } @@ -1469,16 +1464,43 @@ public final class GridCacheLockImpl implements GridCacheLockEx, Externalizable /** {@inheritDoc} */ @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeObject(ctx.kernalContext()); out.writeUTF(name); } /** {@inheritDoc} */ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - IgniteBiTuple<GridKernalContext, String> t = stash.get(); + stash.set(in.readUTF()); + } + + /** + * Reconstructs object on unmarshalling. + * + * @return Reconstructed object. + * @throws ObjectStreamException Thrown in case of unmarshalling error. + */ + private Object readResolve() throws ObjectStreamException { + String name = stash.get(); + + assert name != null; - t.set1((GridKernalContext)in.readObject()); - t.set2(in.readUTF()); + try { + IgniteLock lock = IgnitionEx.localIgnite().context().dataStructures().reentrantLock( + name, + false, + false, + false); + + if (lock == null) + throw new IllegalStateException("Lock was not found on deserialization: " + name); + + return lock; + } + catch (IgniteCheckedException e) { + throw U.withCause(new InvalidObjectException(e.getMessage()), e); + } + finally { + stash.remove(); + } } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/18c5edac/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java index c365f9d..8f196be 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheSemaphoreImpl.java @@ -19,8 +19,10 @@ package org.apache.ignite.internal.processors.datastructures; import java.io.Externalizable; import java.io.IOException; +import java.io.InvalidObjectException; import java.io.ObjectInput; import java.io.ObjectOutput; +import java.io.ObjectStreamException; import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; @@ -32,7 +34,9 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteInterruptedException; import org.apache.ignite.IgniteLogger; +import org.apache.ignite.IgniteSemaphore; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgnitionEx; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.IgniteInternalCache; import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx; @@ -885,6 +889,35 @@ public final class GridCacheSemaphoreImpl implements GridCacheSemaphoreEx, Exter t.set2(in.readUTF()); } + /** + * Reconstructs object on unmarshalling. + * + * @return Reconstructed object. + * @throws ObjectStreamException Thrown in case of unmarshalling error. + */ + private Object readResolve() throws ObjectStreamException { + try { + IgniteBiTuple<GridKernalContext, String> t = stash.get(); + + IgniteSemaphore sem = IgnitionEx.localIgnite().context().dataStructures().semaphore( + t.get2(), + 0, + false, + false); + + if (sem == null) + throw new IllegalStateException("Semaphore was not found on deserialization: " + t.get2()); + + return sem; + } + catch (IgniteCheckedException e) { + throw U.withCause(new InvalidObjectException(e.getMessage()), e); + } + finally { + stash.remove(); + } + } + /** {@inheritDoc} */ @Override public void close() { if (!rmvd) { http://git-wip-us.apache.org/repos/asf/ignite/blob/18c5edac/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java index e60aed3..200e276 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/IgniteSemaphoreAbstractSelfTest.java @@ -77,6 +77,7 @@ public abstract class IgniteSemaphoreAbstractSelfTest extends IgniteAtomicsAbstr */ public void testSemaphore() throws Exception { checkSemaphore(); + checkSemaphoreSerialization(); } /** @@ -231,6 +232,36 @@ public abstract class IgniteSemaphoreAbstractSelfTest extends IgniteAtomicsAbstr } /** + * @throws Exception If failed. + */ + private void checkSemaphoreSerialization() throws Exception { + final IgniteSemaphore sem = grid(0).semaphore("semaphore", -gridCount() + 1, true, true); + + assertEquals(-gridCount() + 1, sem.availablePermits()); + + grid(0).compute().broadcast(new IgniteCallable<Object>() { + @Nullable @Override public Object call() throws Exception { + sem.release(); + + return null; + } + }); + + assert sem.availablePermits() == 1; + + sem.acquire(); + + assert sem.availablePermits() == 0; + + sem.release(); + + // Test operations on removed semaphore. + sem.close(); + + checkRemovedSemaphore(sem); + } + + /** * @param semaphore Semaphore. * @throws Exception If failed. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/18c5edac/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java index ae591bd..679f527 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheLockAbstractTest.java @@ -28,11 +28,13 @@ import java.util.concurrent.locks.Lock; import javax.cache.Cache; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteLock; import org.apache.ignite.cache.CacheMode; import org.apache.ignite.cache.affinity.Affinity; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.lang.IgniteCallable; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; @@ -323,6 +325,35 @@ public abstract class GridCacheLockAbstractTest extends GridCommonAbstractTest { } /** + * @throws Exception If failed. + */ + public void testLockSerialization() throws Exception { + final IgniteLock lock = ignite1.reentrantLock("lock", true, true, true); + + info("Lock created: " + lock); + + lock.isFailoverSafe(); + lock.isFair(); + + ignite2.compute().broadcast(new IgniteCallable<Object>() { + @Nullable @Override public Object call() throws Exception { + Thread.sleep(1000); + + lock.lock(); + + try { + System.out.println("Inside lock: " + lock.getHoldCount()); + } + finally { + lock.unlock(); + } + + return null; + } + }); + } + + /** * @throws Exception If test failed. */ public void testLockAndPut() throws Exception { @@ -573,4 +604,4 @@ public abstract class GridCacheLockAbstractTest extends GridCommonAbstractTest { } } } -} \ No newline at end of file +}
