Advertisement
Guest User

Untitled

a guest
Nov 19th, 2014
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.00 KB | None | 0 0
  1. /*******************************************************************************
  2.  
  3.     Copyright(C) Jonas 'Sortie' Termansen 2012, 2013.
  4.  
  5.     This file is part of Sortix.
  6.  
  7.     Sortix is free software: you can redistribute it and/or modify it under the
  8.     terms of the GNU General Public License as published by the Free Software
  9.     Foundation, either version 3 of the License, or (at your option) any later
  10.     version.
  11.  
  12.     Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
  13.     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  14.     FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  15.     details.
  16.  
  17.     You should have received a copy of the GNU General Public License along with
  18.     Sortix. If not, see <http://www.gnu.org/licenses/>.
  19.  
  20.     sortix/kernel/refcount.h
  21.     A class that implements reference counting.
  22.  
  23. *******************************************************************************/
  24.  
  25. #ifndef SORTIX_REFCOUNT_H
  26. #define SORTIX_REFCOUNT_H
  27.  
  28. #include <sortix/kernel/kthread.h>
  29.  
  30. namespace Sortix {
  31.  
  32. class Refcountable
  33. {
  34. public:
  35.     Refcountable();
  36.     virtual ~Refcountable();
  37.  
  38. public:
  39.     void Refer_Renamed();
  40.     void Unref_Renamed();
  41.     size_t Refcount() const { return refcount; }
  42.     bool IsUnique() const { return refcount == 1; }
  43.  
  44. private:
  45.     kthread_mutex_t reflock;
  46.     size_t refcount;
  47.  
  48. public:
  49.     bool being_deleted;
  50.  
  51. };
  52.  
  53. template <class T> class Ref
  54. {
  55. public:
  56.     constexpr Ref() : obj(NULL) { }
  57.     explicit Ref(T* obj) : obj(obj) { if ( obj ) obj->Refer_Renamed(); }
  58.     template <class U>
  59.     explicit Ref(U* obj) : obj(obj) { if ( obj ) obj->Refer_Renamed(); }
  60.     Ref(const Ref<T>& r) : obj(r.Get()) { if ( obj ) obj->Refer_Renamed(); }
  61.     template <class U>
  62.     Ref(const Ref<U>& r) : obj(r.Get()) { if ( obj ) obj->Refer_Renamed(); }
  63.     ~Ref() { if ( obj ) obj->Unref_Renamed(); }
  64.  
  65.     Ref& operator=(const Ref r)
  66.     {
  67.         if ( obj == r.Get() )
  68.             return *this;
  69.         if ( obj )
  70.         {
  71.             obj->Unref_Renamed();
  72.             obj = NULL;
  73.         }
  74.         if ( (obj = r.Get()) )
  75.             obj->Refer_Renamed();
  76.         return *this;
  77.     }
  78.  
  79.     template <class U>
  80.     Ref operator=(const Ref<U> r)
  81.     {
  82.         if ( obj == r.Get() )
  83.             return *this;
  84.         if ( obj )
  85.         {
  86.             obj->Unref_Renamed();
  87.             obj = NULL;
  88.         }
  89.         if ( (obj = r.Get()) )
  90.             obj->Refer_Renamed();
  91.         return *this;
  92.     }
  93.  
  94.     bool operator==(const Ref& other)
  95.     {
  96.         return (*this).Get() == other.Get();
  97.     }
  98.  
  99.     template <class U> bool operator==(const Ref<U>& other)
  100.     {
  101.         return (*this).Get() == other.Get();
  102.     }
  103.  
  104.     template <class U> bool operator==(const U* const& other)
  105.     {
  106.         return (*this).Get() == other;
  107.     }
  108.  
  109.     bool operator!=(const Ref& other)
  110.     {
  111.         return !((*this) == other);
  112.     }
  113.  
  114.     template <class U> bool operator!=(const Ref<U>& other)
  115.     {
  116.         return !((*this) == other);
  117.     }
  118.  
  119.     template <class U> bool operator!=(const U* const& other)
  120.     {
  121.         return !((*this) == other);
  122.     }
  123.  
  124.     void Reset() { if ( obj ) obj->Unref_Renamed(); obj = NULL; }
  125.     T* Get() const { return obj; }
  126.     T& operator *() const { return *obj; }
  127.     T* operator->() const { return obj; }
  128.     operator bool() const { return obj != NULL; }
  129.     size_t Refcount() const { return obj ? obj->Refcount : 0; }
  130.     bool IsUnique() const { return obj->IsUnique(); }
  131.  
  132. private:
  133.     T* obj;
  134.  
  135. };
  136.  
  137. } // namespace Sortix
  138.  
  139. #endif
  140. /*******************************************************************************
  141.  
  142.     Copyright(C) Jonas 'Sortie' Termansen 2012.
  143.  
  144.     This file is part of Sortix.
  145.  
  146.     Sortix is free software: you can redistribute it and/or modify it under the
  147.     terms of the GNU General Public License as published by the Free Software
  148.     Foundation, either version 3 of the License, or (at your option) any later
  149.     version.
  150.  
  151.     Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
  152.     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  153.     FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  154.     details.
  155.  
  156.     You should have received a copy of the GNU General Public License along with
  157.     Sortix. If not, see <http://www.gnu.org/licenses/>.
  158.  
  159.     refcount.cpp
  160.     A class that implements reference counting.
  161.  
  162. *******************************************************************************/
  163.  
  164. #include <assert.h>
  165.  
  166. #include <sortix/kernel/kernel.h>
  167. #include <sortix/kernel/kthread.h>
  168. #include <sortix/kernel/refcount.h>
  169.  
  170. namespace Sortix {
  171.  
  172. Refcountable::Refcountable()
  173. {
  174.     reflock = KTHREAD_MUTEX_INITIALIZER;
  175.     refcount = 0;
  176.     being_deleted = false;
  177. }
  178.  
  179. Refcountable::~Refcountable()
  180. {
  181.     // It's OK to be deleted if our refcount is 1, it won't mess with any
  182.     // other owners that might need us.
  183.     assert(refcount <= 1);
  184. }
  185.  
  186. void Refcountable::Refer_Renamed()
  187. {
  188.     ScopedLock lock(&reflock);
  189.     refcount++;
  190. }
  191.  
  192. void Refcountable::Unref_Renamed()
  193. {
  194.     assert(!being_deleted);
  195.     kthread_mutex_lock(&reflock);
  196.     assert(refcount);
  197.     bool deleteme = !refcount || !--refcount;
  198.     kthread_mutex_unlock(&reflock);
  199.     if ( deleteme )
  200.     {
  201.         being_deleted = true;
  202.         delete this;
  203.     }
  204. }
  205.  
  206. } // namespace Sortix
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement