You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2011/05/14 22:20:43 UTC
svn commit: r1103210 [2/2] - in
/activemq/activemq-cpp/trunk/activemq-cpp/src:
main/decaf/util/concurrent/locks/ test/ test/decaf/util/concurrent/locks/
Added: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp?rev=1103210&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp Sat May 14 20:20:43 2011
@@ -0,0 +1,1632 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AbstractQueuedSynchronizerTest.h"
+
+#include <decaf/lang/System.h>
+#include <decaf/lang/Thread.h>
+#include <decaf/lang/Runnable.h>
+#include <decaf/util/Date.h>
+#include <decaf/util/concurrent/TimeUnit.h>
+#include <decaf/util/concurrent/locks/LockSupport.h>
+#include <decaf/util/concurrent/locks/AbstractQueuedSynchronizer.h>
+
+using namespace std;
+using namespace decaf;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::util;
+using namespace decaf::util::concurrent;
+using namespace decaf::util::concurrent::locks;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestMutex : public AbstractQueuedSynchronizer {
+ public:
+
+ TestMutex() {}
+ virtual ~TestMutex() {}
+
+ bool isHeldExclusively() const { return getState() == 1; }
+
+ bool tryAcquire(int acquires) {
+ //CPPUNIT_ASSERT(acquires == 1);
+ return compareAndSetState(0, 1);
+ }
+
+ bool tryRelease(int releases) {
+ if (getState() == 0) {
+ throw IllegalMonitorStateException();
+ }
+ setState(0);
+ return true;
+ }
+
+ AbstractQueuedSynchronizer::ConditionObject* newCondition() {
+ return AbstractQueuedSynchronizer::createDefaultConditionObject();
+ }
+
+ };
+
+ class BooleanLatch : public AbstractQueuedSynchronizer {
+ public:
+
+ BooleanLatch() {}
+ virtual ~BooleanLatch() {}
+
+ bool isSignalled() { return getState() != 0; }
+
+ int tryAcquireShared(int ignore) {
+ return isSignalled()? 1 : -1;
+ }
+
+ bool tryReleaseShared(int ignore) {
+ setState(1);
+ return true;
+ }
+ };
+
+ /**
+ * A runnable calling acquireInterruptibly
+ */
+ class InterruptibleSyncRunnable : public Runnable {
+ private:
+
+ AbstractQueuedSynchronizerTest* parent;
+ TestMutex* mutex;
+
+ public:
+
+ InterruptibleSyncRunnable(AbstractQueuedSynchronizerTest* parent,
+ TestMutex* mutex) : Runnable(), parent(parent), mutex(mutex) {}
+ virtual ~InterruptibleSyncRunnable() {}
+
+ virtual void run() {
+ try {
+ std::cout << "InterruptibleSyncRunnable acquireInterruptibly" << std::endl;
+ mutex->acquireInterruptibly(1);
+ std::cout << "InterruptibleSyncRunnable was not interrupted" << std::endl;
+ } catch(InterruptedException& success) {
+ std::cout << "InterruptibleSyncRunnable was interrupted" << std::endl;
+ } catch(Exception& ex) {
+ parent->threadUnexpectedException(ex);
+ } catch(std::exception& stdex) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+
+ class InterruptedSyncRunnable : public Runnable {
+ private:
+
+ AbstractQueuedSynchronizerTest* parent;
+ TestMutex* mutex;
+
+ public:
+
+ InterruptedSyncRunnable(AbstractQueuedSynchronizerTest* parent,
+ TestMutex* mutex) : Runnable(), parent(parent), mutex(mutex) {}
+ virtual ~InterruptedSyncRunnable() {}
+
+ void run() {
+ try {
+ std::cout << "InterruptedSyncRunnable acquireInterruptibly" << std::endl;
+ mutex->acquireInterruptibly(1);
+ parent->threadFail("Should have been interrupted.");
+ } catch(InterruptedException& success) {
+ std::cout << "InterruptedSyncRunnable was interrupted" << std::endl;
+ } catch(Exception& ex) {
+ parent->threadUnexpectedException(ex);
+ } catch(std::exception& stdex) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractQueuedSynchronizerTest::AbstractQueuedSynchronizerTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+AbstractQueuedSynchronizerTest::~AbstractQueuedSynchronizerTest() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testIsHeldExclusively() {
+ TestMutex rl;
+ CPPUNIT_ASSERT(!rl.isHeldExclusively());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquire() {
+ TestMutex rl;
+ rl.acquire(1);
+ CPPUNIT_ASSERT(rl.isHeldExclusively());
+ rl.release(1);
+ CPPUNIT_ASSERT(!rl.isHeldExclusively());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testTryAcquire() {
+ TestMutex rl;
+ CPPUNIT_ASSERT(rl.tryAcquire(1));
+ CPPUNIT_ASSERT(rl.isHeldExclusively());
+ rl.release(1);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testhasQueuedThreads() {
+
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ try {
+ CPPUNIT_ASSERT(!mutex.hasQueuedThreads());
+ mutex.acquire(1);
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasQueuedThreads());
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasQueuedThreads());
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasQueuedThreads());
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!mutex.hasQueuedThreads());
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testIsQueuedNPE() {
+ TestMutex mutex;
+ try {
+ mutex.isQueued(NULL);
+ shouldThrow();
+ } catch(NullPointerException& success) {
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testIsQueued() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ std::cout << std::endl;
+ try {
+ CPPUNIT_ASSERT(!mutex.isQueued(&t1));
+ CPPUNIT_ASSERT(!mutex.isQueued(&t2));
+ mutex.acquire(1);
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+// CPPUNIT_ASSERT(mutex.isQueued(&t1));
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+// CPPUNIT_ASSERT(mutex.isQueued(&t1));
+// CPPUNIT_ASSERT(mutex.isQueued(&t2));
+ t1.interrupt();
+// Thread::sleep(SHORT_DELAY_MS);
+// CPPUNIT_ASSERT(!mutex.isQueued(&t1));
+// CPPUNIT_ASSERT(mutex.isQueued(&t2));
+ mutex.release(1);
+// Thread::sleep(SHORT_DELAY_MS);
+// CPPUNIT_ASSERT(!mutex.isQueued(&t1));
+// Thread::sleep(SHORT_DELAY_MS);
+// CPPUNIT_ASSERT(!mutex.isQueued(&t2));
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ } catch(std::exception& ex) {
+ unexpectedException();
+ } catch(...) {
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetFirstQueuedThread() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ try {
+ CPPUNIT_ASSERT(mutex.getFirstQueuedThread() == NULL);
+ mutex.acquire(1);
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT_EQUAL(&t1, mutex.getFirstQueuedThread());
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT_EQUAL(&t1, mutex.getFirstQueuedThread());
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT_EQUAL(&t2, mutex.getFirstQueuedThread());
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.getFirstQueuedThread() == NULL);
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testHasContended() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ try {
+ CPPUNIT_ASSERT(!mutex.hasContended());
+ mutex.acquire(1);
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasContended());
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasContended());
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasContended());
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.hasContended());
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetQueuedThreads() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+ try {
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->isEmpty());
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->isEmpty());
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->contains(&t1));
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->contains(&t1));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->contains(&t2));
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->contains(&t1));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->contains(&t2));
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getQueuedThreads())->isEmpty());
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetExclusiveQueuedThreads() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ try {
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->isEmpty());
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->isEmpty());
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->contains(&t1));
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->contains(&t1));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->contains(&t2));
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->contains(&t1));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->contains(&t2));
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getExclusiveQueuedThreads())->isEmpty());
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetSharedQueuedThreads() {
+ TestMutex mutex;
+
+ InterruptedSyncRunnable iSyncRun1(this, &mutex);
+ InterruptibleSyncRunnable iSyncRun2(this, &mutex);
+
+ Thread t1(&iSyncRun1);
+ Thread t2(&iSyncRun2);
+
+ try {
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ t1.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getSharedQueuedThreads())->isEmpty());
+ t1.join();
+ t2.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestInterruptedException2Runnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestInterruptedException2Runnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex) :
+ Runnable(), mutex(mutex), parent(parent) {}
+ virtual ~TestInterruptedException2Runnable() {}
+
+ virtual void run() {
+ try {
+ mutex->tryAcquireNanos(1, AbstractQueuedSynchronizerTest::MEDIUM_DELAY_MS * 1000 * 1000);
+ parent->threadShouldThrow();
+ } catch(InterruptedException& success){}
+ }
+ };
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testInterruptedException2() {
+
+ TestMutex mutex;
+ mutex.acquire(1);
+ TestInterruptedException2Runnable run(this, &mutex);
+ Thread t(&run);
+
+ try {
+ t.start();
+ t.interrupt();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestTryAcquireWhenSyncedRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestTryAcquireWhenSyncedRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex) :
+ Runnable(), mutex(mutex), parent(parent) {}
+ virtual ~TestTryAcquireWhenSyncedRunnable() {}
+
+ virtual void run() {
+ parent->threadAssertFalse(mutex->tryAcquire(1));
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testTryAcquireWhenSynced() {
+ TestMutex mutex;
+ mutex.acquire(1);
+ TestTryAcquireWhenSyncedRunnable run(this, &mutex);
+ Thread t(&run);
+
+ try {
+ t.start();
+ t.join();
+ mutex.release(1);
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAcquireNanosTimeoutRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAcquireNanosTimeoutRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex) :
+ Runnable(), mutex(mutex), parent(parent) {}
+ virtual ~TestAcquireNanosTimeoutRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(mutex->tryAcquireNanos(1, 1000 * 1000));
+ } catch(Exception& ex) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireNanosTimeout() {
+ TestMutex mutex;
+ mutex.acquire(1);
+ TestAcquireNanosTimeoutRunnable run(this, &mutex);
+ Thread t(&run);
+
+ try {
+ t.start();
+ t.join();
+ mutex.release(1);
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestGetStateRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestGetStateRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex) :
+ Runnable(), mutex(mutex), parent(parent) {}
+ virtual ~TestGetStateRunnable() {}
+
+ virtual void run() {
+ mutex->acquire(1);
+ try {
+ Thread::sleep(AbstractQueuedSynchronizerTest::SMALL_DELAY_MS);
+ } catch(Exception& e) {
+ parent->threadUnexpectedException();
+ }
+ mutex->release(1);
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetState() {
+ TestMutex mutex;
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(mutex.isHeldExclusively());
+ mutex.release(1);
+ CPPUNIT_ASSERT(!mutex.isHeldExclusively());
+ TestGetStateRunnable run(this, &mutex);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(mutex.isHeldExclusively());
+ t.join();
+ CPPUNIT_ASSERT(!mutex.isHeldExclusively());
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireInterruptibly1() {
+ TestMutex mutex;
+ mutex.acquire(1);
+ InterruptedSyncRunnable iSyncRun(this, &mutex);
+ Thread t(&iSyncRun);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t.interrupt();
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.release(1);
+ t.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireInterruptibly2() {
+ TestMutex mutex;
+ try {
+ mutex.acquireInterruptibly(1);
+ } catch(Exception& e) {
+ unexpectedException();
+ }
+
+ InterruptedSyncRunnable iSyncRun(this, &mutex);
+ Thread t(&iSyncRun);
+
+ try {
+ t.start();
+ t.interrupt();
+ CPPUNIT_ASSERT(mutex.isHeldExclusively());
+ t.join();
+ } catch(Exception& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testOwns() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestMutex mutex2;
+ CPPUNIT_ASSERT(mutex.owns(c));
+ CPPUNIT_ASSERT(!mutex2.owns(c));
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitIllegalMonitor() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ try {
+ c->await();
+ shouldThrow();
+ } catch(IllegalMonitorStateException& success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testSignalIllegalMonitor() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ try {
+ c->signal();
+ shouldThrow();
+ } catch(IllegalMonitorStateException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitNanosTimeout() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ try {
+ mutex.acquire(1);
+ long t = c->awaitNanos(100);
+ CPPUNIT_ASSERT(t <= 0);
+ mutex.release(1);
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitTimeout() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ try {
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(!c->await(SHORT_DELAY_MS, TimeUnit::MILLISECONDS));
+ mutex.release(1);
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitUntilTimeout() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ try {
+ mutex.acquire(1);
+ Date d;
+ CPPUNIT_ASSERT(!c->awaitUntil((d.getTime() + 10)));
+ mutex.release(1);
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAwaitRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ Condition* cond;
+
+ public:
+
+ TestAwaitRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, Condition* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestAwaitRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwait() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestAwaitRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ c->signal();
+ mutex.release(1);
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testHasWaitersNPE() {
+ TestMutex mutex;
+ try {
+ mutex.hasWaiters(NULL);
+ shouldThrow();
+ } catch(NullPointerException& success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitQueueLengthNPE() {
+ TestMutex mutex;
+ try {
+ mutex.getWaitQueueLength(NULL);
+ shouldThrow();
+ } catch(NullPointerException& success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitingThreadsNPE() {
+ TestMutex mutex;
+ try {
+ mutex.getWaitingThreads(NULL);
+ shouldThrow();
+ } catch(NullPointerException& success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testHasWaitersIAE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ TestMutex mutex2;
+ try {
+ mutex2.hasWaiters(c);
+ shouldThrow();
+ } catch(IllegalArgumentException& success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testHasWaitersIMSE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ try {
+ mutex.hasWaiters(c);
+ shouldThrow();
+ } catch(IllegalMonitorStateException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitQueueLengthIAE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ TestMutex mutex2;
+ try {
+ mutex2.getWaitQueueLength(c);
+ shouldThrow();
+ } catch(IllegalArgumentException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitQueueLengthIMSE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ try {
+ mutex.getWaitQueueLength(c);
+ shouldThrow();
+ } catch(IllegalMonitorStateException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitingThreadsIAE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ TestMutex mutex2;
+ try {
+ mutex2.getWaitingThreads(c);
+ shouldThrow();
+ } catch(IllegalArgumentException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitingThreadsIMSE() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = (mutex.newCondition());
+ try {
+ mutex.getWaitingThreads(c);
+ shouldThrow();
+ } catch(IllegalMonitorStateException success) {
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestHasWaitersRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestHasWaitersRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestHasWaitersRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ parent->threadAssertFalse(mutex->hasWaiters(cond));
+ parent->threadAssertEquals(0, mutex->getWaitQueueLength(cond));
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testHasWaiters() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestHasWaitersRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep( SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(mutex.hasWaiters(c));
+ CPPUNIT_ASSERT_EQUAL(1, mutex.getWaitQueueLength(c));
+ c->signal();
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(!mutex.hasWaiters(c));
+ CPPUNIT_ASSERT_EQUAL(0, mutex.getWaitQueueLength(c));
+ mutex.release(1);
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ } catch(Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class testGetWaitQueueLengthRunnable1 : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ testGetWaitQueueLengthRunnable1(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~testGetWaitQueueLengthRunnable1() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ parent->threadAssertFalse(mutex->hasWaiters(cond));
+ parent->threadAssertEquals(0, mutex->getWaitQueueLength(cond));
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+
+ class testGetWaitQueueLengthRunnable2 : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ testGetWaitQueueLengthRunnable2(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~testGetWaitQueueLengthRunnable2() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ parent->threadAssertTrue(mutex->hasWaiters(cond));
+ parent->threadAssertEquals(1, mutex->getWaitQueueLength(cond));
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitQueueLength() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ testGetWaitQueueLengthRunnable1 run1(this, &mutex, c);
+ Thread t1(&run1);
+ testGetWaitQueueLengthRunnable2 run2(this, &mutex, c);
+ Thread t2(&run2);
+
+ try {
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(mutex.hasWaiters(c));
+ CPPUNIT_ASSERT_EQUAL(2, mutex.getWaitQueueLength(c));
+ c->signalAll();
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(!mutex.hasWaiters(c));
+ CPPUNIT_ASSERT_EQUAL(0, mutex.getWaitQueueLength(c));
+ mutex.release(1);
+ t1.join(SHORT_DELAY_MS);
+ t2.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t1.isAlive());
+ CPPUNIT_ASSERT(!t2.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestGetWaitingThreadsRunnable1 : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestGetWaitingThreadsRunnable1(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestGetWaitingThreadsRunnable1() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ std::auto_ptr<Collection<Thread*> > list(mutex->getWaitingThreads(cond));
+ parent->threadAssertTrue(list->isEmpty());
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+
+ class TestGetWaitingThreadsRunnable2 : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestGetWaitingThreadsRunnable2(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestGetWaitingThreadsRunnable2() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ std::auto_ptr<Collection<Thread*> > list(mutex->getWaitingThreads(cond));
+ parent->threadAssertFalse(list->isEmpty());
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetWaitingThreads() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestGetWaitingThreadsRunnable1 run1(this, &mutex, c);
+ Thread t1(&run1);
+ TestGetWaitingThreadsRunnable2 run2(this, &mutex, c);
+ Thread t2(&run2);
+
+ try {
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getWaitingThreads(c))->isEmpty());
+ mutex.release(1);
+ t1.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(mutex.hasWaiters(c));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getWaitingThreads(c))->contains(&t1));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getWaitingThreads(c))->contains(&t2));
+ c->signalAll();
+ mutex.release(1);
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ CPPUNIT_ASSERT(!mutex.hasWaiters(c));
+ CPPUNIT_ASSERT(std::auto_ptr<Collection<Thread*> >(mutex.getWaitingThreads(c))->isEmpty());
+ mutex.release(1);
+ t1.join(SHORT_DELAY_MS);
+ t2.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t1.isAlive());
+ CPPUNIT_ASSERT(!t2.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAwaitUninterruptiblyRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestAwaitUninterruptiblyRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestAwaitUninterruptiblyRunnable() {}
+
+ virtual void run() {
+ mutex->acquire(1);
+ cond->awaitUninterruptibly();
+ mutex->release(1);
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitUninterruptibly() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestAwaitUninterruptiblyRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t.interrupt();
+ mutex.acquire(1);
+ c->signal();
+ mutex.release(1);
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAwaitInterruptRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestAwaitInterruptRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestAwaitInterruptRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ cond->await();
+ mutex->release(1);
+ parent->threadShouldThrow();
+ } catch(InterruptedException& success) {
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitInterrupt() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestAwaitInterruptRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t.interrupt();
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAwaitNanosInterruptRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestAwaitNanosInterruptRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestAwaitNanosInterruptRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ cond->awaitNanos(1000 * 1000 * 1000); // 1 sec
+ mutex->release(1);
+ parent->threadShouldThrow();
+ } catch(InterruptedException& success) {
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitNanosInterrupt() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestAwaitNanosInterruptRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t.interrupt();
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAwaitUntilInterruptRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestAwaitUntilInterruptRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestAwaitUntilInterruptRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ Date d;
+ cond->awaitUntil((d.getTime() + 10000));
+ mutex->release(1);
+ parent->threadShouldThrow();
+ } catch(InterruptedException& success) {
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAwaitUntilInterrupt() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestAwaitNanosInterruptRunnable run(this, &mutex, c);
+ Thread t(&run);
+
+ try {
+ t.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ t.interrupt();
+ t.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestSignalAllRunnable : public Runnable {
+ private:
+
+ TestMutex* mutex;
+ AbstractQueuedSynchronizerTest* parent;
+ AbstractQueuedSynchronizer::ConditionObject* cond;
+
+ public:
+
+ TestSignalAllRunnable(AbstractQueuedSynchronizerTest* parent, TestMutex* mutex, AbstractQueuedSynchronizer::ConditionObject* cond) :
+ Runnable(), mutex(mutex), parent(parent), cond(cond) {}
+ virtual ~TestSignalAllRunnable() {}
+
+ virtual void run() {
+ try {
+ mutex->acquire(1);
+ cond->await();
+ mutex->release(1);
+ }
+ catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testSignalAll() {
+ TestMutex mutex;
+ AbstractQueuedSynchronizer::ConditionObject* c = mutex.newCondition();
+ TestSignalAllRunnable run1(this, &mutex, c);
+ Thread t1(&run1);
+ TestSignalAllRunnable run2(this, &mutex, c);
+ Thread t2(&run2);
+
+ try {
+ t1.start();
+ t2.start();
+ Thread::sleep(SHORT_DELAY_MS);
+ mutex.acquire(1);
+ c->signalAll();
+ mutex.release(1);
+ t1.join(SHORT_DELAY_MS);
+ t2.join(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!t1.isAlive());
+ CPPUNIT_ASSERT(!t2.isAlive());
+ }
+ catch (Exception& ex) {
+ unexpectedException();
+ }
+ delete c;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testToString() {
+ TestMutex mutex;
+ std::string us = mutex.toString();
+ CPPUNIT_ASSERT((int)(us.find("State = 0")) >= 0);
+ mutex.acquire(1);
+ std::string ls = mutex.toString();
+ CPPUNIT_ASSERT((int)(ls.find("State = 1")) >= 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testGetStateWithReleaseShared() {
+ BooleanLatch l;
+ CPPUNIT_ASSERT(!l.isSignalled());
+ l.releaseShared(0);
+ CPPUNIT_ASSERT(l.isSignalled());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testReleaseShared() {
+ BooleanLatch l;
+ CPPUNIT_ASSERT(!l.isSignalled());
+ l.releaseShared(0);
+ CPPUNIT_ASSERT(l.isSignalled());
+ l.releaseShared(0);
+ CPPUNIT_ASSERT(l.isSignalled());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAcquireSharedInterruptiblyRunnable : public Runnable {
+ private:
+
+ BooleanLatch* latch;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAcquireSharedInterruptiblyRunnable(AbstractQueuedSynchronizerTest* parent, BooleanLatch* latch) :
+ Runnable(), latch(latch), parent(parent) {}
+ virtual ~TestAcquireSharedInterruptiblyRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(latch->isSignalled());
+ latch->acquireSharedInterruptibly(0);
+ parent->threadAssertTrue(latch->isSignalled());
+ } catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireSharedInterruptibly() {
+ BooleanLatch l;
+ TestAcquireSharedInterruptiblyRunnable run(this, &l);
+ Thread t(&run);
+
+ try {
+ t.start();
+ CPPUNIT_ASSERT(!l.isSignalled());
+ Thread::sleep(SHORT_DELAY_MS);
+ l.releaseShared(0);
+ CPPUNIT_ASSERT(l.isSignalled());
+ t.join();
+ } catch (InterruptedException& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAsquireSharedTimedRunnable : public Runnable {
+ private:
+
+ BooleanLatch* latch;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAsquireSharedTimedRunnable(AbstractQueuedSynchronizerTest* parent, BooleanLatch* latch) :
+ Runnable(), latch(latch), parent(parent) {}
+ virtual ~TestAsquireSharedTimedRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(latch->isSignalled());
+ parent->threadAssertTrue(latch->tryAcquireSharedNanos(0, AbstractQueuedSynchronizerTest::MEDIUM_DELAY_MS* 1000 * 1000));
+ parent->threadAssertTrue(latch->isSignalled());
+ } catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAsquireSharedTimed() {
+ BooleanLatch l;
+ TestAsquireSharedTimedRunnable run(this, &l);
+ Thread t(&run);
+
+ try {
+ t.start();
+ CPPUNIT_ASSERT(!l.isSignalled());
+ Thread::sleep(SHORT_DELAY_MS);
+ l.releaseShared(0);
+ CPPUNIT_ASSERT(l.isSignalled());
+ t.join();
+ } catch (InterruptedException& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAcquireSharedInterruptiblyInterruptedExceptionRunnable : public Runnable {
+ private:
+
+ BooleanLatch* latch;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAcquireSharedInterruptiblyInterruptedExceptionRunnable(AbstractQueuedSynchronizerTest* parent, BooleanLatch* latch) :
+ Runnable(), latch(latch), parent(parent) {}
+ virtual ~TestAcquireSharedInterruptiblyInterruptedExceptionRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(latch->isSignalled());
+ latch->acquireSharedInterruptibly(0);
+ parent->threadAssertTrue(latch->isSignalled());
+ } catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireSharedInterruptiblyInterruptedException() {
+ BooleanLatch l;
+ TestAcquireSharedInterruptiblyInterruptedExceptionRunnable run(this, &l);
+ Thread t(&run);
+
+ t.start();
+ try {
+ CPPUNIT_ASSERT(!l.isSignalled());
+ t.interrupt();
+ t.join();
+ } catch (InterruptedException& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAcquireSharedNanosInterruptedExceptionRunnable : public Runnable {
+ private:
+
+ BooleanLatch* latch;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAcquireSharedNanosInterruptedExceptionRunnable(AbstractQueuedSynchronizerTest* parent, BooleanLatch* latch) :
+ Runnable(), latch(latch), parent(parent) {}
+ virtual ~TestAcquireSharedNanosInterruptedExceptionRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(latch->isSignalled());
+ latch->tryAcquireSharedNanos(0, AbstractQueuedSynchronizerTest::SMALL_DELAY_MS* 1000 * 1000);
+ parent->threadShouldThrow();
+ } catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireSharedNanosInterruptedException() {
+ BooleanLatch l;
+ TestAcquireSharedNanosInterruptedExceptionRunnable run(this, &l);
+ Thread t(&run);
+
+ t.start();
+ try {
+ Thread::sleep(SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!l.isSignalled());
+ t.interrupt();
+ t.join();
+ } catch (InterruptedException& e){
+ unexpectedException();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+ class TestAcquireSharedNanosTimeoutRunnable : public Runnable {
+ private:
+
+ BooleanLatch* latch;
+ AbstractQueuedSynchronizerTest* parent;
+
+ public:
+
+ TestAcquireSharedNanosTimeoutRunnable(AbstractQueuedSynchronizerTest* parent, BooleanLatch* latch) :
+ Runnable(), latch(latch), parent(parent) {}
+ virtual ~TestAcquireSharedNanosTimeoutRunnable() {}
+
+ virtual void run() {
+ try {
+ parent->threadAssertFalse(latch->isSignalled());
+ parent->threadAssertFalse(latch->tryAcquireSharedNanos(0, AbstractQueuedSynchronizerTest::SMALL_DELAY_MS* 1000 * 1000));
+ } catch(InterruptedException& e) {
+ parent->threadUnexpectedException();
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void AbstractQueuedSynchronizerTest::testAcquireSharedNanosTimeout() {
+ BooleanLatch l;
+ TestAcquireSharedNanosTimeoutRunnable run(this, &l);
+ Thread t(&run);
+
+ t.start();
+ try {
+ Thread::sleep( SHORT_DELAY_MS);
+ CPPUNIT_ASSERT(!l.isSignalled());
+ t.join();
+ } catch(InterruptedException& e) {
+ unexpectedException();
+ }
+}
Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h?rev=1103210&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h Sat May 14 20:20:43 2011
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DECAF_UTIL_CONCURRENT_LOCKS_ABSTRACTQUEUEDSYNCHRONIZERTEST_H_
+#define _DECAF_UTIL_CONCURRENT_LOCKS_ABSTRACTQUEUEDSYNCHRONIZERTEST_H_
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <decaf/util/concurrent/ExecutorsTestSupport.h>
+
+namespace decaf {
+namespace util {
+namespace concurrent {
+namespace locks {
+
+ class AbstractQueuedSynchronizerTest : public ExecutorsTestSupport {
+
+ CPPUNIT_TEST_SUITE( AbstractQueuedSynchronizerTest );
+// CPPUNIT_TEST( testIsHeldExclusively );
+// CPPUNIT_TEST( testAcquire );
+// CPPUNIT_TEST( testTryAcquire );
+// CPPUNIT_TEST( testhasQueuedThreads );
+// CPPUNIT_TEST( testIsQueuedNPE );
+ CPPUNIT_TEST( testIsQueued );
+// CPPUNIT_TEST( testGetFirstQueuedThread );
+// CPPUNIT_TEST( testHasContended );
+// CPPUNIT_TEST( testGetQueuedThreads );
+// CPPUNIT_TEST( testGetExclusiveQueuedThreads );
+// CPPUNIT_TEST( testGetSharedQueuedThreads );
+// CPPUNIT_TEST( testInterruptedException2 );
+// CPPUNIT_TEST( testTryAcquireWhenSynced );
+// CPPUNIT_TEST( testAcquireNanosTimeout );
+// CPPUNIT_TEST( testGetState );
+// CPPUNIT_TEST( testAcquireInterruptibly1 );
+// CPPUNIT_TEST( testAcquireInterruptibly2 );
+// CPPUNIT_TEST( testOwns );
+// CPPUNIT_TEST( testAwaitIllegalMonitor );
+// CPPUNIT_TEST( testSignalIllegalMonitor );
+// CPPUNIT_TEST( testAwaitNanosTimeout );
+// CPPUNIT_TEST( testAwaitTimeout );
+// CPPUNIT_TEST( testAwaitUntilTimeout );
+// CPPUNIT_TEST( testAwait );
+// CPPUNIT_TEST( testHasWaitersNPE );
+// CPPUNIT_TEST( testGetWaitQueueLengthNPE );
+// CPPUNIT_TEST( testGetWaitingThreadsNPE );
+// CPPUNIT_TEST( testHasWaitersIAE );
+// CPPUNIT_TEST( testHasWaitersIMSE );
+// CPPUNIT_TEST( testGetWaitQueueLengthIAE );
+// CPPUNIT_TEST( testGetWaitQueueLengthIMSE );
+// CPPUNIT_TEST( testGetWaitingThreadsIAE );
+// CPPUNIT_TEST( testGetWaitingThreadsIMSE );
+// CPPUNIT_TEST( testHasWaiters );
+// CPPUNIT_TEST( testGetWaitQueueLength );
+// CPPUNIT_TEST( testGetWaitingThreads );
+// CPPUNIT_TEST( testAwaitUninterruptibly );
+// CPPUNIT_TEST( testAwaitInterrupt );
+// CPPUNIT_TEST( testAwaitNanosInterrupt );
+// CPPUNIT_TEST( testAwaitUntilInterrupt );
+// CPPUNIT_TEST( testSignalAll );
+// CPPUNIT_TEST( testToString );
+// CPPUNIT_TEST( testGetStateWithReleaseShared );
+// CPPUNIT_TEST( testReleaseShared );
+// CPPUNIT_TEST( testAcquireSharedInterruptibly );
+// CPPUNIT_TEST( testAsquireSharedTimed );
+// CPPUNIT_TEST( testAcquireSharedInterruptiblyInterruptedException );
+// CPPUNIT_TEST( testAcquireSharedNanosInterruptedException );
+// CPPUNIT_TEST( testAcquireSharedNanosTimeout );
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+
+ AbstractQueuedSynchronizerTest();
+ virtual ~AbstractQueuedSynchronizerTest();
+
+ void testIsHeldExclusively();
+ void testAcquire();
+ void testTryAcquire();
+ void testhasQueuedThreads();
+ void testIsQueuedNPE();
+ void testIsQueued();
+ void testGetFirstQueuedThread();
+ void testHasContended();
+ void testGetQueuedThreads();
+ void testGetExclusiveQueuedThreads();
+ void testGetSharedQueuedThreads();
+ void testInterruptedException2();
+ void testTryAcquireWhenSynced();
+ void testAcquireNanosTimeout();
+ void testGetState();
+ void testAcquireInterruptibly1();
+ void testAcquireInterruptibly2();
+ void testOwns();
+ void testAwaitIllegalMonitor();
+ void testSignalIllegalMonitor();
+ void testAwaitNanosTimeout();
+ void testAwaitTimeout();
+ void testAwaitUntilTimeout();
+ void testAwait();
+ void testHasWaitersNPE();
+ void testGetWaitQueueLengthNPE();
+ void testGetWaitingThreadsNPE();
+ void testHasWaitersIAE();
+ void testHasWaitersIMSE();
+ void testGetWaitQueueLengthIAE();
+ void testGetWaitQueueLengthIMSE();
+ void testGetWaitingThreadsIAE();
+ void testGetWaitingThreadsIMSE();
+ void testHasWaiters();
+ void testGetWaitQueueLength();
+ void testGetWaitingThreads();
+ void testAwaitUninterruptibly();
+ void testAwaitInterrupt();
+ void testAwaitNanosInterrupt();
+ void testAwaitUntilInterrupt();
+ void testSignalAll();
+ void testToString();
+ void testGetStateWithReleaseShared();
+ void testReleaseShared();
+ void testAcquireSharedInterruptibly();
+ void testAsquireSharedTimed();
+ void testAcquireSharedInterruptiblyInterruptedException();
+ void testAcquireSharedNanosInterruptedException();
+ void testAcquireSharedNanosTimeout();
+
+ };
+
+}}}}
+
+#endif /* _DECAF_UTIL_CONCURRENT_LOCKS_ABSTRACTQUEUEDSYNCHRONIZERTEST_H_ */
Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/concurrent/locks/AbstractQueuedSynchronizerTest.h
------------------------------------------------------------------------------
svn:eol-style = native