ncbimtx.inl
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:9k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbimtx.inl,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 15:04:49  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #if defined(CORELIB___NCBIMTX__HPP)  &&  !defined(CORELIB___NCBIMTX__INL)
  10. #define CORELIB___NCBIMTX__INL
  11. /*  $Id: ncbimtx.inl,v 1000.0 2003/10/29 15:04:49 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author: Eugene Vasilchenko
  37.  *
  38.  * File Description:
  39.  *   Mutex classes' inline functions
  40.  *
  41.  */
  42. /////////////////////////////////////////////////////////////////////////////
  43. //  SSystemFastMutexStruct
  44. //
  45. inline
  46. bool SSystemFastMutex::IsInitialized(void) const
  47. {
  48.     return m_Magic == eMutexInitialized;
  49. }
  50. inline
  51. bool SSystemFastMutex::IsUninitialized(void) const
  52. {
  53.     return m_Magic == eMutexUninitialized;
  54. }
  55. inline
  56. void SSystemFastMutex::CheckInitialized(void) const
  57. {
  58. #if defined(INTERNAL_MUTEX_DEBUG)
  59.     if ( !IsInitialized() ) {
  60.         ThrowUninitialized();
  61.     }
  62. #endif
  63. }
  64. inline
  65. void SSystemFastMutex::Lock(void)
  66. {
  67. #if defined(NCBI_NO_THREADS)
  68.     return;
  69. #else
  70.     // check
  71.     CheckInitialized();
  72.     // Acquire system mutex
  73. #  if defined(NCBI_WIN32_THREADS)
  74.     if (WaitForSingleObject(m_Handle, INFINITE) != WAIT_OBJECT_0) {
  75.         ThrowLockFailed();
  76.     }
  77. #  elif defined(NCBI_POSIX_THREADS)
  78.     if ( pthread_mutex_lock(&m_Handle) != 0 ) { // error
  79.         ThrowLockFailed();
  80.     }
  81. #  endif
  82. #endif
  83. }
  84. inline
  85. bool SSystemFastMutex::TryLock(void)
  86. {
  87. #if defined(NCBI_NO_THREADS)
  88.     return true;
  89. #else
  90.     // check
  91.     CheckInitialized();
  92.     // Check if the system mutex is acquired.
  93.     // If not, acquire for the current thread.
  94. #  if defined(NCBI_WIN32_THREADS)
  95.     DWORD status = WaitForSingleObject(m_Handle, 0);
  96.     if (status == WAIT_OBJECT_0) { // ok
  97.         return true;
  98.     }
  99.     else {
  100.         if (status != WAIT_TIMEOUT) { // error
  101.             ThrowTryLockFailed();
  102.         }
  103.         return false;
  104.     }
  105. #  elif defined(NCBI_POSIX_THREADS)
  106.     int status = pthread_mutex_trylock(&m_Handle);
  107.     if (status == 0) { // ok
  108.         return true;
  109.     }
  110.     else {
  111.         if (status != EBUSY) { // error
  112.             ThrowTryLockFailed();
  113.         }
  114.         return false;
  115.     }
  116. #  endif
  117. #endif
  118. }
  119. inline
  120. void SSystemFastMutex::Unlock(void)
  121. {
  122. #if defined(NCBI_NO_THREADS)
  123.     return;
  124. #else
  125.     // check
  126.     CheckInitialized();
  127.         
  128.     // Release system mutex
  129. # if defined(NCBI_WIN32_THREADS)
  130.     if ( !ReleaseMutex(m_Handle) ) { // error
  131.         ThrowUnlockFailed();
  132.     }
  133. # elif defined(NCBI_POSIX_THREADS)
  134.     if ( pthread_mutex_unlock(&m_Handle) != 0 ) { // error
  135.         ThrowUnlockFailed();
  136.     }
  137. # endif
  138. #endif
  139. }
  140. /////////////////////////////////////////////////////////////////////////////
  141. //  SSystemMutex
  142. //
  143. inline
  144. bool SSystemMutex::IsInitialized(void) const
  145. {
  146.     return m_Mutex.IsInitialized();
  147. }
  148. inline
  149. bool SSystemMutex::IsUninitialized(void) const
  150. {
  151.     return m_Mutex.IsUninitialized();
  152. }
  153. inline
  154. void SSystemMutex::InitializeStatic(void)
  155. {
  156.     m_Mutex.InitializeStatic();
  157. }
  158. inline
  159. void SSystemMutex::InitializeDynamic(void)
  160. {
  161.     m_Mutex.InitializeDynamic();
  162.     m_Count = 0;
  163. }
  164. #if defined(NCBI_NO_THREADS)
  165. // empty version of Lock/Unlock methods for inlining
  166. inline
  167. void SSystemMutex::Lock(void)
  168. {
  169. }
  170. inline
  171. bool SSystemMutex::TryLock(void)
  172. {
  173.     return true;
  174. }
  175. inline
  176. void SSystemMutex::Unlock(void)
  177. {
  178. }
  179. #endif
  180. #if defined(NEED_AUTO_INITIALIZE_MUTEX)
  181. inline
  182. CAutoInitializeStaticFastMutex::TObject&
  183. CAutoInitializeStaticFastMutex::Get(void)
  184. {
  185.     if ( !m_Mutex.IsInitialized() ) {
  186.         Initialize();
  187.     }
  188.     return m_Mutex;
  189. }
  190. inline
  191. CAutoInitializeStaticFastMutex::
  192. operator CAutoInitializeStaticFastMutex::TObject&(void)
  193. {
  194.     return Get();
  195. }
  196. inline
  197. void CAutoInitializeStaticFastMutex::Lock(void)
  198. {
  199.     Get().Lock();
  200. }
  201. inline
  202. void CAutoInitializeStaticFastMutex::Unlock(void)
  203. {
  204.     Get().Unlock();
  205. }
  206. inline
  207. bool CAutoInitializeStaticFastMutex::TryLock(void)
  208. {
  209.     return Get().TryLock();
  210. }
  211. inline
  212. CAutoInitializeStaticMutex::TObject&
  213. CAutoInitializeStaticMutex::Get(void)
  214. {
  215.     if ( !m_Mutex.IsInitialized() ) {
  216.         Initialize();
  217.     }
  218.     return m_Mutex;
  219. }
  220. inline
  221. CAutoInitializeStaticMutex::
  222. operator CAutoInitializeStaticMutex::TObject&(void)
  223. {
  224.     return Get();
  225. }
  226. inline
  227. void CAutoInitializeStaticMutex::Lock(void)
  228. {
  229.     Get().Lock();
  230. }
  231. inline
  232. void CAutoInitializeStaticMutex::Unlock(void)
  233. {
  234.     Get().Unlock();
  235. }
  236. inline
  237. bool CAutoInitializeStaticMutex::TryLock(void)
  238. {
  239.     return Get().TryLock();
  240. }
  241. #endif
  242. /////////////////////////////////////////////////////////////////////////////
  243. //  CFastMutex::
  244. //
  245. inline
  246. CFastMutex::CFastMutex(void)
  247. {
  248.     m_Mutex.InitializeDynamic();
  249. }
  250. inline
  251. CFastMutex::~CFastMutex(void)
  252. {
  253.     m_Mutex.Destroy();
  254. }
  255. inline
  256. CFastMutex::operator SSystemFastMutex&(void)
  257. {
  258.     return m_Mutex;
  259. }
  260. inline
  261. void CFastMutex::Lock(void)
  262. {
  263.     m_Mutex.Lock();
  264. }
  265. inline
  266. void CFastMutex::Unlock(void)
  267. {
  268.     m_Mutex.Unlock();
  269. }
  270. inline
  271. bool CFastMutex::TryLock(void)
  272. {
  273.     return m_Mutex.TryLock();
  274. }
  275. // CFastMutexGuard
  276. inline
  277. CFastMutexGuard::CFastMutexGuard(void)
  278.     : m_Mutex(0)
  279. {
  280. }
  281. inline
  282. CFastMutexGuard::CFastMutexGuard(SSystemFastMutex& mtx)
  283.     : m_Mutex(&mtx)
  284. {
  285.     mtx.Lock();
  286. }
  287. inline
  288. CFastMutexGuard::~CFastMutexGuard(void)
  289. {
  290.     if (m_Mutex)
  291.         m_Mutex->Unlock();
  292. }
  293. inline
  294. void CFastMutexGuard::Release(void)
  295. {
  296.     if ( m_Mutex ) {
  297.         m_Mutex->Unlock();
  298.         m_Mutex = 0;
  299.     }
  300. }
  301. inline
  302. void CFastMutexGuard::Guard(SSystemFastMutex& mtx)
  303. {
  304.     if ( &mtx != m_Mutex ) {
  305.         Release();
  306.         mtx.Lock();
  307.         m_Mutex = &mtx;
  308.     }
  309. }
  310. inline
  311. CMutex::CMutex(void)
  312. {
  313.     m_Mutex.InitializeDynamic();
  314. }
  315. inline
  316. CMutex::~CMutex(void)
  317. {
  318.     m_Mutex.Destroy();
  319. }
  320. inline
  321. CMutex::operator SSystemMutex&(void)
  322. {
  323.     return m_Mutex;
  324. }
  325. inline
  326. void CMutex::Lock(void)
  327. {
  328.     m_Mutex.Lock();
  329. }
  330. inline
  331. void CMutex::Unlock(void)
  332. {
  333.     m_Mutex.Unlock();
  334. }
  335. inline
  336. bool CMutex::TryLock(void)
  337. {
  338.     return m_Mutex.TryLock();
  339. }
  340. inline
  341. CMutexGuard::CMutexGuard(void)
  342.     : m_Mutex(0)
  343. {
  344. }
  345. inline
  346. CMutexGuard::CMutexGuard(SSystemMutex& mtx)
  347.     : m_Mutex(&mtx)
  348. {
  349.     mtx.Lock();
  350. }
  351. inline
  352. CMutexGuard::~CMutexGuard(void)
  353. {
  354.     if ( m_Mutex ) {
  355.         m_Mutex->Unlock();
  356.     }
  357. }
  358. inline
  359. void CMutexGuard::Release(void)
  360. {
  361.     if ( m_Mutex ) {
  362.         m_Mutex->Unlock();
  363.         m_Mutex = 0;
  364.     }
  365. }
  366. inline
  367. void CMutexGuard::Guard(SSystemMutex& mtx)
  368. {
  369.     if ( &mtx != m_Mutex ) {
  370.         Release();
  371.         mtx.Lock();
  372.         m_Mutex = &mtx;
  373.     }
  374. }
  375. /*
  376.  * ===========================================================================
  377.  * $Log: ncbimtx.inl,v $
  378.  * Revision 1000.0  2003/10/29 15:04:49  gouriano
  379.  * PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.5
  380.  *
  381.  * Revision 1.5  2003/09/02 16:08:48  vasilche
  382.  * Fixed race condition with optimization on some compilers - added 'volatile'.
  383.  * Moved mutex Lock/Unlock methods out of inline section - they are quite complex.
  384.  *
  385.  * Revision 1.4  2003/09/02 15:41:05  ucko
  386.  * Re-sync preprocessor guards with ncbimtx.hpp.
  387.  *
  388.  * Revision 1.3  2003/06/19 19:16:37  vasilche
  389.  * Added CMutexGuard and CFastMutexGuard constructors.
  390.  *
  391.  * Revision 1.2  2002/09/20 20:02:07  vasilche
  392.  * Added public Lock/Unlock/TryLock
  393.  *
  394.  * Revision 1.1  2002/09/19 20:05:41  vasilche
  395.  * Safe initialization of static mutexes
  396.  *
  397.  * ===========================================================================
  398.  */
  399. #endif