⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _mutex.h

📁 realview22.rar
💻 H
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************
 *
 * _mutex.h - Definitions of classes and inline functions providing MT safety
 *
 * This is an internal header file used to implement the C++ Standard
 * Library. It should never be #included directly by a program.
 *
 * $Id: _mutex.h,v 1.1.1.1 2002/01/10 17:38:30 vkorstan Exp $
 *
 ***************************************************************************
 *
 * Copyright (c) 1994-2001 Rogue Wave Software, Inc.  All Rights Reserved.
 *
 * This computer software is owned by Rogue Wave Software, Inc. and is
 * protected by U.S. copyright laws and other laws and by international
 * treaties.  This computer software is furnished by Rogue Wave Software,
 * Inc. pursuant to a written license agreement and may be used, copied,
 * transmitted, and stored only in accordance with the terms of such
 * license and with the inclusion of the above copyright notice.  This
 * computer software or any other copies thereof may not be provided or
 * otherwise made available to any other person.
 *
 * U.S. Government Restricted Rights.  This computer software is provided
 * with Restricted Rights.  Use, duplication, or disclosure by the
 * Government is subject to restrictions as set forth in subparagraph (c)
 * (1) (ii) of The Rights in Technical Data and Computer Software clause
 * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
 * Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19,
 * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
 * Flatiron Parkway, Boulder, Colorado 80301 USA.
 *
 ***************************************************************************
 *
 * There are two mutex classes:
 *
 * __rw::__rw_mutex_base - a POD-type class with no ctor or dtor (POSIX
 * and Solaris threads only) suitable for mutex objects with static storage
 * duration. On POSIX threads, these objects are fully constructed at static
 * initialization time and initialized via assignment by 
 * PTHREAD_MUTEX_INITIALIZER, while on Solaris threads they do not need to be
 * initialized at all. On platforms such as Win32/64 that do not support static
 * initialization this class does define a ctor that initializes the object
 * by the appropriate thread library call.
 *
 * __rw::__rw_mutex - a non-POD-type class derived from __rw::__rw_mutex_base
 * with explicitly defined ctor and dtor suitable for mutex member variables.
 * On platforms such as Win32/64 that do not support static initialization this
 * class does not define its own ctor and dtor and simply defers the
 * initialization and destruction to its base.
 *
 * __rw::__rw_static_mutex<> - a POD-type class template, defined on
 * platforms such as POSIX or Solaris threads that support static
 * initialization of mutexes, containing a single public static data member
 * of the __rw::__rw_mutex_base class. The static member object is returned
 * from the factory function template __rw::__rw_get_static_mutex<>().
 *
 * On platforms such as Win32/64 that do not support static initialization
 * of mutex objects the factory template function
 * __rw::__rw_get_static_mutex<>() defines and dynamically initializes
 * a static local reference to an object of the __rw::__rw_mutex_base class.
 * The dynamic initialization is done in an MT-safe way (i.e., such that
 * exactly one initialization of the mutex object is guaranteed). On Win32/64
 * this is accomplished by making use of the InterlockedIncrement() API call,
 * everywhere else there exists a small potential for a race condition and
 * the risk of the object being initialized multiple times. The reference is
 * initialized to refer to a properly aligned static data buffer to prevent
 * the destruction of the actual object at program termination, and the object
 * itself is constructed in this buffer space via a call to placement new.
 *
 ***************************************************************************/

#ifndef _RWSTD_MUTEX_H_INCLUDED
#define _RWSTD_MUTEX_H_INCLUDED

#include <rw/_defs.h>

#include _RWSTD_CSTRING

#ifdef _RWSTD_MULTI_THREAD


#include <rw/_exception.h>


#if defined (_RWSTD_SOLARIS_THREADS)  // assuming Solaris 2.1 or greater

// SunOS 5.7 Threads Library:
//   "A statically  allocated  mutex does  not  need to be explicitly
//   initialized; by default, a statically allocated mutex is initialized
//   with  all  zeros and its scope is set to be within the calling
//   process."

#  include <synch.h>
#  include <thread.h>

#  define _RWSTD_MUTEX_INIT(mutex)      mutex_init (&mutex, USYNC_THREAD, 0)
#  define _RWSTD_MUTEX_DESTROY(mutex)   mutex_destroy (&mutex)
#  define _RWSTD_MUTEX_LOCK(mutex)      mutex_lock (&mutex)
#  define _RWSTD_MUTEX_UNLOCK(mutex)    mutex_unlock (&mutex)
#  define _RWSTD_MUTEX_T                mutex_t

#elif defined (_RWSTD_POSIX_D10_THREADS)

// LinuxThreads man page:
//   "Variables of type pthread_mutex_t can also be initialized
//    statically, using the constants  PTHREAD_MUTEX_INITIALIZER
//    (for fast mutexes), PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
//    (for recursive mutexes), and PTHREAD_ERRORCHECK_MUTEX_INI-
//    TIALIZER_NP (for error checking mutexes)."
//    ...
//    "Attempting to initialize an already initialized mutex results
//    in undefined behavior."

#  include <pthread.h>

#  define _RWSTD_MUTEX_INIT(mutex)      pthread_mutex_init (&mutex, 0)
#  define _RWSTD_MUTEX_DESTROY(mutex)   pthread_mutex_destroy (&mutex)
#  define _RWSTD_MUTEX_LOCK(mutex)      pthread_mutex_lock (&mutex)
#  define _RWSTD_MUTEX_UNLOCK(mutex)    pthread_mutex_unlock (&mutex)
#  define _RWSTD_MUTEX_T                pthread_mutex_t

#elif defined (_RWSTD_DCE_THREADS)

#  if defined (_RWSTD_NO_DCE_PTHREAD_H)
#    include <pthread.h>
#  else
#    include <dce/pthread.h>
#  endif

#  define _RWSTD_MUTEX_INIT(mutex) \
          pthread_mutex_init (&mutex, pthread_mutexattr_default)
#  define _RWSTD_MUTEX_DESTROY(mutex)   pthread_mutex_destroy (&mutex)
#  define _RWSTD_MUTEX_LOCK(mutex)      pthread_mutex_lock (&mutex)
#  define _RWSTD_MUTEX_UNLOCK(mutex)    pthread_mutex_unlock (&mutex)
#  define _RWSTD_MUTEX_T                pthread_mutex_t

// DCE doesn't seem to support static mutex initialization
#  include <new>

#elif defined (_WIN32) || defined (_WIN64)

#  ifdef _RWSTD_NO_FWD_DECLARATIONS

#    include <windows.h>
#    define _RWSTD_MUTEX_T _RTL_CRITICAL_SECTION

#  else   // if defined (_RWSTD_NO_FWD_DECLARATIONS)

   // avoid #including this header...
   // #  include <windows.h>

extern "C" {

// but rather declare these globals here
struct _RTL_CRITICAL_SECTION;

__declspec (dllimport) void __stdcall
InitializeCriticalSection (_RTL_CRITICAL_SECTION*);

__declspec (dllimport) void __stdcall
EnterCriticalSection (_RTL_CRITICAL_SECTION*);

__declspec (dllimport) void __stdcall
LeaveCriticalSection (_RTL_CRITICAL_SECTION*);

__declspec (dllimport) void __stdcall
DeleteCriticalSection (_RTL_CRITICAL_SECTION*);

__declspec (dllimport) long __stdcall
InterlockedIncrement (long*);

__declspec (dllimport) long __stdcall
InterlockedDecrement (long*);

__declspec (dllimport) long __stdcall
InterlockedExchange (long*, long);

}   // extern "C"

_RWSTD_NAMESPACE_BEGIN (__rw)

// fake critical section type
union __rw_critical_section {
    long _C_pad;   // force alignment
    char _C_buf [24 /* == sizeof (_RTL_CRITICAL_SECTION) */];
};

#    define _RWSTD_MUTEX_T _RW::__rw_critical_section

_RWSTD_NAMESPACE_END   // __rw


#  endif   // _RWSTD_NO_FWD_DECLARATIONS


_RWSTD_NAMESPACE_BEGIN (__rw)

// Win32/64 throws non-C++ exceptions rather than returning error status
// from some system calls like most other operating systems do

inline int __rw_mutex_init (_RTL_CRITICAL_SECTION *__mutex)
{
    __try {
        InitializeCriticalSection (__mutex);
    }
    __except (1) {
        return -1;
    }
    return 0;
}

inline int __rw_mutex_destroy (_RTL_CRITICAL_SECTION *__mutex)
{
    __try {
        DeleteCriticalSection (__mutex);
    }
    __except (1) {
        return -1;
    }
    return 0;
}

inline int __rw_mutex_lock (_RTL_CRITICAL_SECTION *__mutex)
{
    __try {
        EnterCriticalSection (__mutex);
    }
    __except (1) {
        return -1;
    }
    return 0;
}

inline int __rw_mutex_unlock (_RTL_CRITICAL_SECTION *__mutex)
{
    __try {
        LeaveCriticalSection (__mutex);
    }
    __except (1) {
        return -1;
    }
    return 0;
}

#  define _RWSTD_MUTEX_INIT(mutex)      \
   __rw_mutex_init (_RWSTD_REINTERPRET_CAST (_RTL_CRITICAL_SECTION*, &mutex))
#  define _RWSTD_MUTEX_DESTROY(mutex)   \
   __rw_mutex_destroy (_RWSTD_REINTERPRET_CAST (_RTL_CRITICAL_SECTION*, &mutex))
#  define _RWSTD_MUTEX_LOCK(mutex)      \
   __rw_mutex_lock (_RWSTD_REINTERPRET_CAST (_RTL_CRITICAL_SECTION*, &mutex))
#  define _RWSTD_MUTEX_UNLOCK(mutex)    \
   __rw_mutex_unlock (_RWSTD_REINTERPRET_CAST (_RTL_CRITICAL_SECTION*, &mutex))

_RWSTD_NAMESPACE_END   // __rw

#elif defined (__OS2__)

#  define INCL_DOSSEMAPHORES

#  include <os2.h>

#  define _RWSTD_MUTEX_INIT(mutex) \
          DosCreateMutexSem (0, &mutex, DC_SEM_SHARED,FALSE)
#  define _RWSTD_MUTEX_DESTROY(mutex)   DosCloseMutexSem (mutex)
#  define _RWSTD_MUTEX_LOCK(mutex) \
          DosRequestMutexSem (mutex, SEM_INDEFINITE_WAIT)
#  define _RWSTD_MUTEX_UNLOCK(mutex)    DosReleaseMutexSem (mutex)
#  define _RWSTD_MUTEX_T                HMTX

#else
#  error unknown thread environment
#endif


#if defined (__DECCXX)
   // get declarations of __ATOMIC_XXX intrinsics

#  include <machine/builtins.h>

#endif   // __DECXX


#if defined (__GNUG__) && defined (__osf__)
   // prevent g++ warnings about missing initializers
   // see <pthread.h> for explanation of _PTHREAD_NOMETER_STATIC
#  ifndef _PTHREAD_NOMETER_STATIC
#    define _RWSTD_PTHREAD_MUTEX_INITIALIZER \
            { _PTHREAD_MSTATE_SLOW, _PTHREAD_MVALID | _PTHREAD_MVF_STA, \
              0, 0, 0, 0, 0, 0 }
#  else   // if defined (_PTHREAD_NOMETER_STATIC)
#    define _RWSTD_PTHREAD_MUTEX_INITIALIZER
            { 0, _PTHREAD_MVALID | _PTHREAD_MVF_STA, 0, 0, 0, 0, 0, 0 }
#  endif   // _PTHREAD_NOMETER_STATIC
#elif defined (__GNUG__) && defined (__sgi__)
   // prevent g++ warnings about a partly bracketed initializer
#  define _RWSTD_PTHREAD_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#else
#  define _RWSTD_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#endif


_RWSTD_NAMESPACE_BEGIN (__rw)

// a using declaration (rather than a directive)
// used to work around yet another MSVC 6.0 bug
_USING (std::exception);

class __rw_thread_error : public exception
{
public:
    __rw_thread_error () _THROWS (())
    : exception () { }

    virtual const char* what () const _THROWS (()) {
        return "thread synchronization error";
    }
};                            


// POD type with no user-defined ctor or dtor facilitates static
// initialization of mutex objects with static storage duration
// (important during library initialziation time)
class _RWSTD_EXPORT __rw_mutex_base
{
public:

    void _C_acquire () {
#if !defined (__HP_aCC) || __HP_aCC > 32700
        if (0 != _RWSTD_MUTEX_LOCK (_C_mutex))
            _RW::__rw_throw (_RWSTD_ERROR_RUNTIME_ERROR,
                             "synchronization error");
#else
        // working around an HP aCC 3.27 bug JAGac88738
        _RWSTD_MUTEX_LOCK (_C_mutex);
#endif   // !defined (__HP_aCC) || __HP_aCC > 32700
    }

    void _C_release ();

#ifdef _RWSTD_NO_STATIC_MUTEX_INIT

    // static initialization not an option, define ctor and dtor
    // and make member mutex private

    __rw_mutex_base ();

    ~__rw_mutex_base ();

private:

    // not defined
    __rw_mutex_base (const __rw_mutex_base&);
    __rw_mutex_base& operator= (const __rw_mutex_base&);

#endif   // _RWSTD_NO_STATIC_MUTEX_INIT

    _RWSTD_MUTEX_T _C_mutex;   // the real thing
};


inline void __rw_mutex_base::_C_release ()
{
    // we should NOT throw from here as _C_release will typically be called
    // during the destruction of local objects such as __rw_guard (perhaps
    // due to another exception)
    _RWSTD_MUTEX_UNLOCK (_C_mutex);
}


// non-POD type, always initializes mutex data member via a function call
class  _RWSTD_EXPORT __rw_mutex: public __rw_mutex_base
{
public:

#ifndef _RWSTD_NO_STATIC_MUTEX_INIT

    __rw_mutex ();

    ~__rw_mutex ();

private:

    // not defined
    __rw_mutex (const __rw_mutex&);
    __rw_mutex& operator= (const __rw_mutex&);

#endif   // _RWSTD_NO_STATIC_MUTEX_INIT

};


#ifndef _RWSTD_NO_STATIC_MUTEX_INIT

// helper factory class - static member is guranteed to be constructed
// during static initialization; objects of this POD class are not
// destroyed during program termination (important to allow them
// to be used in dtors of other objects with static storage duration)
template <class _TypeT>
struct __rw_static_mutex
{
    static __rw_mutex_base _C_mutex;
};


template <class _TypeT>
__rw_mutex_base __rw_static_mutex<_TypeT>::_C_mutex

#ifdef _RWSTD_POSIX_D10_THREADS

    = { _RWSTD_PTHREAD_MUTEX_INITIALIZER }

#endif   // _RWSTD_POSIX_D10_THREADS
        ;

// explicitly instantiated to work around a g++ 2.95.2 bug on COFF systems
// (such as IBM AIX or DEC OSF1) where it "forgets" to do so implicitly for
// explicitly initialized static data members
_RWSTD_INSTANTIATE_1 (class _RWSTD_EXPORT __rw_static_mutex<int>);
_RWSTD_INSTANTIATE_1 (class _RWSTD_EXPORT __rw_static_mutex<size_t>);


inline __rw_mutex::__rw_mutex ()

#else   // if defined (_RWSTD_NO_STATIC_MUTEX_INIT)

inline __rw_mutex_base::__rw_mutex_base ()

#endif   // _RWSTD_NO_STATIC_MUTEX_INIT
{ 
    if (0 != _RWSTD_MUTEX_INIT (_C_mutex))
        _RW::__rw_throw (_RWSTD_ERROR_RUNTIME_ERROR, "synchronization error");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -