searchengine/util/cpixtools/inc/public/cpixsynctools.h
changeset 0 671dee74050a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/searchengine/util/cpixtools/inc/public/cpixsynctools.h	Mon Apr 19 14:40:16 2010 +0300
@@ -0,0 +1,436 @@
+/*
+* 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: 
+*
+*/
+#ifndef CPIXTOOLS_CPIXSYNCTOOLS_H_
+#define CPIXTOOLS_CPIXSYNCTOOLS_H_
+
+#include <pthread.h>
+
+#include <exception>
+#include <new>
+#include <string>
+
+namespace Cpt
+{
+
+    /**
+     * Class to signal sync related error conditions.
+     */
+    class SyncExc : public std::exception
+    {
+        //
+        // private members
+        //
+        std::string     what_;
+
+    public:
+        //
+        // public operators
+        //
+
+        /**
+         * Overriden from std::exception
+         */
+        virtual const char * what() const throw();
+
+
+        //
+        // Lifecycle management
+        //
+
+        /**
+         * Constructs this exception with printf style format string
+         * and potential detail arguments.
+         */
+        SyncExc(const char * format,
+                ...);
+    };
+
+
+
+    // private namespace
+    namespace Impl
+    {
+
+        /**
+         * A simple structure to store information necessary for
+         * recursive locking.
+         */
+        struct Recursive
+        {
+            pthread_t           lockOwner_;
+            size_t              lockCount_;
+        };
+
+
+
+        /**
+         * To protect regions with a mutex. Just construct it giving it a
+         * valid mutex. On construction, it locks it and on destruction it
+         * unlocks it. Lower level locking primitive class.
+         */
+        class SyncRegion_
+        {
+        private:
+            //
+            // private members
+            //
+            pthread_mutex_t     * mutex_;
+            Recursive           * recursive_;
+
+            // preventing C++ value semantics - declared but not defined
+            SyncRegion_(const SyncRegion_ &);
+
+            // preventing C++ value semantics - declared but not defined
+            SyncRegion_ & operator=(const SyncRegion_ &);
+        
+
+        public:
+            //
+            // public operations
+            //
+
+            /**
+             * Locks the given mutex. Not advised to use directly, as
+             * unlocking must be guaranteed then by the client. Use
+             * class SyncRegion RAII instead.
+             *
+             * @param mutex the mutex to lock.
+             */
+            static void lockMutex(pthread_mutex_t * mutex);
+
+
+            /**
+             * Recursively locks a mutex (manual implementation). Must
+             * also use the recursive unlock() in pair.
+             */
+            static void lockMutex(pthread_mutex_t * mutex,
+                                  Recursive       * recursive);
+
+
+            /**
+             * Unlocks the given mutex. Not advised to use directly.
+             *
+             * @param mutex the mutex to unlock
+             */
+            static void unlockMutex(pthread_mutex_t * mutex);
+
+
+            /**
+             * Unlocks the mutex recursively (manual
+             * implementation). Must be used for a mutex that was
+             * recursively locked.
+             */
+            static void unlockMutex(pthread_mutex_t * mutex,
+                                    Recursive       * recursive);
+
+
+            /**
+             * Initialized the mutex.
+             *
+             * @param mutex - pointer to the mutex struct to
+             * initialize
+             */
+            static void initMutex(pthread_mutex_t * mutex);
+
+            /**
+             * Destroys the given mutex.
+             *
+             * @param mutex the mutex to destroy.
+             */
+            static void destroyMutex(pthread_mutex_t * mutex);
+
+
+            /**
+             * Constructs this "sentry", locking the given mutex.
+             */
+            SyncRegion_(pthread_mutex_t * mutex);
+
+
+            /**
+             * Constructs this "sentry", recursively locking the given
+             * mutex.
+             */
+            SyncRegion_(pthread_mutex_t * mutex,
+                        Recursive       * recursive);
+
+
+            /**
+             * Destructs this "sentry", unlocking the mutex.
+             */
+            ~SyncRegion_();
+        }; // class
+       
+    } // namespace 
+
+
+
+    /**
+     * A class that can be used for locking. Implemented with pthread
+     * mutex. It does not have any operations on its own (beside
+     * construction and destruction), one must use SyncRegion to
+     * lock/unlock it.
+     */
+    class Mutex
+    {
+    protected:
+        //
+        // protected members
+        //
+        pthread_mutex_t         mutex_;
+
+
+    private:
+        //
+        // private members
+        //
+
+        // preventing C++ value semantics - declared but not defined
+        Mutex(const Mutex &);
+        
+        // preventing C++ value semantics - declared but not defined
+        Mutex & operator=(const Mutex &);
+
+        Impl::Recursive       * recursive_;
+        
+
+    public:
+        //
+        // public operators
+        //
+
+        //
+        // lifetime management
+        //
+        /**
+         * Constructs this mutex (initializes pthread mutex) - non
+         * recursive.
+         */
+        Mutex();
+
+
+        /**
+         * Constructs this mutex (initializes pthread mutex).
+         *
+         * @param whether to allow recursive locking.
+         */
+        Mutex(bool recursive);
+
+
+        /**
+         * Destroys this mutex (destroys pthread mutex). The pthread
+         * mutex is acquired before destroying.
+         */
+        ~Mutex();
+
+
+        /**
+         * One uses SyncRegion to lock this mutex.
+         */
+        friend class SyncRegion;
+
+
+    private:
+        //
+        // private
+        //
+        void init(bool recursive);
+
+        friend class SyncRegion;
+    };
+
+
+
+    /**
+     * A base class for any class that needs synchronization
+     * primitives.
+     */
+    class SyncEntity : public Mutex
+    {
+    private:
+        //
+        // private members
+        //
+        pthread_cond_t       cond_;
+
+        // preventing C++ value semantics - declared but not defined
+        SyncEntity(const SyncEntity &);
+
+        // preventing C++ value semantics - declared but not defined
+        SyncEntity & operator=(const SyncEntity &);
+
+    public:
+        //
+        // public operators
+        //
+
+        /**
+         * Wait on this object (cond_ and mutex_).
+         */
+        void wait();
+
+
+        /**
+         * Signal a thread waiting on this object.
+         */
+        void signal();
+
+
+        /**
+         * Broadcasts (signals) to all waiting threads on this object.
+         */
+        void broadcast();
+
+
+        //
+        // lifetime management
+        //
+        /**
+         * Constructor
+         */
+        SyncEntity();
+
+
+        /**
+         * Destructor. The pthread mutex of this synchronized entity is
+         * acquired before destroying it.
+         */
+        virtual ~SyncEntity();
+
+
+        /**
+         * One uses SyncRegion to lock this synchronized entity.
+         */
+        friend class SyncRegion;
+    };
+    
+
+
+    /**
+     * A class to use confortably to lock on SyncEntities.
+     */
+    class SyncRegion : private Impl::SyncRegion_
+    {
+    private:
+        //
+        // private members
+        //
+
+    public:
+        //
+        // public operations
+        //
+
+        /**
+         * Constructor - locks the mutex.
+         */
+        SyncRegion(Mutex & mutex);
+
+
+        /**
+         * Constructor - locks the mutex of the target entity.
+         */
+        SyncRegion(SyncEntity & entity);
+
+
+        /**
+         * Destructor - unlocks the mutex of the target entity.
+         */
+        ~SyncRegion();
+    };
+    
+
+
+    /**
+     * A class that can lock multiple mutexes and release them all at
+     * its destruction (in the reverse order of their locking).
+     */
+    class MultiSyncRegion
+    {
+    private:
+        //
+        // private members
+        //
+        /**
+         * Maximum number of SyncRegion_ instances managed here
+         */
+        size_t              maxSize_;
+
+        /**
+         * Array of SyncRegion_ size bytes of maxSize.
+         */
+        SyncRegion        * syncers_;
+
+        /**
+         * Pointer to the next empty (unconstructed) SyncRegion_ slot.
+         */
+        SyncRegion        * next_;
+
+
+
+    public:
+        //
+        // public operators
+        //
+        /**
+         * Locks the given mutex (adds it to the number of
+         * mutexes/sync entities already locked by this).
+         */
+        void lock(Mutex & mutex);
+
+
+        /**
+         * Locks the given syncEntity (adds it to the number of
+         * mutexes/sync entities already locked by this).
+         */
+        void lock(SyncEntity & syncEntity);
+
+
+        //
+        // lifetime management
+        //
+        /**
+         * Constructor - creates a MultiSyncRegion that can lock up to
+         * a certain number of mutexes.
+         *
+         * @param maxSize maximal number of mutexes this
+         * MultiSyncRegion will be able to lock.
+         */
+        MultiSyncRegion(size_t maxSize);
+
+
+        /**
+         * Destructor - releases all the locks (if any) on any mutexes
+         * that have been locked by this instance.
+         */
+        ~MultiSyncRegion();
+
+
+    private:
+        /**
+         * Checks if this MultiSyncRegion instance has filled up its
+         * array pointed by syncers_, and if so, throws an exception.
+         */
+        void throwIfFull();
+    };
+
+
+
+
+} // namespace
+
+
+#endif CPIXTOOLS_CPIXSYNCTOOLS_H_