activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r772734 - in /activemq/activemq-cpp/trunk/activemq-cpp/src: main/decaf/util/concurrent/atomic/AtomicInteger.cpp test/decaf/lang/PointerTest.cpp test/decaf/lang/PointerTest.h
Date Thu, 07 May 2009 18:13:04 GMT
Author: tabish
Date: Thu May  7 18:13:00 2009
New Revision: 772734

URL: http://svn.apache.org/viewvc?rev=772734&view=rev
Log:
AMQCPP-242 Changes to try and make AtomicInteger actually perform its operations atomically.

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/atomic/AtomicInteger.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.h

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/atomic/AtomicInteger.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/atomic/AtomicInteger.cpp?rev=772734&r1=772733&r2=772734&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/atomic/AtomicInteger.cpp
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/atomic/AtomicInteger.cpp
Thu May  7 18:13:00 2009
@@ -36,12 +36,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 int AtomicInteger::getAndSet( int newValue ) {
-    for(;;) {
-        int current = get();
-        if( compareAndSet( current, newValue ) ) {
-            return current;
-        }
-    }
+    return apr_atomic_xchg32( &this->value, newValue );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,9 +51,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 int AtomicInteger::getAndDecrement() {
-    int previous = (int)this->value;
-    apr_atomic_dec32( &this->value );
-    return previous;
+    return apr_atomic_dec32( &this->value ) + 1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -68,20 +61,17 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 int AtomicInteger::incrementAndGet() {
-    apr_atomic_inc32( &this->value );
-    return this->value;
+    return apr_atomic_inc32( &this->value ) + 1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 int AtomicInteger::decrementAndGet() {
-    apr_atomic_dec32( &this->value );
-    return this->value;
+    return apr_atomic_dec32( &this->value );
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 int AtomicInteger::addAndGet( int delta ) {
-    apr_atomic_add32( &this->value, delta );
-    return this->value;
+    return apr_atomic_add32( &this->value, delta ) + delta;
 }
 
 ////////////////////////////////////////////////////////////////////////////////

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.cpp?rev=772734&r1=772733&r2=772734&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.cpp Thu May 
7 18:13:00 2009
@@ -21,6 +21,7 @@
 #include <decaf/lang/Thread.h>
 #include <decaf/lang/Runnable.h>
 #include <decaf/lang/exceptions/ClassCastException.h>
+#include <decaf/util/concurrent/CountDownLatch.h>
 
 #include <map>
 #include <string>
@@ -29,6 +30,7 @@
 using namespace decaf;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
+using namespace decaf::util::concurrent;
 
 ////////////////////////////////////////////////////////////////////////////////
 class TestClassBase {
@@ -461,3 +463,103 @@
         ClassCastException );
 
 }
+
+////////////////////////////////////////////////////////////////////////////////
+class Gate {
+private:
+
+    CountDownLatch * enter_latch;
+    CountDownLatch * leave_latch;
+    Mutex mutex;
+    bool closed;
+
+public:
+
+    Gate() : closed( true ) {}
+    virtual ~Gate() {}
+
+    void open( int count ) {
+        leave_latch = new CountDownLatch( count );
+        enter_latch = new CountDownLatch( count );
+        mutex.lock();
+        closed = false;
+        mutex.notifyAll();
+        mutex.unlock();
+    }
+
+    void enter() {
+        mutex.lock();
+        while( closed )
+            mutex.wait();
+        enter_latch->countDown();
+        if( enter_latch->await( 0 ) ) {
+            closed = true;
+        }
+        mutex.unlock();
+    }
+
+    void leave() {
+        leave_latch->countDown();
+    }
+
+    void close() {
+        leave_latch->await();
+        delete leave_latch;
+        delete enter_latch;
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+class PointerTestThread: public Thread {
+private:
+
+    Gate *_gate;
+    Pointer<std::string> _s;
+
+public:
+
+    PointerTestThread( Gate *gate ) : _gate( gate ) {}
+    virtual ~PointerTestThread() {}
+
+    void setString( Pointer<std::string> s ) {
+        _s = s;
+    }
+
+    virtual void run() {
+        for( int j = 0; j < 1000; j++ ) {
+            _gate->enter();
+            _s.reset( NULL );
+            _gate->leave();
+        }
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+void PointerTest::testThreadSafety() {
+
+    Pointer<PointerTestThread> thread[10];
+    Gate gate;
+
+    for( int i = 0; i < 10; i++ ) {
+        thread[i].reset( new PointerTestThread( &gate ) );
+        thread[i]->start();
+    }
+
+    for( int j = 0; j < 1000; j++ ) {
+        // Put this in its own scope so that the main thread frees the string
+        // before the threads.
+        {
+            Pointer<std::string> s( new std::string() );
+            for( int i = 0; i < 10; i++ )
+                thread[i]->setString( s );
+        }
+
+        // Signal the threads to free the string.
+        gate.open( 10 );
+        gate.close();
+    }
+
+    for( int i = 0; i < 10; i++ ) {
+        thread[i]->join();
+    }
+}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.h?rev=772734&r1=772733&r2=772734&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/lang/PointerTest.h Thu May  7
18:13:00 2009
@@ -36,6 +36,7 @@
         CPPUNIT_TEST( testSTLContainers );
         CPPUNIT_TEST( testReturnByValue );
         CPPUNIT_TEST( testDynamicCast );
+        CPPUNIT_TEST( testThreadSafety );
         CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -52,6 +53,7 @@
         void testSTLContainers();
         void testReturnByValue();
         void testDynamicCast();
+        void testThreadSafety();
 
     };
 



Mime
View raw message