File indexing completed on 2025-01-18 10:12:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "internal/_deprecated_header_message_guard.h"
0018
0019 #if !defined(__TBB_show_deprecation_message_recursive_mutex_H) && defined(__TBB_show_deprecated_header_message)
0020 #define __TBB_show_deprecation_message_recursive_mutex_H
0021 #pragma message("TBB Warning: tbb/recursive_mutex.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.")
0022 #endif
0023
0024 #if defined(__TBB_show_deprecated_header_message)
0025 #undef __TBB_show_deprecated_header_message
0026 #endif
0027
0028 #ifndef __TBB_recursive_mutex_H
0029 #define __TBB_recursive_mutex_H
0030
0031 #define __TBB_recursive_mutex_H_include_area
0032 #include "internal/_warning_suppress_enable_notice.h"
0033
0034 #if _WIN32||_WIN64
0035 #include "machine/windows_api.h"
0036 #else
0037 #include <pthread.h>
0038 #endif
0039
0040 #include <new>
0041 #include "aligned_space.h"
0042 #include "tbb_stddef.h"
0043 #include "tbb_profiling.h"
0044
0045 namespace tbb {
0046
0047
0048
0049 class __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::recursive_mutex is deprecated, use std::recursive_mutex")
0050 recursive_mutex : internal::mutex_copy_deprecated_and_disabled {
0051 public:
0052
0053 recursive_mutex() {
0054 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
0055 internal_construct();
0056 #else
0057 #if _WIN32||_WIN64
0058 InitializeCriticalSectionEx(&impl, 4000, 0);
0059 #else
0060 pthread_mutexattr_t mtx_attr;
0061 int error_code = pthread_mutexattr_init( &mtx_attr );
0062 if( error_code )
0063 tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutexattr_init failed");
0064
0065 pthread_mutexattr_settype( &mtx_attr, PTHREAD_MUTEX_RECURSIVE );
0066 error_code = pthread_mutex_init( &impl, &mtx_attr );
0067 if( error_code )
0068 tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_init failed");
0069
0070 pthread_mutexattr_destroy( &mtx_attr );
0071 #endif
0072 #endif
0073 };
0074
0075 ~recursive_mutex() {
0076 #if TBB_USE_ASSERT
0077 internal_destroy();
0078 #else
0079 #if _WIN32||_WIN64
0080 DeleteCriticalSection(&impl);
0081 #else
0082 pthread_mutex_destroy(&impl);
0083
0084 #endif
0085 #endif
0086 };
0087
0088 class scoped_lock;
0089 friend class scoped_lock;
0090
0091
0092
0093
0094 class scoped_lock: internal::no_copy {
0095 public:
0096
0097 scoped_lock() : my_mutex(NULL) {};
0098
0099
0100 scoped_lock( recursive_mutex& mutex ) {
0101 #if TBB_USE_ASSERT
0102 my_mutex = &mutex;
0103 #endif
0104 acquire( mutex );
0105 }
0106
0107
0108 ~scoped_lock() {
0109 if( my_mutex )
0110 release();
0111 }
0112
0113
0114 void acquire( recursive_mutex& mutex ) {
0115 #if TBB_USE_ASSERT
0116 internal_acquire( mutex );
0117 #else
0118 my_mutex = &mutex;
0119 mutex.lock();
0120 #endif
0121 }
0122
0123
0124 bool try_acquire( recursive_mutex& mutex ) {
0125 #if TBB_USE_ASSERT
0126 return internal_try_acquire( mutex );
0127 #else
0128 bool result = mutex.try_lock();
0129 if( result )
0130 my_mutex = &mutex;
0131 return result;
0132 #endif
0133 }
0134
0135
0136 void release() {
0137 #if TBB_USE_ASSERT
0138 internal_release();
0139 #else
0140 my_mutex->unlock();
0141 my_mutex = NULL;
0142 #endif
0143 }
0144
0145 private:
0146
0147 recursive_mutex* my_mutex;
0148
0149
0150 void __TBB_EXPORTED_METHOD internal_acquire( recursive_mutex& m );
0151
0152
0153 bool __TBB_EXPORTED_METHOD internal_try_acquire( recursive_mutex& m );
0154
0155
0156 void __TBB_EXPORTED_METHOD internal_release();
0157
0158 friend class recursive_mutex;
0159 };
0160
0161
0162 static const bool is_rw_mutex = false;
0163 static const bool is_recursive_mutex = true;
0164 static const bool is_fair_mutex = false;
0165
0166
0167
0168
0169 void lock() {
0170 #if TBB_USE_ASSERT
0171 aligned_space<scoped_lock> tmp;
0172 new(tmp.begin()) scoped_lock(*this);
0173 #else
0174 #if _WIN32||_WIN64
0175 EnterCriticalSection(&impl);
0176 #else
0177 int error_code = pthread_mutex_lock(&impl);
0178 if( error_code )
0179 tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed");
0180 #endif
0181 #endif
0182 }
0183
0184
0185
0186 bool try_lock() {
0187 #if TBB_USE_ASSERT
0188 aligned_space<scoped_lock> tmp;
0189 return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
0190 #else
0191 #if _WIN32||_WIN64
0192 return TryEnterCriticalSection(&impl)!=0;
0193 #else
0194 return pthread_mutex_trylock(&impl)==0;
0195 #endif
0196 #endif
0197 }
0198
0199
0200 void unlock() {
0201 #if TBB_USE_ASSERT
0202 aligned_space<scoped_lock> tmp;
0203 scoped_lock& s = *tmp.begin();
0204 s.my_mutex = this;
0205 s.internal_release();
0206 #else
0207 #if _WIN32||_WIN64
0208 LeaveCriticalSection(&impl);
0209 #else
0210 pthread_mutex_unlock(&impl);
0211 #endif
0212 #endif
0213 }
0214
0215
0216 #if _WIN32||_WIN64
0217 typedef LPCRITICAL_SECTION native_handle_type;
0218 #else
0219 typedef pthread_mutex_t* native_handle_type;
0220 #endif
0221 native_handle_type native_handle() { return (native_handle_type) &impl; }
0222
0223 private:
0224 #if _WIN32||_WIN64
0225 CRITICAL_SECTION impl;
0226 enum state_t {
0227 INITIALIZED=0x1234,
0228 DESTROYED=0x789A,
0229 } state;
0230 #else
0231 pthread_mutex_t impl;
0232 #endif
0233
0234
0235 void __TBB_EXPORTED_METHOD internal_construct();
0236
0237
0238 void __TBB_EXPORTED_METHOD internal_destroy();
0239 };
0240
0241 __TBB_DEFINE_PROFILING_SET_NAME(recursive_mutex)
0242
0243 }
0244
0245 #include "internal/_warning_suppress_disable_notice.h"
0246 #undef __TBB_recursive_mutex_H_include_area
0247
0248 #endif