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; | 
