SharedCluster.h revision 296417
1254721Semaste//===------------------SharedCluster.h --------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef utility_SharedCluster_h_
11254721Semaste#define utility_SharedCluster_h_
12254721Semaste
13254721Semaste#include "lldb/Utility/SharingPtr.h"
14254721Semaste#include "lldb/Host/Mutex.h"
15254721Semaste
16276479Sdim#include "llvm/ADT/SmallPtrSet.h"
17276479Sdim
18254721Semastenamespace lldb_private {
19254721Semaste
20254721Semastenamespace imp
21254721Semaste{
22254721Semaste    template <typename T>
23254721Semaste    class shared_ptr_refcount : public lldb_private::imp::shared_count
24254721Semaste    {
25254721Semaste    public:
26254721Semaste        template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {}
27254721Semaste
28254721Semaste        shared_ptr_refcount() : shared_count (0) {}
29254721Semaste
30296417Sdim        ~shared_ptr_refcount() override
31254721Semaste        {
32254721Semaste        }
33254721Semaste
34296417Sdim        void on_zero_shared() override
35254721Semaste        {
36254721Semaste            manager->DecrementRefCount();
37254721Semaste        }
38296417Sdim
39254721Semaste    private:
40254721Semaste        T *manager;
41254721Semaste    };
42254721Semaste
43254721Semaste} // namespace imp
44254721Semaste
45254721Semastetemplate <class T>
46254721Semasteclass ClusterManager
47254721Semaste{
48254721Semastepublic:
49254721Semaste    ClusterManager () :
50254721Semaste        m_objects(),
51254721Semaste        m_external_ref(0),
52254721Semaste        m_mutex(Mutex::eMutexTypeNormal) {}
53254721Semaste
54254721Semaste    ~ClusterManager ()
55254721Semaste    {
56276479Sdim        for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos)
57254721Semaste        {
58276479Sdim            T *object = *pos;
59276479Sdim            delete object;
60254721Semaste        }
61276479Sdim
62254721Semaste        // Decrement refcount should have been called on this ClusterManager,
63254721Semaste        // and it should have locked the mutex, now we will unlock it before
64254721Semaste        // we destroy it...
65254721Semaste        m_mutex.Unlock();
66254721Semaste    }
67254721Semaste
68254721Semaste    void ManageObject (T *new_object)
69254721Semaste    {
70254721Semaste        Mutex::Locker locker (m_mutex);
71276479Sdim        m_objects.insert (new_object);
72254721Semaste    }
73254721Semaste
74254721Semaste    typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object)
75254721Semaste    {
76254721Semaste        {
77254721Semaste            Mutex::Locker locker (m_mutex);
78254721Semaste            m_external_ref++;
79276479Sdim            assert (m_objects.count(desired_object));
80254721Semaste        }
81254721Semaste        return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this));
82254721Semaste    }
83254721Semaste
84254721Semasteprivate:
85254721Semaste
86254721Semaste    void DecrementRefCount ()
87254721Semaste    {
88254721Semaste        m_mutex.Lock();
89254721Semaste        m_external_ref--;
90254721Semaste        if (m_external_ref == 0)
91254721Semaste            delete this;
92254721Semaste        else
93254721Semaste            m_mutex.Unlock();
94254721Semaste    }
95254721Semaste
96254721Semaste    friend class imp::shared_ptr_refcount<ClusterManager>;
97254721Semaste
98276479Sdim    llvm::SmallPtrSet<T *, 16> m_objects;
99254721Semaste    int m_external_ref;
100254721Semaste    Mutex m_mutex;
101254721Semaste};
102254721Semaste
103254721Semaste} // namespace lldb_private
104296417Sdim
105254721Semaste#endif // utility_SharedCluster_h_
106