/[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 2427 by persson, Sat Mar 2 07:03:04 2013 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2005 - 2007 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2013 Christian Schoenebeck                       *
4   *                                                                         *   *                                                                         *
5   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# 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));
         // already tell the engine which instrument to load  
         pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrumentIndex);  
48    
49            // the listener only needs to be registered once in the
50            // Sampler, but as we don't know if Sampler has been
51            // recreated, we simply remove and add every time
52            pEngineChannel->GetSampler()->RemoveChannelCountListener(&eventHandler);
53            pEngineChannel->GetSampler()->AddChannelCountListener(&eventHandler);
54            
55          command_t cmd;          command_t cmd;
56          cmd.type           = command_t::DIRECT_LOAD;          cmd.type           = command_t::DIRECT_LOAD;
57          cmd.pEngineChannel = pEngineChannel;          cmd.pEngineChannel = pEngineChannel;
58            cmd.instrumentId.Index = uiInstrumentIndex;
59            cmd.instrumentId.FileName = Filename;
60    
61          mutex.Lock();          {
62          queue.push_back(cmd);              LockGuard lock(mutex);
63          mutex.Unlock();              queue.push_back(cmd);
64            }
65    
66          StartThread(); // ensure thread is running          StartThread(); // ensure thread is running
67          conditionJobsLeft.Set(true); // wake up thread          conditionJobsLeft.Set(true); // wake up thread
# Line 77  namespace LinuxSampler { Line 86  namespace LinuxSampler {
86          cmd.instrumentId = ID;          cmd.instrumentId = ID;
87          cmd.mode         = Mode;          cmd.mode         = Mode;
88    
89          mutex.Lock();          {
90          queue.push_back(cmd);              LockGuard lock(mutex);
91          mutex.Unlock();              queue.push_back(cmd);
92            }
93    
94          StartThread(); // ensure thread is running          StartThread(); // ensure thread is running
95          conditionJobsLeft.Set(true); // wake up thread          conditionJobsLeft.Set(true); // wake up thread
# 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              while (!queue.empty()) {  
102                #if CONFIG_PTHREAD_TESTCANCEL
103                TestCancel();
104                #endif
105    
106                while (true) {
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();                  {
111                  cmd = queue.front();                      LockGuard lock(mutex);
112                  mutex.Unlock();                      if (queue.empty()) break;
113    
114                        cmd = queue.front();
115                        queue.pop_front();
116    
117                        if (cmd.type == command_t::DIRECT_LOAD) {
118                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
119                        }
120                    }
121    
122                  try {                  try {
123                      switch (cmd.type) {                      switch (cmd.type) {
124                          case command_t::DIRECT_LOAD:                          case command_t::DIRECT_LOAD:
125                                cmd.pEngineChannel->PrepareLoadInstrument(cmd.instrumentId.FileName.c_str(), cmd.instrumentId.Index);
126                              cmd.pEngineChannel->LoadInstrument();                              cmd.pEngineChannel->LoadInstrument();
127                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
128                              break;                              break;
129                          case command_t::INSTR_MODE:                          case command_t::INSTR_MODE:
130                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
# Line 109  namespace LinuxSampler { Line 134  namespace LinuxSampler {
134                      }                      }
135                  } catch (Exception e) {                  } catch (Exception e) {
136                      e.PrintMessage();                      e.PrintMessage();
137                        if (cmd.type == command_t::DIRECT_LOAD) {
138                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
139                        }
140                  } catch (...) {                  } catch (...) {
141                      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;
142                        if (cmd.type == command_t::DIRECT_LOAD) {
143                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
144                        }
145                  }                  }
   
                 // remove processed command from queue  
                 mutex.Lock();  
                 queue.pop_front();  
                 mutex.Unlock();  
146              }              }
147    
148              // nothing left to do, sleep until new jobs arrive              // nothing left to do, sleep until new jobs arrive
# Line 126  namespace LinuxSampler { Line 152  namespace LinuxSampler {
152              // unlock condition object so it can be turned again by other thread              // unlock condition object so it can be turned again by other thread
153              conditionJobsLeft.Unlock();              conditionJobsLeft.Unlock();
154          }          }
155            return 0;
156        }
157    
158        void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
159            /*
160               Removing from the queue an eventual scheduled loading of an instrument
161               to a sampler channel which is going to be removed.
162            */
163            LockGuard lock(pThread->mutex);
164            std::list<command_t>::iterator it;
165            for (it = pThread->queue.begin(); it != pThread->queue.end();){
166                if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
167                if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
168                    it = pThread->queue.erase(it);
169                    // we don't break here because the same engine channel could
170                    // occur more than once in the queue, so don't make optimizations
171                } else {
172                    ++it;
173                }
174            }
175        }
176    
177    #if defined(__APPLE__) && !defined(__x86_64__)
178        int InstrumentManagerThread::StopThread() {
179            // This is a fix for Mac OS X 32 bit, where SignalStopThread
180            // doesn't wake up a thread waiting for a condition variable.
181            SignalStopThread(); // send stop signal, but don't wait
182            conditionJobsLeft.Set(true); // wake thread
183            return Thread::StopThread(); // then wait for it to cancel
184        }
185    #endif
186    
187    #ifdef WIN32
188        int InstrumentManagerThread::StopThread() {
189            int res = Thread::StopThread();
190            conditionJobsLeft.Reset();
191            return res;
192      }      }
193    #endif
194    
195  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC