Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1997.
  5. //
  6. // File: Refcount.hxx
  7. //
  8. // Contents: For refcounting, under lock
  9. //
  10. // Classes: CRefCount
  11. //
  12. // History: 09-Feb-94 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. class CRefCount
  17. {
  18. public:
  19. inline CRefCount();
  20. inline ~CRefCount();
  21. inline void AddRef();
  22. inline void Release();
  23. inline void Wait();
  24. private:
  25. CMutexSem _mtx; // Refcount incremented under lock
  26. CEventSem _evt; // Set when _cRef drops to 1
  27. unsigned _cRef; // RefCount
  28. };
  29. inline CRefCount::CRefCount()
  30. : _cRef( 1 )
  31. {
  32. }
  33. inline CRefCount::~CRefCount()
  34. {
  35. //
  36. // We must take the lock here. Otherwise some other thread may have set
  37. // _evt (under lock) but not yet have run to completion and
  38. // released _mtx. If we finish executing this destructor before
  39. // _mtx is released, _mtx will have been deleted before _mtx.Release()
  40. // is called. Bad news!
  41. //
  42. CLock lock( _mtx );
  43. }
  44. inline void CRefCount::AddRef()
  45. {
  46. CLock lock( _mtx );
  47. _cRef++;
  48. }
  49. inline void CRefCount::Release()
  50. {
  51. CLock lock( _mtx );
  52. _cRef--;
  53. if ( _cRef == 1 )
  54. _evt.Set();
  55. }
  56. inline void CRefCount::Wait()
  57. {
  58. {
  59. CLock lock( _mtx );
  60. if ( _cRef > 1 )
  61. _evt.Reset();
  62. else
  63. return;
  64. }
  65. _evt.Wait();
  66. }