Author: david.lloyd(a)jboss.com
Date: 2008-07-17 18:49:31 -0400 (Thu, 17 Jul 2008)
New Revision: 4380
Added:
remoting3/trunk/api/src/test/java/org/jboss/cx/remoting/spi/CloseableTestCase.java
Modified:
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractAutoCloseable.java
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java
Log:
Add test case for closables
Modified:
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractAutoCloseable.java
===================================================================
---
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractAutoCloseable.java 2008-07-17
16:21:03 UTC (rev 4379)
+++
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractAutoCloseable.java 2008-07-17
22:49:31 UTC (rev 4380)
@@ -55,8 +55,10 @@
protected void dec() throws RemotingException {
final int v = refcount.decrementAndGet();
+ log.trace("Clearing reference to %s to %d", this, Integer.valueOf(v));
if (v == 0) {
// we dropped the refcount to zero
+ log.trace("Refcount of %s dropped to zero, closing", this);
if (refcount.compareAndSet(0, -65536)) {
// we are closing
close();
@@ -71,6 +73,7 @@
protected void inc() throws RemotingException {
final int v = refcount.getAndIncrement();
+ log.trace("Adding reference to %s to %d", this, Integer.valueOf(v +
1));
if (v < 0) {
// was already closed
refcount.decrementAndGet();
@@ -95,6 +98,10 @@
inc();
}
+ public void close() throws RemotingException {
+ dec();
+ }
+
@SuppressWarnings({ "unchecked" })
public T getResource() {
return (T) AbstractAutoCloseable.this;
Modified:
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java
===================================================================
---
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java 2008-07-17
16:21:03 UTC (rev 4379)
+++
remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java 2008-07-17
22:49:31 UTC (rev 4380)
@@ -58,6 +58,7 @@
public void close() throws RemotingException {
if (! closed.getAndSet(true)) {
+ log.trace("Closed %s", this);
synchronized (closeLock) {
if (closeHandlers != null) {
for (final CloseHandler<? super T> handler : closeHandlers) {
Added: remoting3/trunk/api/src/test/java/org/jboss/cx/remoting/spi/CloseableTestCase.java
===================================================================
--- remoting3/trunk/api/src/test/java/org/jboss/cx/remoting/spi/CloseableTestCase.java
(rev 0)
+++
remoting3/trunk/api/src/test/java/org/jboss/cx/remoting/spi/CloseableTestCase.java 2008-07-17
22:49:31 UTC (rev 4380)
@@ -0,0 +1,179 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.jboss.cx.remoting.spi;
+
+import junit.framework.TestCase;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.jboss.xnio.IoUtils;
+import org.jboss.cx.remoting.CloseHandler;
+import org.jboss.cx.remoting.test.support.LoggingHelper;
+import org.jboss.cx.remoting.spi.remote.Handle;
+
+/**
+ *
+ */
+public final class CloseableTestCase extends TestCase {
+ static {
+ LoggingHelper.init();
+ }
+
+ public void testBasic() throws Throwable {
+ final ExecutorService executorService = Executors.newCachedThreadPool();
+ try {
+ final AtomicBoolean closed = new AtomicBoolean();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AbstractCloseable<Object> closeable = new
AbstractCloseable<Object>(executorService) {
+ // empty
+ };
+ try {
+ closeable.addCloseHandler(new CloseHandler<Object>() {
+ public void handleClose(final Object x) {
+ closed.set(true);
+ latch.countDown();
+ }
+ });
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ closeable.close();
+ assertTrue(latch.await(500L, TimeUnit.MILLISECONDS));
+ assertFalse(closeable.isOpen());
+ assertTrue(closed.get());
+ } finally {
+ IoUtils.safeClose(closeable);
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+ }
+
+ public void testAutoClose() throws Throwable {
+ final ExecutorService executorService = Executors.newCachedThreadPool();
+ try {
+ final AtomicBoolean closed = new AtomicBoolean();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AbstractAutoCloseable<Object> closeable = new
AbstractAutoCloseable<Object>(executorService) {
+ // empty
+ };
+ try {
+ closeable.addCloseHandler(new CloseHandler<Object>() {
+ public void handleClose(final Object x) {
+ closed.set(true);
+ latch.countDown();
+ }
+ });
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ closeable.autoClose();
+ assertTrue(latch.await(500L, TimeUnit.MILLISECONDS));
+ assertFalse(closeable.isOpen());
+ assertTrue(closed.get());
+ } finally {
+ IoUtils.safeClose(closeable);
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+ }
+
+ public void testAutoCloseWithOneRef() throws Throwable {
+ final ExecutorService executorService = Executors.newCachedThreadPool();
+ try {
+ final AtomicBoolean closed = new AtomicBoolean();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AbstractAutoCloseable<Object> closeable = new
AbstractAutoCloseable<Object>(executorService) {
+ // empty
+ };
+ try {
+ closeable.addCloseHandler(new CloseHandler<Object>() {
+ public void handleClose(final Object x) {
+ closed.set(true);
+ latch.countDown();
+ }
+ });
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ final Handle<Object> h1 = closeable.getHandle();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ closeable.autoClose();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ h1.close();
+ assertTrue(latch.await(500L, TimeUnit.MILLISECONDS));
+ assertFalse(closeable.isOpen());
+ assertTrue(closed.get());
+ } finally {
+ IoUtils.safeClose(closeable);
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+ }
+
+ public void testAutoCloseWithThreeRefs() throws Throwable {
+ final ExecutorService executorService = Executors.newCachedThreadPool();
+ try {
+ final AtomicBoolean closed = new AtomicBoolean();
+ final CountDownLatch latch = new CountDownLatch(1);
+ final AbstractAutoCloseable<Object> closeable = new
AbstractAutoCloseable<Object>(executorService) {
+ // empty
+ };
+ try {
+ closeable.addCloseHandler(new CloseHandler<Object>() {
+ public void handleClose(final Object x) {
+ closed.set(true);
+ latch.countDown();
+ }
+ });
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ final Handle<Object> h1 = closeable.getHandle();
+ final Handle<Object> h2 = closeable.getHandle();
+ final Handle<Object> h3 = closeable.getHandle();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ closeable.autoClose();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ h1.close();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ h2.close();
+ assertTrue(closeable.isOpen());
+ assertFalse(closed.get());
+ h3.close();
+ assertTrue(latch.await(500L, TimeUnit.MILLISECONDS));
+ assertFalse(closeable.isOpen());
+ assertTrue(closed.get());
+ } finally {
+ IoUtils.safeClose(closeable);
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+ }
+}