00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifndef WINSTL_INCL_H_WINSTL
00060 # include "winstl.h"
00061 #endif
00062
00063
00064
00065
00066
00067 #ifndef _WINSTL_NO_NAMESPACE
00068 # if defined(_STLSOFT_NO_NAMESPACE) || \
00069 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00070
00071 namespace winstl
00072 {
00073 # else
00074
00075
00076 namespace stlsoft
00077 {
00078
00079 namespace winstl_project
00080 {
00081
00082 # endif
00083 #endif
00084
00085
00086
00087
00088
00089 #ifdef __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE
00090 # pragma message(_sscomp_fileline_message("This needs to be parameterised with a winstl::system_resource_policy, which would control whether to throw if MX create fails"))
00091 #endif
00092
00093
00095
00096 {
00097 public:
00098 typedef process_mutex class_type;
00099
00102 public:
00104 process_mutex() winstl_throw_0()
00105 : m_mx(create_mutex_(NULL, false, static_cast<ws_char_a_t const *>(0), m_bCreated))
00106 , m_bAbandoned(false)
00107 {}
00109 ss_explicit_k process_mutex(ws_char_a_t const *name) winstl_throw_0()
00110 : m_mx(create_mutex_(NULL, false, name, m_bCreated))
00111 , m_bAbandoned(false)
00112 {}
00114 ss_explicit_k process_mutex(ws_char_w_t const *name) winstl_throw_0()
00115 : m_mx(create_mutex_(NULL, false, name, m_bCreated))
00116 , m_bAbandoned(false)
00117 {}
00119 ss_explicit_k process_mutex(ws_bool_t bInitialOwer) winstl_throw_0()
00120 : m_mx(create_mutex_(NULL, bInitialOwer, static_cast<ws_char_a_t const *>(0), m_bCreated))
00121 , m_bAbandoned(false)
00122 {}
00124 ss_explicit_k process_mutex(ws_char_a_t const *name, ws_bool_t bInitialOwer) winstl_throw_0()
00125 : m_mx(create_mutex_(NULL, bInitialOwer, name, m_bCreated))
00126 , m_bAbandoned(false)
00127 {}
00129 ss_explicit_k process_mutex(ws_char_w_t const *name, ws_bool_t bInitialOwer) winstl_throw_0()
00130 : m_mx(create_mutex_(NULL, bInitialOwer, name, m_bCreated))
00131 , m_bAbandoned(false)
00132 {}
00134 ss_explicit_k process_mutex(ws_char_a_t const *name, ws_bool_t bInitialOwer, LPSECURITY_ATTRIBUTES psa) winstl_throw_0()
00135 : m_mx(create_mutex_(psa, bInitialOwer, name, m_bCreated))
00136 , m_bAbandoned(false)
00137 {}
00139 ss_explicit_k process_mutex(ws_char_w_t const *name, ws_bool_t bInitialOwer, LPSECURITY_ATTRIBUTES psa) winstl_throw_0()
00140 : m_mx(create_mutex_(psa, bInitialOwer, name, m_bCreated))
00141 , m_bAbandoned(false)
00142 {}
00143
00145 ~process_mutex() winstl_throw_0()
00146 {
00147 if(m_mx != NULL)
00148 {
00149 ::CloseHandle(m_mx);
00150 }
00151 }
00152
00153 #if 0
00154 void close() winstl_throw_0()
00155 {
00156 if(m_mx != NULL)
00157 {
00158 CloseHandleSetNull(m_mx);
00159 }
00160 }
00161 #endif
00162
00164
00167 public:
00169 void lock() winstl_throw_0()
00170 {
00171 DWORD dwRes = ::WaitForSingleObject(m_mx, INFINITE);
00172
00173 m_bAbandoned = (dwRes == WAIT_ABANDONED);
00174 }
00176 ws_bool_t lock(ws_dword_t wait) winstl_throw_0()
00177 {
00178 DWORD dwRes = ::WaitForSingleObject(m_mx, wait);
00179
00180 m_bAbandoned = (dwRes == WAIT_ABANDONED);
00181
00182 return (dwRes == WAIT_OBJECT_0);
00183 }
00187 ws_bool_t try_lock()
00188 {
00189 return lock(0);
00190 }
00192 void unlock() winstl_throw_0()
00193 {
00194 ::ReleaseMutex(m_mx);
00195 }
00197
00200 public:
00201 HANDLE handle()
00202 {
00203 return m_mx;
00204 }
00206
00209 public:
00215 ws_bool_t created() const
00216 {
00217 return m_bCreated;
00218 }
00219
00226 ws_bool_t abandoned() const
00227 {
00228 return m_bAbandoned;
00229 }
00230
00232
00233
00234 private:
00235 static HANDLE create_mutex_(LPSECURITY_ATTRIBUTES psa, ws_bool_t bInitialOwner, ws_char_a_t const *name, ws_bool_t &bCreated)
00236 {
00237 HANDLE mx = ::CreateMutexA(psa, bInitialOwner, name);
00238
00239 bCreated = (mx != NULL && ::GetLastError() != ERROR_ALREADY_EXISTS);
00240
00241 return mx;
00242 }
00243 static HANDLE create_mutex_(LPSECURITY_ATTRIBUTES psa, ws_bool_t bInitialOwner, ws_char_w_t const *name, ws_bool_t &bCreated)
00244 {
00245 HANDLE mx = ::CreateMutexW(psa, bInitialOwner, name);
00246
00247 bCreated = (mx != NULL && ::GetLastError() != ERROR_ALREADY_EXISTS);
00248
00249 return mx;
00250 }
00251 static HANDLE open_mutex_(ws_dword_t access, ws_bool_t bInheritHandle, ws_char_a_t const *name, ws_bool_t &bCreated)
00252 {
00253 HANDLE mx = ::OpenMutexA(access, bInheritHandle, name);
00254
00255 bCreated = (mx != NULL && ::GetLastError() != ERROR_ALREADY_EXISTS);
00256
00257 return mx;
00258 }
00259 static HANDLE open_mutex_(ws_dword_t access, ws_bool_t bInheritHandle, ws_char_w_t const *name, ws_bool_t &bCreated)
00260 {
00261 HANDLE mx = ::OpenMutexW(access, bInheritHandle, name);
00262
00263 bCreated = (mx != NULL && ::GetLastError() != ERROR_ALREADY_EXISTS);
00264
00265 return mx;
00266 }
00267
00268
00269 private:
00270 HANDLE m_mx;
00271 ws_bool_t m_bCreated;
00272 ws_bool_t m_bAbandoned;
00273
00274
00275 private:
00276 process_mutex(class_type const &rhs);
00277 process_mutex &operator =(class_type const &rhs);
00278 };
00279
00280
00281
00282
00283
00284 #ifndef _WINSTL_NO_NAMESPACE
00285 # if defined(_STLSOFT_NO_NAMESPACE) || \
00286 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00287 }
00288 # else
00289 }
00290 # endif
00291 #endif
00292
00294
00297
00301
00306
00310 inline void lock_instance(winstl_ns_qual(process_mutex) &mx)
00311 {
00312 mx.lock();
00313 }
00314
00318 inline void unlock_instance(winstl_ns_qual(process_mutex) &mx)
00319 {
00320 mx.unlock();
00321 }
00322
00324
00325 #ifndef _WINSTL_NO_NAMESPACE
00326 # if defined(_STLSOFT_NO_NAMESPACE) || \
00327 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00328 namespace winstl {
00329 # else
00330 namespace winstl_project {
00331 # if defined(__STLSOFT_COMPILER_IS_BORLAND)
00332 using ::stlsoft::lock_instance;
00333 using ::stlsoft::unlock_instance;
00334 # endif
00335 # endif
00336 #endif
00337
00338
00339
00340
00341
00342
00344
00345 {
00346 public:
00348 typedef process_mutex lock_type;
00349 typedef process_mutex_lock_traits class_type;
00350
00351
00352 public:
00354 static void lock(process_mutex &c)
00355 {
00356 lock_instance(c);
00357 }
00358
00360 static void unlock(process_mutex &c)
00361 {
00362 unlock_instance(c);
00363 }
00364 };
00365
00367
00368
00369 #ifdef STLSOFT_UNITTEST
00370
00371 namespace unittest
00372 {
00373 ss_bool_t test_winstl_process_mutex(unittest_reporter *r)
00374 {
00375 using stlsoft::unittest::unittest_initialiser;
00376
00377 ss_bool_t bSuccess = true;
00378
00379 unittest_initialiser init(r, "WinSTL", "process_mutex", __FILE__);
00380
00381 process_mutex mx_r(true);
00382
00383 mx_r.lock();
00384 if(!mx_r.try_lock())
00385 {
00386 r->report("process_mutex could not lock recursively ", __LINE__);
00387 bSuccess = false;
00388 }
00389 else
00390 {
00391 mx_r.unlock();
00392 }
00393 mx_r.unlock();
00394
00395 process_mutex mx_named("STLSoft.WinSTL.process_mutex");
00396
00397 mx_named.lock();
00398 if(!mx_named.try_lock())
00399 {
00400 r->report("process_mutex could not lock recursively ", __LINE__);
00401 mx_named.unlock();
00402 bSuccess = false;
00403 }
00404 mx_named.unlock();
00405
00406 return bSuccess;
00407 }
00408
00409 unittest_registrar unittest_winstl_process_mutex(test_winstl_process_mutex);
00410
00411 }
00412
00413 #endif
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 #endif
00426
00427
00428
00429
00430
00431