activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r991550 - in /activemq/activemq-cpp/trunk/activemq-cpp/src: main/activemq/library/ActiveMQCPP.cpp main/activemq/util/IdGenerator.cpp main/activemq/util/IdGenerator.h test/activemq/util/IdGeneratorTest.cpp test/activemq/util/IdGeneratorTest.h
Date Wed, 01 Sep 2010 14:28:18 GMT
Author: tabish
Date: Wed Sep  1 14:28:18 2010
New Revision: 991550

URL: http://svn.apache.org/viewvc?rev=991550&view=rev
Log:
fix for: https://issues.apache.org/activemq/browse/AMQCPP-314

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/library/ActiveMQCPP.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.h

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/library/ActiveMQCPP.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/library/ActiveMQCPP.cpp?rev=991550&r1=991549&r2=991550&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/library/ActiveMQCPP.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/library/ActiveMQCPP.cpp Wed
Sep  1 14:28:18 2010
@@ -21,6 +21,8 @@
 #include <activemq/wireformat/WireFormatRegistry.h>
 #include <activemq/transport/TransportRegistry.h>
 
+#include <activemq/util/IdGenerator.h>
+
 #include <activemq/wireformat/stomp/StompWireFormatFactory.h>
 #include <activemq/wireformat/openwire/OpenWireFormatFactory.h>
 
@@ -31,6 +33,7 @@
 
 using namespace activemq;
 using namespace activemq::library;
+using namespace activemq::util;
 using namespace activemq::transport;
 using namespace activemq::transport::tcp;
 using namespace activemq::transport::mock;
@@ -48,6 +51,9 @@ void ActiveMQCPP::initializeLibrary( int
 
     // Register all Transports
     ActiveMQCPP::registerTransports();
+
+    // Start the IdGenerator Kernel
+    IdGenerator::initialize();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -57,6 +63,11 @@ void ActiveMQCPP::initializeLibrary() {
 
 ////////////////////////////////////////////////////////////////////////////////
 void ActiveMQCPP::shutdownLibrary() {
+
+    // Shutdown the IdGenerator Kernel
+    IdGenerator::initialize();
+
+    // Now it should be safe to shutdown Decaf.
     decaf::lang::Runtime::shutdownRuntime();
 }
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.cpp?rev=991550&r1=991549&r2=991550&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.cpp Wed Sep
 1 14:28:18 2010
@@ -22,6 +22,9 @@
 #include <decaf/lang/Thread.h>
 #include <decaf/net/InetAddress.h>
 #include <decaf/net/ServerSocket.h>
+#include <decaf/util/concurrent/Mutex.h>
+
+#include <decaf/lang/exceptions/RuntimeException.h>
 
 #include <apr_strings.h>
 
@@ -29,29 +32,46 @@ using namespace activemq;
 using namespace activemq::util;
 using namespace decaf;
 using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
 using namespace decaf::net;
 using namespace decaf::util;
 using namespace decaf::util::concurrent;
 
 ////////////////////////////////////////////////////////////////////////////////
-IdGenerator::StaticData::StaticData() : UNIQUE_STUB(), instanceCount(0), hostname() {
+IdGeneratorKernel* IdGenerator::kernel = NULL;
 
-    std::string stub = "";
+////////////////////////////////////////////////////////////////////////////////
+namespace activemq {
+namespace util {
 
-    try {
-        hostname = InetAddress::getLocalHost().getHostName();
-        ServerSocket ss( 0 );
-        stub = "-" + Long::toString( ss.getLocalPort() ) + "-" +
-                     Long::toString( System::currentTimeMillis() ) + "-";
-        Thread::sleep( 100 );
-        ss.close();
-    } catch( Exception& ioe ) {
-        hostname = "localhost";
-        stub = "-1-" + Long::toString( System::currentTimeMillis() ) + "-";
-    }
+    class IdGeneratorKernel {
+    public:
 
-    UNIQUE_STUB = stub;
-}
+        std::string UNIQUE_STUB;
+        int instanceCount;
+        std::string hostname;
+        mutable decaf::util::concurrent::Mutex mutex;
+
+        IdGeneratorKernel() : UNIQUE_STUB(), instanceCount(0), hostname() {
+
+            std::string stub = "";
+
+            try {
+                hostname = InetAddress::getLocalHost().getHostName();
+                ServerSocket ss( 0 );
+                stub = "-" + Long::toString( ss.getLocalPort() ) + "-" +
+                             Long::toString( System::currentTimeMillis() ) + "-";
+                Thread::sleep( 100 );
+                ss.close();
+            } catch( Exception& ioe ) {
+                hostname = "localhost";
+                stub = "-1-" + Long::toString( System::currentTimeMillis() ) + "-";
+            }
+
+            UNIQUE_STUB = stub;
+        }
+    };
+}}
 
 ////////////////////////////////////////////////////////////////////////////////
 IdGenerator::IdGenerator() : prefix(), seed(), sequence(0) {
@@ -70,17 +90,21 @@ std::string IdGenerator::generateId() co
 
     std::string result;
 
-    StaticData& statics = IdGenerator::getClassStaticData();
+    if( IdGenerator::kernel == NULL ) {
+        throw RuntimeException( __FILE__, __LINE__, "Library is not initialized." );
+    }
 
-    synchronized( &statics.mutex ) {
+    synchronized( &( IdGenerator::kernel->mutex ) ) {
 
         if( seed.empty() ) {
 
             if( prefix.empty() ) {
-                this->seed = std::string( "ID:" ) + statics.hostname +
-                             statics.UNIQUE_STUB + Long::toString( statics.instanceCount++
) + ":";
+                this->seed = std::string( "ID:" ) + IdGenerator::kernel->hostname +
+                             IdGenerator::kernel->UNIQUE_STUB +
+                             Long::toString( IdGenerator::kernel->instanceCount++ ) +
":";
             } else {
-                this->seed = prefix + statics.UNIQUE_STUB + Long::toString( statics.instanceCount++
) + ":";
+                this->seed = prefix + IdGenerator::kernel->UNIQUE_STUB +
+                             Long::toString( IdGenerator::kernel->instanceCount++ ) +
":";
             }
         }
 
@@ -143,7 +167,11 @@ int IdGenerator::compare( const std::str
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-IdGenerator::StaticData& IdGenerator::getClassStaticData() {
-    static IdGenerator::StaticData statics;
-    return statics;
+void IdGenerator::initialize() {
+    IdGenerator::kernel = new IdGeneratorKernel();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void IdGenerator::shutdown() {
+    delete IdGenerator::kernel;
 }

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.h?rev=991550&r1=991549&r2=991550&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/IdGenerator.h Wed Sep
 1 14:28:18 2010
@@ -20,30 +20,25 @@
 
 #include <activemq/util/Config.h>
 
-#include <decaf/util/concurrent/Mutex.h>
 #include <string>
 
 namespace activemq {
+namespace library {
+    class ActiveMQCPP;
+}
 namespace util {
 
+    class IdGeneratorKernel;
+
     class AMQCPP_API IdGenerator {
     private:
 
-        class StaticData {
-        public:
-
-            std::string UNIQUE_STUB;
-            int instanceCount;
-            std::string hostname;
-            mutable decaf::util::concurrent::Mutex mutex;
-
-            StaticData();
-        };
-
         std::string prefix;
         mutable std::string seed;
         mutable long long sequence;
 
+        static IdGeneratorKernel* kernel;
+
     public:
 
         IdGenerator();
@@ -97,8 +92,10 @@ namespace util {
 
     private:
 
-        static StaticData& getClassStaticData();
+        static void initialize();
+        static void shutdown();
 
+        friend class activemq::library::ActiveMQCPP;
     };
 
 }}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.cpp?rev=991550&r1=991549&r2=991550&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.cpp Wed
Sep  1 14:28:18 2010
@@ -19,9 +19,47 @@
 
 #include <activemq/util/IdGenerator.h>
 
+#include <decaf/lang/Thread.h>
+
 using namespace activemq;
 using namespace activemq::util;
 
+using namespace decaf;
+using namespace decaf::lang;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class CreateIdThread : public Thread {
+    public:
+
+        virtual void run() {
+
+            IdGenerator idGen;
+
+            CPPUNIT_ASSERT( idGen.generateId() != "" );
+            CPPUNIT_ASSERT( idGen.generateId() != "" );
+
+            std::string id1 = idGen.generateId();
+            std::string id2 = idGen.generateId();
+
+            CPPUNIT_ASSERT( id1 != id2 );
+
+            std::size_t idPos = id1.find("ID:");
+
+            CPPUNIT_ASSERT( idPos == 0 );
+
+            std::size_t firstColon = id1.find(':');
+            std::size_t lastColon = id1.rfind(':');
+
+            CPPUNIT_ASSERT( firstColon != lastColon );
+            CPPUNIT_ASSERT( ( lastColon - firstColon ) > 1 );
+        }
+
+    };
+
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 IdGeneratorTest::IdGeneratorTest() {
 }
@@ -77,3 +115,27 @@ void IdGeneratorTest::testCompare() {
     CPPUNIT_ASSERT( IdGenerator::compare( id1, id2 ) < 0 );
     CPPUNIT_ASSERT( IdGenerator::compare( id2, id1 ) > 0 );
 }
+
+////////////////////////////////////////////////////////////////////////////////
+void IdGeneratorTest::testThreadSafety() {
+
+    static const int COUNT = 50;
+
+    std::vector<CreateIdThread*> threads;
+
+    for( int i = 0; i < COUNT; i++ ) {
+        threads.push_back( new CreateIdThread );
+    }
+
+    for( int i = 0; i < COUNT; i++ ) {
+        threads[i]->start();
+    }
+
+    for( int i = 0; i < COUNT; i++ ) {
+        threads[i]->join();
+    }
+
+    for( int i = 0; i < COUNT; i++ ) {
+        delete threads[i];
+    }
+}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.h?rev=991550&r1=991549&r2=991550&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/activemq/util/IdGeneratorTest.h Wed
Sep  1 14:28:18 2010
@@ -30,6 +30,7 @@ namespace util {
         CPPUNIT_TEST( testConstructor1 );
         CPPUNIT_TEST( testConstructor2 );
         CPPUNIT_TEST( testCompare );
+        CPPUNIT_TEST( testThreadSafety );
         CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -40,6 +41,7 @@ namespace util {
         void testConstructor1();
         void testConstructor2();
         void testCompare();
+        void testThreadSafety();
 
     };
 



Mime
View raw message