diff options
-rw-r--r-- | src/cachemanager.cc | 98 | ||||
-rw-r--r-- | src/cachemanager.h | 10 |
2 files changed, 67 insertions, 41 deletions
diff --git a/src/cachemanager.cc b/src/cachemanager.cc index c035703..719df17 100644 --- a/src/cachemanager.cc +++ b/src/cachemanager.cc @@ -66,86 +66,106 @@ sample_t *CacheManager::open(AudioFile *file, int initial_samples_needed, int ch availableids.pop_front(); m_ids.unlock(); - cache_t c; - c.file = file; - c.channel = channel; - c.pos = initial_samples_needed; - // Allocate buffers - // Increase audio ref count - - id2cache[id] = c; + if(initial_samples_needed < file->size) { + cache_t c; + c.file = file; + c.channel = channel; + c.pos = initial_samples_needed; + + // Allocate buffers + // Increase audio ref count + + id2cache[id] = c; - event_t e; - e.id = id; - pushEvent(e); + event_t e = createEvent(id, LOADNEXT); + pushEvent(e); + } return file->data; } void CacheManager::close(cacheid_t id) { - m_ids.lock(); - availableids.push_back(id); - m_ids.unlock(); - + { + event_t e = createEvent(id, CLEAN); + MutexAutolock l(m_events); + eventqueue.push_front(e); + } + + { + MutexAutolock l(m_ids); + availableids.push_back(id); + } // Clean cache_t mapped to event - // Clean event list for other events mapped to this id? - // Maybe we need an event for this, that we can push in front of eventqueue (con: we dont read from disk when doing this stuff). // Decrement audiofile ref count } sample_t *CacheManager::next(cacheid_t id, size_t &size) { - cache_t *c; - { - MutexAutolock l(m_caches); - c = &id2cache[id]; - } size = CHUNKSIZE; - sample_t *s = c->file->data + c->pos; - c->pos += size; + m_caches.lock(); + cache_t c = id2cache[id]; + c.pos += size; + id2cache[id] = c; + m_caches.unlock(); + + // If more is left of file + if(c.pos < c.file->size) { + event_t e = createEvent(id, LOADNEXT); + pushEvent(e); + } + + sample_t *s = c.file->data + c.pos; return s; } void CacheManager::loadNext(cacheid_t id) { - m_caches.lock(); + MutexAutolock l(m_caches); cache_t c = id2cache[id]; c.pos += CHUNKSIZE; id2cache[id] = c; - m_caches.unlock(); - - // If more is left of file - if(c.pos < c.file->size) { - event_t e; - e.id = id; - pushEvent(e); - } } void CacheManager::thread_main() { while(running) { sem.wait(); - + m_events.lock(); if(eventqueue.empty()) { event_t e = eventqueue.front(); eventqueue.pop_front(); m_events.unlock(); - - loadNext(e.id); + + if(!e.active) continue; + + switch(e.cmd) { + case LOADNEXT: + loadNext(e.id); + break; + case CLEAN: + break; + } } else { m_events.unlock(); - } + } } } void CacheManager::pushEvent(event_t e) { // Check that if event should be merged (Maybe by event queue (ie. push in front). - m_events.lock(); + MutexAutolock l(m_events); eventqueue.push_back(e); - m_events.unlock(); +} + +CacheManager::event_t CacheManager::createEvent(cacheid_t id, cmd_t cmd) +{ + event_t e; + e.active = true; + e.id = id; + e.cmd = cmd; + return e; } diff --git a/src/cachemanager.h b/src/cachemanager.h index b30de4c..6a14429 100644 --- a/src/cachemanager.h +++ b/src/cachemanager.h @@ -91,14 +91,20 @@ private: void *b; } cache_t; + enum cmd_t { + LOADNEXT = 0, + CLEAN = 1 + }; + typedef struct { + bool active; cacheid_t id; + cmd_t cmd; } event_t; + CacheManager::event_t createEvent(cacheid_t id, cmd_t type); void loadNext(cacheid_t id); void pushEvent(event_t e); - cacheid_t leaseId(); - cacheid_t releaseId(); // Protected by mutex std::list<event_t> eventqueue; |