smart_mutex.h

Go to the documentation of this file.
00001 /*
00002  * smart_mutex.h
00003  *
00004  * Copyright (C) 2007  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * Simple smart mutex object.
00032  */
00033 
00034 #ifndef WAVEPACKET_THREADSAFE_SMART_MUTEX_H__
00035 #define WAVEPACKET_THREADSAFE_SMART_MUTEX_H__
00036 
00037 // includes --------------------------------------------------------------------
00038 #include "common/common.h"
00039 
00040 #include <pthread.h>
00041 
00042 /// \ingroup threading
00043 /*@{*/
00044 
00045 /// \defgroup threadsafe Threadsafe Collection API
00046 ///
00047 /// A set of objects and collection for threadsafe C++ code.
00048 /// Assumes use of the posix pthreads libraries.
00049 /*@{*/
00050 
00051 
00052 /// class that automatically creates and destroys pthread mutexes
00053 class smart_mutex {
00054 public:
00055         /// constructor will automatically create pthread mutex
00056         smart_mutex(void) {
00057                         ASSERT(!pthread_mutex_init(&m_mutex, NULL),
00058                             "Failed to initialize mutex");
00059                 }
00060 
00061         /// destructor will automatically destroy pthread mutex
00062         ~smart_mutex(void) {
00063                         pthread_mutex_destroy(&m_mutex);
00064                 }
00065 
00066         /// accessor to retrieve pthread mutex object
00067         pthread_mutex_t * getMutex(void) {
00068                         return &m_mutex;
00069                 }
00070 
00071 private:
00072         // private member data
00073         pthread_mutex_t         m_mutex;
00074 };
00075 
00076 
00077 
00078 /// class that automatically locks and unlocks pthread mutexes
00079 /// To use mlocks in code:
00080 ///   - create a mutex (or smart_mutex) that will be locked
00081 ///   - create an mlock object and pass the mutex in the constructor
00082 ///   - on destruction, the mlock will automatically unlock the mutex
00083 ///
00084 /// Example:
00085 ///\code
00086 ///     void threadsafeFunction(void)
00087 ///     {
00088 ///             smart_mutex my_mutex;
00089 ///
00090 ///             mlock lock(my_mutex);   // blocks until mutex is acquired
00091 ///
00092 ///             // some stuff that needs to be protected happens here
00093 ///             ...
00094 ///
00095 ///     }  <--- mutex is unlocked here as mlock destructor is called
00096 ///\endcode
00097 class mlock {
00098 public:
00099         /// constructor that accepts smart_mutex
00100         mlock(IN smart_mutex& sm) {
00101                         this->lock(sm.getMutex());
00102                 }
00103 
00104         /// constructor that accepts pthread mutex
00105         mlock(IN pthread_mutex_t * pm) {
00106                         this->lock(pm);
00107                 }
00108 
00109         /// destructor automatically unlocks
00110         ~mlock(void) {
00111                         pthread_mutex_unlock(m_pm);
00112                 }
00113 
00114 private:
00115         // private helper methods
00116         mlock(void);
00117         mlock(IN const mlock&);
00118         void lock(IN pthread_mutex_t * pm) {
00119                         ASSERT(pm, "null mutex?");
00120                         m_pm = pm;
00121                         pthread_mutex_lock(pm);
00122                 }
00123 
00124         // private member data -------------------------------------------------
00125         pthread_mutex_t *       m_pm;
00126 };
00127 
00128 
00129 
00130 #endif  // WAVEPACKET_THREADSAFE_SMART_MUTEX_H__
00131