weak_ptr.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #include <util/generic/ptr.h>
  3. #include <util/system/mutex.h>
  4. template <typename T>
  5. struct TWeakPtr;
  6. template <typename TSelf>
  7. struct TWeakRefCounted {
  8. template <typename>
  9. friend struct TWeakPtr;
  10. private:
  11. struct TRef: public TAtomicRefCount<TRef> {
  12. TMutex Mutex;
  13. TSelf* Outer;
  14. TRef(TSelf* outer)
  15. : Outer(outer)
  16. {
  17. }
  18. void Release() {
  19. TGuard<TMutex> g(Mutex);
  20. Y_ASSERT(!!Outer);
  21. Outer = nullptr;
  22. }
  23. TIntrusivePtr<TSelf> Get() {
  24. TGuard<TMutex> g(Mutex);
  25. Y_ASSERT(!Outer || Outer->RefCount() > 0);
  26. return Outer;
  27. }
  28. };
  29. TAtomicCounter Counter;
  30. TIntrusivePtr<TRef> RefPtr;
  31. public:
  32. TWeakRefCounted()
  33. : RefPtr(new TRef(static_cast<TSelf*>(this)))
  34. {
  35. }
  36. void Ref() {
  37. Counter.Inc();
  38. }
  39. void UnRef() {
  40. if (Counter.Dec() == 0) {
  41. RefPtr->Release();
  42. // drop is to prevent dtor from reading it
  43. RefPtr.Drop();
  44. delete static_cast<TSelf*>(this);
  45. }
  46. }
  47. void DecRef() {
  48. Counter.Dec();
  49. }
  50. unsigned RefCount() const {
  51. return Counter.Val();
  52. }
  53. };
  54. template <typename T>
  55. struct TWeakPtr {
  56. private:
  57. typedef TIntrusivePtr<typename T::TRef> TRefPtr;
  58. TRefPtr RefPtr;
  59. public:
  60. TWeakPtr() {
  61. }
  62. TWeakPtr(T* t) {
  63. if (!!t) {
  64. RefPtr = t->RefPtr;
  65. }
  66. }
  67. TWeakPtr(TIntrusivePtr<T> t) {
  68. if (!!t) {
  69. RefPtr = t->RefPtr;
  70. }
  71. }
  72. TIntrusivePtr<T> Get() {
  73. if (!RefPtr) {
  74. return nullptr;
  75. } else {
  76. return RefPtr->Get();
  77. }
  78. }
  79. };