From 331be8dc452bf47705556d2a7f7f5988973930ca Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Sun, 7 Apr 2013 13:01:34 +0200
Subject: Fixed crashbug on drumkit reload.

---
 src/audiofile.cc     |  8 ++++++++
 src/audiofile.h      |  3 +++
 src/drumgizmo.cc     |  8 ++++++++
 src/drumkit.cc       | 17 +++++++++++++++++
 src/drumkit.h        |  7 +++++++
 src/drumkitloader.cc | 13 +++++++++++++
 src/instrument.cc    |  9 +++++++++
 src/instrument.h     |  4 ++++
 8 files changed, 69 insertions(+)

(limited to 'src')

diff --git a/src/audiofile.cc b/src/audiofile.cc
index 3f0bd82..5a9cdb5 100644
--- a/src/audiofile.cc
+++ b/src/audiofile.cc
@@ -42,15 +42,23 @@ AudioFile::AudioFile(std::string filename)
   data = NULL;
   size = 0;
 
+  magic = this;
+
   //load();
 }
 
 AudioFile::~AudioFile()
 {
+  magic = NULL;
   //printf("delete AudioFile %p\n", this);
   unload();
 }
 
+bool AudioFile::isValid()
+{
+  return this == magic;
+}
+
 void AudioFile::unload()
 {
   if(data) {
diff --git a/src/audiofile.h b/src/audiofile.h
index 17ff651..e4b8410 100644
--- a/src/audiofile.h
+++ b/src/audiofile.h
@@ -48,7 +48,10 @@ public:
 
   std::string filename;
 
+  bool isValid();
+
 private:
+  void *magic;
   Mutex mutex;
   bool is_loaded;
 };
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 219ec7b..5391cdd 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -143,6 +143,8 @@ bool DrumGizmo::loadkit(std::string file)
 
   DEBUG(drumgizmo, "loadkit(%s)\n", kitfile.c_str());
 
+  kit.clear();
+
   DrumKitParser parser(kitfile, kit);
   if(parser.parse()) {
     ERR(drumgizmo, "Drumkit parser failed: %s\n", kitfile.c_str());
@@ -233,6 +235,8 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
   // Handle engine messages, at most one in each iteration:
   handleEngineEvents();
 
+  if(!samples) return true;
+
   ie->pre();
   oe->pre(nsamples);
 
@@ -255,9 +259,13 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
         }
       */
       
+      if(!kit.isValid()) continue;
+
       if(d < (int)kit.instruments.size()) {
         i = kit.instruments[d];
       }
+
+      if(!i->isValid()) continue;
       
       if(i == NULL) {
         ERR(drumgizmo, "Missing Instrument %d.\n", evs[e].instrument);
diff --git a/src/drumkit.cc b/src/drumkit.cc
index 00ab2e2..caceafb 100644
--- a/src/drumkit.cc
+++ b/src/drumkit.cc
@@ -26,13 +26,30 @@
  */
 #include "drumkit.h"
 
+DrumKit::DrumKit()
+{
+  magic = this;
+}
+
 DrumKit::~DrumKit()
+{
+  magic = NULL;
+  clear();
+}
+
+void DrumKit::clear()
 {
   Instruments::iterator i = instruments.begin();
   while(i != instruments.end()) {
     delete *i;
     i++;
   }
+  instruments.clear();
+}
+
+bool DrumKit::isValid()
+{
+  return this == magic;
 }
 
 std::string DrumKit::name()
diff --git a/src/drumkit.h b/src/drumkit.h
index d25b6b3..2ed558d 100644
--- a/src/drumkit.h
+++ b/src/drumkit.h
@@ -37,6 +37,7 @@ class DrumKitParser;
 class DrumKit {
   friend class DrumKitParser;
 public:
+  DrumKit();
   ~DrumKit();
 
   std::string name();
@@ -45,7 +46,13 @@ public:
   Instruments instruments;
   Channels channels;
  
+  void clear();
+
+  bool isValid();
+
 private:
+  void *magic;
+
   std::string _name;
   std::string _description;
 };
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index ed1a187..45dcec3 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -68,6 +68,7 @@ void DrumKitLoader::loadKit(DrumKit *kit)
 }
 
 
+
 void DrumKitLoader::thread_main()
 {
   while(1) {
@@ -79,10 +80,14 @@ void DrumKitLoader::thread_main()
     if(quitit) return;
 
     unsigned int count = 0;
+
+    if(!kit->isValid()) goto finish;
+
     { // Count total number of files that need loading:
       Instruments::iterator i = kit->instruments.begin();
       while(i != kit->instruments.end()) {
         Instrument *instr = *i;
+        if(!instr->isValid()) goto finish;
 
         count += instr->audiofiles.size();
         i++;
@@ -95,6 +100,8 @@ void DrumKitLoader::thread_main()
       while(i != kit->instruments.end()) {
         Instrument *instr = *i;
         
+        if(!instr->isValid()) goto finish;
+
         std::vector<AudioFile*>::iterator a = instr->audiofiles.begin();
         while(a != instr->audiofiles.end()) {
 #if 0
@@ -105,6 +112,9 @@ void DrumKitLoader::thread_main()
 #endif/*WIN32*/
 #endif
           AudioFile *af = *a;
+
+          if(!af->isValid()) goto finish;
+
           af->load();
           loaded++;
 
@@ -124,6 +134,9 @@ void DrumKitLoader::thread_main()
     mutex.lock();
     is_done = true;
     mutex.unlock();
+
+  finish:
+    continue;
   }
 }
 
diff --git a/src/instrument.cc b/src/instrument.cc
index 297e6c6..22b6a90 100644
--- a/src/instrument.cc
+++ b/src/instrument.cc
@@ -39,10 +39,14 @@ Instrument::Instrument()
   DEBUG(instrument, "new %p\n", this);
   mod = 1.0;
   lastpos = 0;
+
+  magic = this;
 }
 
 Instrument::~Instrument()
 {
+  magic = NULL;
+
   DEBUG(instrument, "delete %p\n", this);
   std::vector<AudioFile*>::iterator i = audiofiles.begin();
   while(i != audiofiles.end()) {
@@ -51,6 +55,11 @@ Instrument::~Instrument()
   }
 }
 
+bool Instrument::isValid()
+{
+  return this == magic;
+}
+
 Sample *Instrument::sample(level_t level, size_t pos)
 {
   if(Conf::enable_velocity_modifier == false) {
diff --git a/src/instrument.h b/src/instrument.h
index 9b110be..b146cb2 100644
--- a/src/instrument.h
+++ b/src/instrument.h
@@ -50,7 +50,11 @@ public:
 
   std::vector<AudioFile*> audiofiles;
 
+  bool isValid();
+
 private:
+  void *magic;
+
   std::string _name;
   std::string _description;
   RangeMap<level_t, Sample*> samples;
-- 
cgit v1.2.3