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.

106 lines
1.6 KiB

1 year ago
  1. #pragma once
  2. #include "spinlock.h"
  3. #include <cassert>
  4. namespace vlc
  5. {
  6. template<typename TargetClass, bool threadSafe = true> class Refcounted
  7. {
  8. using RefcountType = uint32_t;
  9. volatile RefcountType m_refCount = 0;
  10. Spinlock m_lock;
  11. public:
  12. RefcountType incRef()
  13. {
  14. m_lock.lock();
  15. auto result = m_refCount;
  16. m_refCount++;
  17. m_lock.unlock();
  18. return result;
  19. }
  20. RefcountType decRef()
  21. {
  22. m_lock.lock();
  23. assert(m_refCount > 0);
  24. auto result = m_refCount;
  25. m_refCount--;
  26. m_lock.unlock();
  27. return result;
  28. }
  29. RefcountType refs() const
  30. {
  31. return m_refCount;
  32. }
  33. protected:
  34. Refcounted() = default;
  35. ~Refcounted() = default;
  36. explicit Refcounted(RefcountType initial_refs) : m_refCount(initial_refs)
  37. {
  38. }
  39. };
  40. template<typename TargetClass> class Refcounted<TargetClass, false>
  41. {
  42. using RefcountType = uint32_t;
  43. RefcountType m_refCount = 0;
  44. public:
  45. RefcountType incRef()
  46. {
  47. auto result = m_refCount;
  48. m_refCount++;
  49. return result;
  50. }
  51. RefcountType decRef()
  52. {
  53. assert(m_refCount > 0);
  54. auto result = m_refCount;
  55. m_refCount--;
  56. return result;
  57. }
  58. RefcountType refs() const
  59. {
  60. return m_refCount;
  61. }
  62. protected:
  63. Refcounted() = default;
  64. ~Refcounted() = default;
  65. explicit Refcounted(RefcountType initial_refs) : m_refCount(initial_refs)
  66. {
  67. }
  68. };
  69. }
  70. template<typename T> void intrusiveIncRef(vlc::Refcounted<T>* ptr)
  71. {
  72. if (ptr)
  73. {
  74. ptr->incRef();
  75. }
  76. }
  77. template<typename T> void intrusiveDecRef(vlc::Refcounted<T>* ptr)
  78. {
  79. if (ptr && ptr->decRef() == 1)
  80. {
  81. delete static_cast<T*>(ptr);
  82. }
  83. }