/[svn]/linuxsampler/trunk/src/engines/InstrumentManagerThread.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/InstrumentManagerThread.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1424 by schoenebeck, Sun Oct 14 22:00:17 2007 UTC revision 2185 by persson, Sun Jun 19 09:09:38 2011 UTC
# Line 21  Line 21 
21  #include "InstrumentManagerThread.h"  #include "InstrumentManagerThread.h"
22    
23  #include "../common/global_private.h"  #include "../common/global_private.h"
24    #include "EngineChannelFactory.h"
25    
26  namespace LinuxSampler {  namespace LinuxSampler {
27    
28      InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {      InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {
29            eventHandler.pThread = this;
30      }      }
31    
32      InstrumentManagerThread::~InstrumentManagerThread() {      InstrumentManagerThread::~InstrumentManagerThread() {
# Line 43  namespace LinuxSampler { Line 45  namespace LinuxSampler {
45       */       */
46      void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {      void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {
47          dmsg(1,("Scheduling '%s' (Index=%d) to be loaded in background (if not loaded yet).\n",Filename.c_str(),uiInstrumentIndex));          dmsg(1,("Scheduling '%s' (Index=%d) to be loaded in background (if not loaded yet).\n",Filename.c_str(),uiInstrumentIndex));
48    
49            static bool listenerRegistered = false;
50            if (!listenerRegistered) {
51                pEngineChannel->GetSampler()->AddChannelCountListener(&eventHandler);
52                listenerRegistered = true;
53            }
54            
55            
56          // already tell the engine which instrument to load          // already tell the engine which instrument to load
57          pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrumentIndex);          pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrumentIndex);
58    
# Line 88  namespace LinuxSampler { Line 98  namespace LinuxSampler {
98      // Entry point for the task thread.      // Entry point for the task thread.
99      int InstrumentManagerThread::Main() {      int InstrumentManagerThread::Main() {
100          while (true) {          while (true) {
101    
102                #if CONFIG_PTHREAD_TESTCANCEL
103                TestCancel();
104                #endif
105    
106              while (!queue.empty()) {              while (!queue.empty()) {
107                  command_t cmd;                  command_t cmd;
108    
109                  // grab a new command from the queue                  // grab a new command from the queue
110                  mutex.Lock();                  mutex.Lock();
111                  cmd = queue.front();                  cmd = queue.front();
112                    queue.pop_front();
113                  mutex.Unlock();                  mutex.Unlock();
114    
115                  try {                  try {
116                      switch (cmd.type) {                      switch (cmd.type) {
117                          case command_t::DIRECT_LOAD:                          case command_t::DIRECT_LOAD:
118                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
119                              cmd.pEngineChannel->LoadInstrument();                              cmd.pEngineChannel->LoadInstrument();
120                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
121                              break;                              break;
122                          case command_t::INSTR_MODE:                          case command_t::INSTR_MODE:
123                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
# Line 109  namespace LinuxSampler { Line 127  namespace LinuxSampler {
127                      }                      }
128                  } catch (Exception e) {                  } catch (Exception e) {
129                      e.PrintMessage();                      e.PrintMessage();
130                        if (cmd.type == command_t::DIRECT_LOAD) {
131                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
132                        }
133                  } catch (...) {                  } catch (...) {
134                      std::cerr << "InstrumentManagerThread: some exception occured, could not finish task\n" << std::flush;                      std::cerr << "InstrumentManagerThread: some exception occured, could not finish task\n" << std::flush;
135                        if (cmd.type == command_t::DIRECT_LOAD) {
136                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
137                        }
138                  }                  }
   
                 // remove processed command from queue  
                 mutex.Lock();  
                 queue.pop_front();  
                 mutex.Unlock();  
139              }              }
140    
141              // nothing left to do, sleep until new jobs arrive              // nothing left to do, sleep until new jobs arrive
# Line 126  namespace LinuxSampler { Line 145  namespace LinuxSampler {
145              // unlock condition object so it can be turned again by other thread              // unlock condition object so it can be turned again by other thread
146              conditionJobsLeft.Unlock();              conditionJobsLeft.Unlock();
147          }          }
148            return 0;
149        }
150    
151        void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
152            /*
153               Removing from the queue an eventual scheduled loading of an instrument
154               to a sampler channel which is going to be removed.
155            */
156            pThread->mutex.Lock();
157            std::list<command_t>::iterator it;
158            for (it = pThread->queue.begin(); it != pThread->queue.end();){
159                if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
160                if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
161                    it = pThread->queue.erase(it);
162                    // we don't break here because the same engine channel could
163                    // occur more than once in the queue, so don't make optimizations
164                } else {
165                    ++it;
166                }
167            }
168            pThread->mutex.Unlock();
169        }
170    
171        int InstrumentManagerThread::StopThread() {
172            // This is a fix for Mac OS X, where SignalStopThread doesn't
173            // wake up a thread waiting for a condition variable.
174            SignalStopThread(); // send stop signal, but don't wait
175            conditionJobsLeft.Set(true); // wake thread
176            return Thread::StopThread(); // then wait for it to cancel
177      }      }
178    
179  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.1424  
changed lines
  Added in v.2185

  ViewVC Help
Powered by ViewVC