From 2067d8af88cdeb14ecee0deaaeb873e3bc1eb513 Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Sun, 12 Apr 2015 11:27:31 +0200
Subject: Added close event to free cache buffers.

---
 src/cachemanager.cc | 44 +++++++++++++++++++++++++++++++++-----------
 src/cachemanager.h  | 38 +++++++++++++++++++++++---------------
 2 files changed, 56 insertions(+), 26 deletions(-)

(limited to 'src')

diff --git a/src/cachemanager.cc b/src/cachemanager.cc
index d3fdd9e..f7d155b 100644
--- a/src/cachemanager.cc
+++ b/src/cachemanager.cc
@@ -101,7 +101,8 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed, int
   }
 
   if(initial_samples_needed < file->size) {
-    cevent_t e = createLoadNextEvent(c.file, c.pos + CHUNKSIZE, c.back);
+    cevent_t e =
+      createLoadNextEvent(c.file, c.channel, c.pos + CHUNKSIZE, c.back);
     pushEvent(e);
   }
 
@@ -112,6 +113,9 @@ void CacheManager::close(cacheid_t id)
 {
   if(id == CACHE_DUMMYID) return;
 
+  cevent_t e = createCloseEvent(id);
+  pushEvent(e);
+
   {
 //    event_t e = createEvent(id, CLEAN);
 //    MutexAutolock l(m_events); 
@@ -150,18 +154,26 @@ sample_t *CacheManager::next(cacheid_t id, size_t &size)
   c.pos += CHUNKSIZE;
   
   if(c.pos < c.file->size) {
-    cevent_t e = createLoadNextEvent(c.file, c.pos, c.back);
+    cevent_t e = createLoadNextEvent(c.file, c.channel, c.pos, c.back);
     pushEvent(e);
   } 
 
   return c.front;
 }
 
-void CacheManager::loadNext(cevent_t &e) 
+void CacheManager::handleLoadNextEvent(cevent_t &e) 
 {
   memcpy(e.buffer, e.file->data + e.pos, CHUNKSIZE * sizeof(sample_t));
 }
 
+void CacheManager::handleCloseEvent(cevent_t &e) 
+{
+  cache_t& c = id2cache[e.id];
+  delete[] c.front;
+  delete[] c.back;
+  // TODO: Count down ref coutner on c.file and close it if 0.
+}
+
 void CacheManager::thread_main()
 {
   while(running) {
@@ -178,13 +190,13 @@ void CacheManager::thread_main()
 
       switch(e.cmd) {  
         case LOADNEXT:
-          loadNext(e);
+          handleLoadNextEvent(e);
+          break;
+        case CLOSE:
+          handleCloseEvent(e);
           break;
-//        case CLEAN:
-//          break;
       }      
-    }
-    else {
+    } else {
       m_events.unlock();
     }
   }
@@ -200,14 +212,24 @@ void CacheManager::pushEvent(cevent_t e)
   sem.post();
 }
 
-CacheManager::cevent_t CacheManager::createLoadNextEvent(AudioFile *file,
-                                                         size_t pos,
-                                                         sample_t* buffer)
+CacheManager::cevent_t
+CacheManager::createLoadNextEvent(AudioFile *file, size_t channel, size_t pos,
+                                  sample_t* buffer)
 {
   cevent_t e;
   e.cmd = LOADNEXT;
   e.pos = pos;
   e.buffer = buffer;
   e.file = file;
+  e.channel = channel;
+  return e; 
+}
+
+CacheManager::cevent_t
+CacheManager::createCloseEvent(cacheid_t id)
+{
+  cevent_t e;
+  e.cmd = CLOSE;
+  e.id = id;
   return e; 
 }
diff --git a/src/cachemanager.h b/src/cachemanager.h
index 557ba23..21579d9 100644
--- a/src/cachemanager.h
+++ b/src/cachemanager.h
@@ -131,46 +131,54 @@ public:
   void thread_main();
 
 private:
-
-  void pushEvent();
-
   typedef struct {
     AudioFile *file;
-    int channel;
-    size_t pos;
+    size_t channel;
+    size_t pos; //< File possition
     sample_t *front;
     sample_t *back;
-    size_t localpos;
+    size_t localpos; //< Intra buffer (front) position.
   } cache_t;
 
-  enum cmd_t {
+  typedef enum {
     LOADNEXT = 0,
-//    CLEAN = 1
-  };
+    CLOSE = 1
+  } cmd_t;
 
   typedef struct {
     cmd_t cmd;
+
+    // For close event:
+    cacheid_t id;
+
+    // For load next event:
     size_t pos;
     sample_t *buffer;
     AudioFile *file;
+    size_t channel;
   } cevent_t;
 
-  cevent_t createLoadNextEvent(AudioFile *file, size_t pos, sample_t* buffer);
-  void loadNext(cevent_t &e);
+  cevent_t createLoadNextEvent(AudioFile *file, size_t channel, size_t pos,
+                               sample_t* buffer);
+  cevent_t createCloseEvent(cacheid_t id);
+
+  void handleLoadNextEvent(cevent_t &e);
+  void handleCloseEvent(cevent_t &e);
+
   void pushEvent(cevent_t e);
 
-  // Protected by mutex
+  std::vector<cache_t> id2cache; 
+
+  // Protected by mutex:
   std::list<cevent_t> eventqueue;
   std::list<cacheid_t> availableids; 
-  std::vector<cache_t> id2cache; 
   
   Mutex m_events;
   Mutex m_ids;
-  Mutex m_caches;
 
   Semaphore sem;
 
-  int running;
+  bool running;
 };
 
 #endif/*__DRUMGIZMO_CACHEMANAGER_H__*/
-- 
cgit v1.2.3