/[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 2349 by persson, Sun Jun 17 15:47:43 2012 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2005 - 2007 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 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    #ifdef __APPLE__
27    #include <sys/utsname.h>
28    #endif
29    
30  namespace LinuxSampler {  namespace LinuxSampler {
31    
32      InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {      InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {
33            eventHandler.pThread = this;
34      }      }
35    
36      InstrumentManagerThread::~InstrumentManagerThread() {      InstrumentManagerThread::~InstrumentManagerThread() {
# Line 43  namespace LinuxSampler { Line 49  namespace LinuxSampler {
49       */       */
50      void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {      void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {
51          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);  
52    
53            // the listener only needs to be registered once in the
54            // Sampler, but as we don't know if Sampler has been
55            // recreated, we simply remove and add every time
56            pEngineChannel->GetSampler()->RemoveChannelCountListener(&eventHandler);
57            pEngineChannel->GetSampler()->AddChannelCountListener(&eventHandler);
58            
59          command_t cmd;          command_t cmd;
60          cmd.type           = command_t::DIRECT_LOAD;          cmd.type           = command_t::DIRECT_LOAD;
61          cmd.pEngineChannel = pEngineChannel;          cmd.pEngineChannel = pEngineChannel;
62            cmd.instrumentId.Index = uiInstrumentIndex;
63            cmd.instrumentId.FileName = Filename;
64    
65          mutex.Lock();          mutex.Lock();
66          queue.push_back(cmd);          queue.push_back(cmd);
# Line 88  namespace LinuxSampler { Line 100  namespace LinuxSampler {
100      // Entry point for the task thread.      // Entry point for the task thread.
101      int InstrumentManagerThread::Main() {      int InstrumentManagerThread::Main() {
102          while (true) {          while (true) {
103              while (!queue.empty()) {  
104                #if CONFIG_PTHREAD_TESTCANCEL
105                TestCancel();
106                #endif
107    
108                while (true) {
109                  command_t cmd;                  command_t cmd;
110    
111                  // grab a new command from the queue                  // grab a new command from the queue
112                  mutex.Lock();                  mutex.Lock();
113                  cmd = queue.front();                  bool empty = queue.empty();
114                    if (!empty) {
115                        cmd = queue.front();
116                        queue.pop_front();
117    
118                        if (cmd.type == command_t::DIRECT_LOAD) {
119                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
120                        }
121                    }
122                  mutex.Unlock();                  mutex.Unlock();
123                    if (empty) break;
124    
125                  try {                  try {
126                      switch (cmd.type) {                      switch (cmd.type) {
127                          case command_t::DIRECT_LOAD:                          case command_t::DIRECT_LOAD:
128                                cmd.pEngineChannel->PrepareLoadInstrument(cmd.instrumentId.FileName.c_str(), cmd.instrumentId.Index);
129                              cmd.pEngineChannel->LoadInstrument();                              cmd.pEngineChannel->LoadInstrument();
130                                EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
131                              break;                              break;
132                          case command_t::INSTR_MODE:                          case command_t::INSTR_MODE:
133                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);                              cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
# Line 109  namespace LinuxSampler { Line 137  namespace LinuxSampler {
137                      }                      }
138                  } catch (Exception e) {                  } catch (Exception e) {
139                      e.PrintMessage();                      e.PrintMessage();
140                        if (cmd.type == command_t::DIRECT_LOAD) {
141                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
142                        }
143                  } catch (...) {                  } catch (...) {
144                      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;
145                        if (cmd.type == command_t::DIRECT_LOAD) {
146                            EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
147                        }
148                  }                  }
   
                 // remove processed command from queue  
                 mutex.Lock();  
                 queue.pop_front();  
                 mutex.Unlock();  
149              }              }
150    
151              // nothing left to do, sleep until new jobs arrive              // nothing left to do, sleep until new jobs arrive
# Line 126  namespace LinuxSampler { Line 155  namespace LinuxSampler {
155              // unlock condition object so it can be turned again by other thread              // unlock condition object so it can be turned again by other thread
156              conditionJobsLeft.Unlock();              conditionJobsLeft.Unlock();
157          }          }
158            return 0;
159        }
160    
161        void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
162            /*
163               Removing from the queue an eventual scheduled loading of an instrument
164               to a sampler channel which is going to be removed.
165            */
166            pThread->mutex.Lock();
167            std::list<command_t>::iterator it;
168            for (it = pThread->queue.begin(); it != pThread->queue.end();){
169                if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
170                if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
171                    it = pThread->queue.erase(it);
172                    // we don't break here because the same engine channel could
173                    // occur more than once in the queue, so don't make optimizations
174                } else {
175                    ++it;
176                }
177            }
178            pThread->mutex.Unlock();
179        }
180    
181    #ifdef __APPLE__
182        int InstrumentManagerThread::StopThread() {
183            utsname buf;
184            int osVersion = uname(&buf) ? 0 : atoi(buf.release);
185    
186            // This is a fix for Mac OS X 10.6 and earlier, where
187            // SignalStopThread doesn't wake up a thread waiting for a
188            // condition variable.
189            if (osVersion < 11) { // darwin 11 = OS X 10.7
190                SignalStopThread(); // send stop signal, but don't wait
191                conditionJobsLeft.Set(true); // wake thread
192            }
193            return Thread::StopThread(); // then wait for it to cancel
194        }
195    #endif
196    
197    #ifdef WIN32
198        int InstrumentManagerThread::StopThread() {
199            int res = Thread::StopThread();
200            conditionJobsLeft.Reset();
201            return res;
202      }      }
203    #endif
204    
205  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC