STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

winstl_spin_mutex.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_spin_mutex.h (originally MWSpinMx.h, ::SynesisWin)
00003  *
00004  * Purpose:     Intra-process mutex, based on spin waits.
00005  *
00006  * Date:        27th August 1997
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef WINSTL_INCL_H_WINSTL_SPIN_MUTEX
00046 #define WINSTL_INCL_H_WINSTL_SPIN_MUTEX
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define WINSTL_VER_H_WINSTL_SPIN_MUTEX_MAJOR       2
00050 # define WINSTL_VER_H_WINSTL_SPIN_MUTEX_MINOR       0
00051 # define WINSTL_VER_H_WINSTL_SPIN_MUTEX_REVISION    1
00052 # define WINSTL_VER_H_WINSTL_SPIN_MUTEX_EDIT        23
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef WINSTL_INCL_H_WINSTL
00060 # include "winstl.h"                    // Include the WinSTL root header
00061 #endif /* !WINSTL_INCL_H_WINSTL */
00062 
00063 /* 
00064  * Namespace
00065  */
00066 
00067 #ifndef _WINSTL_NO_NAMESPACE
00068 # if defined(_STLSOFT_NO_NAMESPACE) || \
00069      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00070 /* There is no stlsoft namespace, so must define ::winstl */
00071 namespace winstl
00072 {
00073 # else
00074 /* Define stlsoft::winstl_project */
00075 
00076 namespace stlsoft
00077 {
00078 
00079 namespace winstl_project
00080 {
00081 
00082 # endif /* _STLSOFT_NO_NAMESPACE */
00083 #endif /* !_WINSTL_NO_NAMESPACE */
00084 
00085 /* 
00086  * Classes
00087  */
00088 
00089 // class spin_mutex
00091 class spin_mutex
00092 {
00093 public:
00094     typedef spin_mutex class_type;
00095 
00096 // Construction
00097 public:
00099     ss_explicit_k spin_mutex(ws_sint32_t *p = NULL) winstl_throw_0()
00100         : m_spinCount((NULL != p) ? p : &m_internalCount)
00101         , m_internalCount(0)
00102 #ifdef STLSOFT_SPINMUTEX_COUNT_LOCKS
00103         , m_cLocks(0)
00104 #endif // STLSOFT_SPINMUTEX_COUNT_LOCKS
00105     {}
00107     ~spin_mutex() winstl_throw_0()
00108     {
00109 #ifdef STLSOFT_SPINMUTEX_COUNT_LOCKS
00110         stlsoft_assert(m_cLocks == 0);
00111 #endif // STLSOFT_SPINMUTEX_COUNT_LOCKS
00112     }
00113 
00114 // Operations
00115 public:
00117     void lock() winstl_throw_0()
00118     {
00119         for(; 0 != ::InterlockedExchange((LPLONG)m_spinCount, 1); ::Sleep(1))
00120         {}
00121 #ifdef STLSOFT_SPINMUTEX_COUNT_LOCKS
00122         stlsoft_assert(++m_cLocks != 0);
00123 #endif // STLSOFT_SPINMUTEX_COUNT_LOCKS
00124     }
00126     void unlock() winstl_throw_0()
00127     {
00128 #ifdef STLSOFT_SPINMUTEX_COUNT_LOCKS
00129         stlsoft_assert(m_cLocks-- != 0);
00130 #endif // STLSOFT_SPINMUTEX_COUNT_LOCKS
00131         (void)::InterlockedExchange((LPLONG)m_spinCount, 0);
00132     }
00133 
00134 // Members
00135 private:
00136     ws_sint32_t     *m_spinCount;
00137     ws_sint32_t     m_internalCount;
00138 #ifdef STLSOFT_SPINMUTEX_COUNT_LOCKS
00139     ws_sint32_t     m_cLocks;       // Used as check on matched Lock/Unlock calls
00140 #endif // STLSOFT_SPINMUTEX_COUNT_LOCKS
00141 
00142 // Not to be implemented
00143 private:
00144     spin_mutex(class_type const &rhs);
00145     spin_mutex &operator =(class_type const &rhs);
00146 };
00147 
00148 /* 
00149  * Control shims
00150  */
00151 
00152 #ifndef _WINSTL_NO_NAMESPACE
00153 # if defined(_STLSOFT_NO_NAMESPACE) || \
00154      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00155 } // namespace winstl
00156 # else
00157 } // namespace winstl_project
00158 # endif /* _STLSOFT_NO_NAMESPACE */
00159 #endif /* !_WINSTL_NO_NAMESPACE */
00160 
00162 
00165 
00169 
00174 
00178 inline void lock_instance(winstl_ns_qual(spin_mutex) &mx)
00179 {
00180     mx.lock();
00181 }
00182 
00186 inline void unlock_instance(winstl_ns_qual(spin_mutex) &mx)
00187 {
00188     mx.unlock();
00189 }
00190 
00192 
00193 #ifndef _WINSTL_NO_NAMESPACE
00194 # if defined(_STLSOFT_NO_NAMESPACE) || \
00195      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00196 namespace winstl {
00197 # else
00198 namespace winstl_project {
00199 #  if defined(__STLSOFT_COMPILER_IS_BORLAND)
00200 using ::stlsoft::lock_instance;
00201 using ::stlsoft::unlock_instance;
00202 #  endif /* __STLSOFT_COMPILER_IS_BORLAND */
00203 # endif /* _STLSOFT_NO_NAMESPACE */
00204 #endif /* !_WINSTL_NO_NAMESPACE */
00205 
00206 /* 
00207  * lock_traits (for the compilers that do not support Koenig Lookup)
00208  */
00209 
00210 // class lock_traits
00212 struct spin_mutex_lock_traits
00213 {
00214 public:
00216     typedef spin_mutex                lock_type;
00217     typedef spin_mutex_lock_traits    class_type;
00218 
00219 // Operations
00220 public:
00222     static void lock(spin_mutex &c)
00223     {
00224         lock_instance(c);
00225     }
00226 
00228     static void unlock(spin_mutex &c)
00229     {
00230         unlock_instance(c);
00231     }
00232 };
00233 
00235 // Unit-testing
00236 
00237 #ifdef STLSOFT_UNITTEST
00238 
00239 namespace unittest
00240 {
00241     ss_bool_t test_winstl_spin_mutex(unittest_reporter *r)
00242     {
00243         using stlsoft::unittest::unittest_initialiser;
00244 
00245         ss_bool_t               bSuccess    =   true;
00246 
00247         unittest_initialiser    init(r, "WinSTL", "spin_mutex", __FILE__);
00248 
00249 #if 0
00250         if(<<TODO>>)
00251         {
00252             r->report("<<TODO>> failed ", __LINE__);
00253             bSuccess = false;
00254         }
00255 #endif /* 0 */
00256 
00257         return bSuccess;
00258     }
00259 
00260     unittest_registrar    unittest_winstl_spin_mutex(test_winstl_spin_mutex);
00261 
00262 } // namespace unittest
00263 
00264 #endif /* STLSOFT_UNITTEST */
00265 
00266 /* 
00267 
00268 #ifndef _WINSTL_NO_NAMESPACE
00269 # if defined(_STLSOFT_NO_NAMESPACE) || \
00270      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00271 } // namespace winstl
00272 # else
00273 } // namespace winstl_project
00274 } // namespace stlsoft
00275 # endif /* _STLSOFT_NO_NAMESPACE */
00276 #endif /* !_WINSTL_NO_NAMESPACE */
00277 
00278 /* 
00279 
00280 #endif /* !WINSTL_INCL_H_WINSTL_SPIN_MUTEX */
00281 
00282 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004