You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2007/10/03 06:25:39 UTC

svn commit: r581488 - /logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp

Author: carnold
Date: Tue Oct  2 21:25:39 2007
New Revision: 581488

URL: http://svn.apache.org/viewvc?rev=581488&view=rev
Log:
LOGCXX-175: APRCharsetEncoder threading test

Modified:
    logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp

Modified: logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp
URL: http://svn.apache.org/viewvc/logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp?rev=581488&r1=581487&r2=581488&view=diff
==============================================================================
--- logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp (original)
+++ logging/log4cxx/trunk/src/test/cpp/helpers/charsetencodertestcase.cpp Tue Oct  2 21:25:39 2007
@@ -21,16 +21,22 @@
 #include <log4cxx/helpers/charsetencoder.h>
 #include "../insertwide.h"
 #include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/thread.h>
+#include <log4cxx/helpers/mutex.h>
+#include <log4cxx/helpers/condition.h>
+#include <log4cxx/helpers/synchronized.h>
+#include <apr.h>
+#include <apr_atomic.h>
+
 
 using namespace log4cxx;
 using namespace log4cxx::helpers;
 
-#define APR_SUCCESS ((log4cxx_status_t) 0)
-
 
 class CharsetEncoderTestCase : public CppUnit::TestFixture
 {
         CPPUNIT_TEST_SUITE(CharsetEncoderTestCase);
+                CPPUNIT_TEST(thread1);
                 CPPUNIT_TEST(encode1);
                 CPPUNIT_TEST(encode2);
                 CPPUNIT_TEST(encode3);
@@ -165,7 +171,128 @@
           }
           CPPUNIT_ASSERT(iter == greeting.end());
         }
+        
+        class ThreadPackage {
+        public:
+            ThreadPackage(CharsetEncoderPtr& enc, int repetitions) : 
+                p(), lock(p), condition(p), passCount(0), failCount(0), enc(enc), repetitions(repetitions) {
+            }
+            
+            void await() {
+                synchronized sync(lock);
+                condition.await(lock);
+            }
+            
+            void signalAll() {
+                synchronized sync(lock);
+                condition.signalAll();
+            }
+            
+            void fail() {
+                apr_atomic_inc32(&failCount);
+            }
+            
+            void pass() {
+                apr_atomic_inc32(&passCount);
+            }
+            
+            apr_uint32_t getFail() {
+               return apr_atomic_read32(&failCount);
+            }
+            
+            apr_uint32_t getPass() {
+               return apr_atomic_read32(&passCount);
+            }
+            
+            int getRepetitions() {
+                return repetitions;
+            }
+            
+            CharsetEncoderPtr& getEncoder() {
+               return enc;
+            }
+            
+        private:
+            ThreadPackage(const ThreadPackage&);
+            ThreadPackage& operator=(ThreadPackage&);
+            Pool p;
+            Mutex lock;
+            Condition condition;
+            volatile apr_uint32_t passCount;
+            volatile apr_uint32_t failCount; 
+            CharsetEncoderPtr enc;
+            int repetitions;
+        };
+        
+        static void* LOG4CXX_THREAD_FUNC thread1Action(log4cxx_thread_t* thread, void* data) {
+            ThreadPackage* package = (ThreadPackage*) data;
+            const char utf8_greet[] = { 'A',
+                                    (char) 0xD8, (char) 0x85,
+                                    (char) 0xD4, (char) 0xB0,
+                                    (char) 0xE0, (char) 0xA6, (char) 0x86,
+                                    (char) 0xE4, (char) 0xB8, (char) 0x83,
+                                    (char) 0xD0, (char) 0x80,
+                                    0 };
+#if LOG4CXX_LOGCHAR_IS_WCHAR
+            //   arbitrary, hopefully meaningless, characters from
+            //     Latin, Arabic, Armenian, Bengali, CJK and Cyrillic
+            const logchar greet[] = { L'A', 0x0605, 0x0530, 0x986, 0x4E03, 0x400, 0 };
+#endif
+
+#if LOG4CXX_LOGCHAR_IS_UTF8
+            const logchar *greet = utf8_greet;
+#endif
+          LogString greeting(greet);
+
+          package->await();
+          for(int i = 0; i < package->getRepetitions(); i++) {
+            bool pass = true;
+            char buf[BUFSIZE];
+            ByteBuffer out(buf, BUFSIZE);
+            LogString::const_iterator iter = greeting.begin();
+            log4cxx_status_t stat = package->getEncoder()->encode(greeting, iter, out);
+            pass = (false == CharsetEncoder::isError(stat));
+            if (pass) {
+                stat = package->getEncoder()->encode(greeting, iter, out);
+                pass = (false == CharsetEncoder::isError(stat));
+                if (pass) {
+                    out.flip();
+                    pass = (13 == out.limit());
+                    for(size_t i = 0; i < out.limit() && pass; i++) {
+                        pass = (utf8_greet[i] == out.data()[i]);
+                    }
+                    pass = pass && (iter == greeting.end());
+                }
+            }
+            if (pass) {
+                package->pass();
+            } else {
+                package->fail();
+            }
+          }
+            return 0;
+        }
 
+        void thread1() {
+              enum { THREAD_COUNT = 10, THREAD_REPS = 10000 };
+              Thread threads[THREAD_COUNT];
+              CharsetEncoderPtr enc(CharsetEncoder::getEncoder(LOG4CXX_STR("ISO-8859-1")));
+              ThreadPackage* package = new ThreadPackage(enc, THREAD_REPS);
+              for(int i = 0; i < THREAD_COUNT; i++) {
+                  threads[i].run(thread1Action, package);
+              }
+              //
+              //   give time for all threads to be launched so
+              //      we don't signal before everybody is waiting.
+              Thread::sleep(100);
+              package->signalAll();
+              for(int i = 0; i < THREAD_COUNT; i++) {
+                  threads[i].join();
+              }
+              CPPUNIT_ASSERT_EQUAL((apr_uint32_t) 0, package->getFail());
+              CPPUNIT_ASSERT_EQUAL((apr_uint32_t) THREAD_COUNT * THREAD_REPS, package->getPass());
+              delete package;
+        }
 
 
 };