blob: 991af4b4fa4987717a7878928322e1e71b40ecf6 [file] [log] [blame]
//===------------------SharedCluster.h --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef utility_SharedCluster_h_
#define utility_SharedCluster_h_
#include "lldb/Utility/SharingPtr.h"
#include "lldb/Host/Mutex.h"
namespace lldb_private {
namespace imp
{
template <typename T>
class shared_ptr_refcount : public lldb_private::imp::shared_count
{
public:
template<class Y> shared_ptr_refcount (Y *in) : shared_count (0), manager(in) {}
shared_ptr_refcount() : shared_count (0) {}
virtual ~shared_ptr_refcount ()
{
}
virtual void on_zero_shared ()
{
manager->DecrementRefCount();
}
private:
T *manager;
};
} // namespace imp
template <class T>
class ClusterManager
{
public:
ClusterManager () :
m_objects(),
m_external_ref(0),
m_mutex(Mutex::eMutexTypeNormal) {}
~ClusterManager ()
{
size_t n_items = m_objects.size();
for (size_t i = 0; i < n_items; i++)
{
delete m_objects[i];
}
// Decrement refcount should have been called on this ClusterManager,
// and it should have locked the mutex, now we will unlock it before
// we destroy it...
m_mutex.Unlock();
}
void ManageObject (T *new_object)
{
Mutex::Locker locker (m_mutex);
if (!ContainsObject(new_object))
m_objects.push_back (new_object);
}
typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object)
{
{
Mutex::Locker locker (m_mutex);
m_external_ref++;
assert (ContainsObject(desired_object));
}
return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this));
}
private:
bool ContainsObject (const T *desired_object)
{
typename std::vector<T *>::iterator pos, end = m_objects.end();
pos = std::find(m_objects.begin(), end, desired_object);
return pos != end;
}
void DecrementRefCount ()
{
m_mutex.Lock();
m_external_ref--;
if (m_external_ref == 0)
delete this;
else
m_mutex.Unlock();
}
friend class imp::shared_ptr_refcount<ClusterManager>;
std::vector<T *> m_objects;
int m_external_ref;
Mutex m_mutex;
};
} // namespace lldb_private
#endif // utility_SharedCluster_h_