/[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 970 by schoenebeck, Wed Dec 6 22:28:17 2006 UTC revision 2324 by persson, Sun Mar 4 09:01:32 2012 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2005, 2006 Christian Schoenebeck                        *   *   Copyright (C) 2005 - 2012 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 20  Line 20 
20    
21  #include "InstrumentManagerThread.h"  #include "InstrumentManagerThread.h"
22    
23    #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          pQueue = new RingBuffer<command_t,true>(INSTRUMENT_LOADER_QUEUE_SIZE);          eventHandler.pThread = this;
30      }      }
31    
32      InstrumentManagerThread::~InstrumentManagerThread() {      InstrumentManagerThread::~InstrumentManagerThread() {
         if (pQueue) delete pQueue;  
33      }      }
34    
35      /**      /**
# Line 42  namespace LinuxSampler { Line 44  namespace LinuxSampler {
44       * @param pEngineChannel - engine channel on which the instrument should be loaded       * @param pEngineChannel - engine channel on which the instrument should be loaded
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).",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          pQueue->push(&cmd);          cmd.instrumentId.Index = uiInstrumentIndex;
59            cmd.instrumentId.FileName = Filename;
60    
61            mutex.Lock();
62            queue.push_back(cmd);
63            mutex.Unlock();
64    
65          StartThread(); // ensure thread is running          StartThread(); // ensure thread is running
66          conditionJobsLeft.Set(true); // wake up thread          conditionJobsLeft.Set(true); // wake up thread
67      }      }
# Line 72  namespace LinuxSampler { Line 84  namespace LinuxSampler {
84          cmd.pManager     = pManager;          cmd.pManager     = pManager;
85          cmd.instrumentId = ID;          cmd.instrumentId = ID;
86          cmd.mode         = Mode;          cmd.mode         = Mode;
87          pQueue->push(&cmd);  
88            mutex.Lock();
89            queue.push_back(cmd);
90            mutex.Unlock();
91    
92          StartThread(); // ensure thread is running          StartThread(); // ensure thread is running
93          conditionJobsLeft.Set(true); // wake up thread          conditionJobsLeft.Set(true); // wake up thread
94      }      }
# Line 80  namespace LinuxSampler { Line 96  namespace LinuxSampler {
96      // Entry point for the task thread.      // Entry point for the task thread.
97      int InstrumentManagerThread::Main() {      int InstrumentManagerThread::Main() {
98          while (true) {          while (true) {
99              while (pQueue->read_space()) {  
100                #if CONFIG_PTHREAD_TESTCANCEL
101                TestCancel();
102                #endif
103    
104                while (true) {
105                  command_t cmd;                  command_t cmd;
106                  pQueue->pop(&cmd);  
107                    // grab a new command from the queue
108                    mutex.Lock();
109                    bool empty = queue.empty();
110                    if (!empty) {
111                        cmd = queue.front();
112                        queue.pop_front();
113                    }
114                    mutex.Unlock();
115                    if (empty) break;
116    
117                  try {                  try {
118                      switch (cmd.type) {                      switch (cmd.type) {
119                          case command_t::DIRECT_LOAD:                          case command_t::DIRECT_LOAD:
120                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
121                                cmd.pEngineChannel->PrepareLoadInstrument(cmd.instrumentId.FileName.c_str(), cmd.instrumentId.Index);
122                              cmd.pEngineChannel->LoadInstrument();                              cmd.pEngineChannel->LoadInstrument();
123                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
124                              break;                              break;
125                          case command_t::INSTR_MODE:                          case command_t::INSTR_MODE:
126                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
# Line 94  namespace LinuxSampler { Line 128  namespace LinuxSampler {
128                          default:                          default:
129                              std::cerr << "InstrumentManagerThread: unknown command - BUG!\n" << std::flush;                              std::cerr << "InstrumentManagerThread: unknown command - BUG!\n" << std::flush;
130                      }                      }
131                  }                  } catch (Exception e) {
                 catch (Exception e) {  
132                      e.PrintMessage();                      e.PrintMessage();
133                        if (cmd.type == command_t::DIRECT_LOAD) {
134                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
135                        }
136                    } catch (...) {
137                        std::cerr << "InstrumentManagerThread: some exception occured, could not finish task\n" << std::flush;
138                        if (cmd.type == command_t::DIRECT_LOAD) {
139                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
140                        }
141                  }                  }
142              }              }
143    
# Line 107  namespace LinuxSampler { Line 148  namespace LinuxSampler {
148              // unlock condition object so it can be turned again by other thread              // unlock condition object so it can be turned again by other thread
149              conditionJobsLeft.Unlock();              conditionJobsLeft.Unlock();
150          }          }
151            return 0;
152        }
153    
154        void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
155            /*
156               Removing from the queue an eventual scheduled loading of an instrument
157               to a sampler channel which is going to be removed.
158            */
159            pThread->mutex.Lock();
160            std::list<command_t>::iterator it;
161            for (it = pThread->queue.begin(); it != pThread->queue.end();){
162                if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
163                if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
164                    it = pThread->queue.erase(it);
165                    // we don't break here because the same engine channel could
166                    // occur more than once in the queue, so don't make optimizations
167                } else {
168                    ++it;
169                }
170            }
171            pThread->mutex.Unlock();
172        }
173    
174    #ifdef __APPLE__
175        int InstrumentManagerThread::StopThread() {
176            // This is a fix for Mac OS X, where SignalStopThread doesn't
177            // wake up a thread waiting for a condition variable.
178            SignalStopThread(); // send stop signal, but don't wait
179            conditionJobsLeft.Set(true); // wake thread
180            return Thread::StopThread(); // then wait for it to cancel
181        }
182    #endif
183    
184    #ifdef WIN32
185        int InstrumentManagerThread::StopThread() {
186            int res = Thread::StopThread();
187            conditionJobsLeft.Reset();
188            return res;
189      }      }
190    #endif
191    
192  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.970  
changed lines
  Added in v.2324

  ViewVC Help
Powered by ViewVC