From 3dcc42c508dd798b9034f77e6f83ec75e648936c Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Thu, 25 Apr 2013 21:43:48 +0200
Subject: Fix crash on 'load drumkit' while another drumkit is already loading.

---
 src/drumgizmo.cc     | 13 +++++++------
 src/drumkitloader.cc | 18 +++++++++++++++---
 src/drumkitloader.h  |  5 ++++-
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index b5e5c63..8ba45f5 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -145,6 +145,8 @@ bool DrumGizmo::loadkit(std::string file)
 
   DEBUG(drumgizmo, "loadkit(%s)\n", kitfile.c_str());
 
+  loader.skip();
+
   kit.clear();
 
   DrumKitParser parser(kitfile, kit);
@@ -288,7 +290,6 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
         continue;
       }
 
-#if 1
       if(i->group() != "") {
         // Add event to ramp down all existing events with the same groupname.
         Channels::iterator j = kit.channels.begin();
@@ -311,7 +312,6 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
           j++;
         }
       }
-#endif   
 
       Sample *s = i->sample(evs[e].velocity, evs[e].offset + pos);
       
@@ -348,7 +348,6 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
   //
   // Write audio
   //
-  
   for(size_t c = 0; c < kit.channels.size(); c++) {
     sample_t *buf = samples;
     bool internal = false;
@@ -356,9 +355,11 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
       buf = oe->getBuffer(c);
       internal = true;
     }
-    memset(buf, 0, nsamples * sizeof(sample_t));
-    getSamples(c, pos, buf, nsamples);
-    if(!internal) oe->run(c, samples, nsamples);
+    if(buf) {
+      memset(buf, 0, nsamples * sizeof(sample_t));
+      getSamples(c, pos, buf, nsamples);
+      if(!internal) oe->run(c, samples, nsamples);
+    }
   }
   
   ie->post();
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index c997dfb..79d000a 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -36,6 +36,7 @@ DrumKitLoader::DrumKitLoader(DrumGizmo *dg)
   drumgizmo = dg;
   is_done = false;
   quitit = false;
+  skipit = false;
 }
 
 DrumKitLoader::~DrumKitLoader()
@@ -52,6 +53,13 @@ void DrumKitLoader::stop()
   wait_stop();
 }
 
+void DrumKitLoader::skip()
+{
+  skipit = true;
+  semaphore.post();
+  skip_semaphore.wait();
+}
+
 bool DrumKitLoader::isDone()
 {
   bool done;
@@ -74,8 +82,6 @@ void DrumKitLoader::loadKit(DrumKit *kit)
   semaphore.post();
 }
 
-
-
 void DrumKitLoader::thread_main()
 {
   while(1) {
@@ -86,6 +92,12 @@ void DrumKitLoader::thread_main()
 
     if(quitit) return;
 
+    if(skipit) {
+      skip_semaphore.post();
+      skipit = false;
+      continue;
+    }
+
     unsigned int count = 0;
 
     if(kit && !kit->isValid()) goto finish;
@@ -133,7 +145,7 @@ void DrumKitLoader::thread_main()
           
           a++;
 
-          if(quitit) return;
+          if(skipit) goto finish;
         }
         
         i++;
diff --git a/src/drumkitloader.h b/src/drumkitloader.h
index f614ea0..50b8236 100644
--- a/src/drumkitloader.h
+++ b/src/drumkitloader.h
@@ -49,14 +49,17 @@ public:
   bool isDone();
 
   void stop();
+  void skip();
 
 private:
   DrumGizmo *drumgizmo;
   Semaphore semaphore;
+  Semaphore skip_semaphore;
   DrumKit *kit;
   bool is_done;
   Mutex mutex;
-  bool quitit;
+  volatile bool quitit;
+  volatile bool skipit;
 };
 
 #endif/*__DRUMGIZMO_DRUMKITLOADER_H__*/
-- 
cgit v1.2.3