searchengine/util/tsrc/cpixtoolsunittest/src/mutextest.cpp
changeset 0 671dee74050a
child 8 6547bf8ca13a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/searchengine/util/tsrc/cpixtoolsunittest/src/mutextest.cpp	Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+#include <unistd.h>
+
+#include <memory>
+#include <string.h>
+
+#include "itk.h"
+
+#include "cpixsynctools.h"
+
+
+void testMutex(Itk::TestMgr * )
+{
+    using namespace Cpt;
+
+    Mutex
+        mutex;
+
+    SyncRegion
+        sr(mutex);
+}
+
+
+void testRecursiveMutex(Itk::TestMgr * )
+{
+    using namespace Cpt;
+
+    Mutex
+        mutex(true);
+
+    SyncRegion
+        sr1(mutex);
+
+    SyncRegion
+        sr2(mutex);
+}
+
+
+void testMultiSyncRegion(Itk::TestMgr * )
+{
+    using namespace Cpt;
+
+    Mutex
+        mutex1,
+        mutex2(true),
+        mutex3;
+
+    {
+        MultiSyncRegion
+            msr(4);
+        
+        msr.lock(mutex1);
+        msr.lock(mutex2);
+        msr.lock(mutex3);
+        msr.lock(mutex2);
+    }
+
+    SyncRegion
+        sr(mutex1);
+
+    SyncRegion
+        sr1(mutex2);
+
+    SyncRegion
+        sr2(mutex3);
+}
+
+
+void testSyncExc(Itk::TestMgr * mgr)
+{
+    pthread_mutex_t
+        mutex;
+
+    // kept uninitialized on purpose!
+
+    try
+        {
+            Cpt::Impl::SyncRegion_::lockMutex(&mutex);
+
+            ITK_EXPECT(mgr,
+                       false,
+                       "Locking uninitalized mutex should have failed");
+        }
+    catch (std::exception & exc)
+        {
+            printf("Locking unitialized mutex have failed (as should): %s\n",
+                   exc.what());
+        }
+
+    try
+        {
+            Cpt::Impl::SyncRegion_::unlockMutex(&mutex);
+
+            ITK_EXPECT(mgr,
+                       false,
+                       "Unlocking uninitalized mutex should have failed");
+        }
+    catch (std::exception & exc)
+        {
+            printf("Unlocking unitialized mutex have failed (as should): %s\n",
+                   exc.what());
+        }
+
+    Cpt::Impl::SyncRegion_::initMutex(&mutex);
+
+    try
+        {
+            Cpt::Impl::SyncRegion_::unlockMutex(&mutex);
+
+            // TODO this should be ITK_EXPECT - why does NOT it fail?
+            printf("Unlocking initialized but non-locked mutex should have failed\n");
+        }
+    catch (std::exception & exc)
+        {
+            printf("Unlocking initialized but non-locked mutex have failed (as should): %s\n",
+                   exc.what());
+        }
+
+    try
+        {
+            {
+                Cpt::Impl::SyncRegion_
+                    sr(&mutex);
+            }
+
+            printf("Locked and unlocked mutex");
+        }
+    catch (std::exception & exc)
+        {
+            ITK_EXPECT(mgr,
+                       false,
+                       "Failed to lock and unlock mutex: %s",
+                       exc.what());
+        }
+
+    Cpt::Impl::SyncRegion_::destroyMutex(&mutex);
+}
+
+
+/**
+ * Test "SyncExc2" tries to create a situation where a thread that
+ * does not own the lock tries to unlock the mutex (should fail).
+ */
+struct StupidUnlock
+{
+    pthread_mutex_t    * mutex_;
+    Itk::TestMgr       * mgr_;
+};
+
+
+void * StupidThreadFunc(void * param)
+{
+    printf("# SyncExc2 / StupidThread BEGIN.\n");
+
+    StupidUnlock
+        * p = reinterpret_cast<StupidUnlock*>(param);
+
+    try
+        {
+            Cpt::Impl::SyncRegion_::unlockMutex(p->mutex_);
+
+            // TODO this should be ITK_EXPECT - why does NOT it fail?
+            printf("# Unlocking mutex that is locked by another thread should fail (imho) - but it succeeds on both winscw and arm.\n");
+        }
+    catch (std::exception & exc)
+        {
+            printf("# Unlocking mutex owned by another thread have failed (as should): %s\n",
+                   exc.what());
+        }
+    
+    printf("# SyncExc2 / StupidThread END.\n");
+
+    return NULL;
+}
+
+
+void testSyncExc2(Itk::TestMgr * mgr)
+{
+    pthread_mutex_t
+        mutex;
+
+    Cpt::Impl::SyncRegion_::initMutex(&mutex);
+
+    {
+        Cpt::Impl::SyncRegion_
+            sr(&mutex);
+
+        // here we create a thread that will try to unlock the mutex
+        // held by this thread - it should fail
+        StupidUnlock
+            stupidUnlock = {
+            &mutex,
+            mgr
+        };
+        
+        pthread_t
+            stupidThread;
+        
+        int
+            result = pthread_create(&stupidThread,
+                                    NULL,
+                                    &StupidThreadFunc,
+                                    &stupidUnlock);
+        
+        ITK_ASSERT(mgr,
+                   result == 0,
+                   "Could not start stupid thread: %d",
+                   result);
+        
+        printf("Sleep(1) ...\n");
+
+        sleep(1);
+        
+        printf("... awake(1)\n");
+
+        result = pthread_join(stupidThread,
+                              NULL);
+        
+        printf("has joined stupid thread, unlocking mutex\n");
+    }
+
+    Cpt::Impl::SyncRegion_::destroyMutex(&mutex);
+
+    printf("SyncExc2 test done.\n");
+}
+
+
+
+Itk::TesterBase * CreateMutexTests()
+{
+    using namespace Itk;
+
+    SuiteTester
+        * mutexTests = new SuiteTester("mutex");
+
+#define TEST "mutex"
+    mutexTests->add(TEST,
+                    testMutex);
+#undef TEST
+
+#define TEST "recursivemutex"
+    mutexTests->add(TEST,
+                    testRecursiveMutex);
+#undef TEST
+
+#define TEST "multisyncregion"
+    mutexTests->add(TEST,
+                    testMultiSyncRegion);
+#undef TEST
+
+#define TEST "syncexc"
+    mutexTests->add(TEST,
+                    testSyncExc,
+                    TEST);
+#undef TEST
+
+#define TEST "syncexc2"
+    mutexTests->add(TEST,
+                    testSyncExc2,
+                    TEST);
+#undef TEST
+
+
+    // ... add more tests to suite
+    
+    return mutexTests;
+    
+}