1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#include <assert.h>
#include "stack_ptr.hpp"
#include "cache-t.hpp"
namespace acommon {
static StackPtr<Mutex> global_cache_lock(new Mutex);
static GlobalCacheBase * first_cache = 0;
void Cacheable::copy() const
{
//CERR << "COPY\n";
LOCK(&cache->lock);
refcount++;
}
void GlobalCacheBase::del(Cacheable * n)
{
*n->prev = n->next;
if (n->next) n->next->prev = n->prev;
n->next = 0;
n->prev = 0;
}
void GlobalCacheBase::add(Cacheable * n)
{
assert(n->refcount > 0);
n->next = first;
n->prev = &first;
if (first) first->prev = &n->next;
first = n;
n->cache = this;
}
void GlobalCacheBase::release(Cacheable * d)
{
//CERR << "RELEASE\n";
LOCK(&lock);
d->refcount--;
assert(d->refcount >= 0);
if (d->refcount != 0) return;
//CERR << "DEL\n";
if (d->attached()) del(d);
delete d;
}
void GlobalCacheBase::detach(Cacheable * d)
{
LOCK(&lock);
if (d->attached()) del(d);
}
void GlobalCacheBase::detach_all()
{
LOCK(&lock);
Cacheable * p = first;
while (p) {
*p->prev = 0;
p->prev = 0;
p = p->next;
}
}
void release_cache_data(GlobalCacheBase * cache, const Cacheable * d)
{
cache->release(const_cast<Cacheable *>(d));
}
GlobalCacheBase::GlobalCacheBase(const char * n)
: name (n)
{
LOCK(global_cache_lock);
next = first_cache;
prev = &first_cache;
if (first_cache) first_cache->prev = &next;
first_cache = this;
}
GlobalCacheBase::~GlobalCacheBase()
{
detach_all();
LOCK(global_cache_lock);
*prev = next;
if (next) next->prev = prev;
}
bool reset_cache(const char * which)
{
LOCK(global_cache_lock);
bool any = false;
for (GlobalCacheBase * i = first_cache; i; i = i->next)
{
if (which && strcmp(i->name, which) == 0) {i->detach_all(); any = true;}
}
return any;
}
extern "C"
int aspell_reset_cache(const char * which)
{
return reset_cache(which);
}
#if 0
struct CacheableImpl : public Cacheable
{
class CacheConfig;
typedef String CacheKey;
bool cache_key_eq(const CacheKey &);
static PosibErr<CacheableImpl *> get_new(const CacheKey &, CacheConfig *);
};
template
PosibErr<CacheableImpl *> get_cache_data(GlobalCache<CacheableImpl> *,
CacheableImpl::CacheConfig *,
const CacheableImpl::CacheKey &);
#endif
}
|