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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1761 - (hide annotations) (download)
Fri Aug 29 15:42:06 2008 UTC (15 years, 8 months ago) by iliev
File size: 6743 byte(s)
* fixed a crash which occurs when removing a sampler channel waiting
  to start instrument loading after another channel

1 schoenebeck 947 /***************************************************************************
2     * *
3 schoenebeck 1040 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
4 schoenebeck 947 * *
5     * 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 *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This library is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this library; if not, write to the Free Software *
17     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18     * MA 02111-1307 USA *
19     ***************************************************************************/
20    
21     #include "InstrumentManagerThread.h"
22    
23 schoenebeck 1424 #include "../common/global_private.h"
24    
25 schoenebeck 947 namespace LinuxSampler {
26    
27     InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {
28 iliev 1761 eventHandler.pThread = this;
29 schoenebeck 947 }
30    
31     InstrumentManagerThread::~InstrumentManagerThread() {
32     }
33    
34     /**
35     * @brief Order loading of a new instrument.
36     *
37     * The request will go into a queue waiting to be processed by the
38     * class internal task thread. This method will immediately return and
39     * the instrument will be loaded in the background.
40     *
41     * @param Filename - file name of the instrument
42     * @param uiInstrumentIndex - index of the instrument within the file
43     * @param pEngineChannel - engine channel on which the instrument should be loaded
44     */
45     void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {
46 persson 1038 dmsg(1,("Scheduling '%s' (Index=%d) to be loaded in background (if not loaded yet).\n",Filename.c_str(),uiInstrumentIndex));
47 iliev 1761
48     static bool listenerRegistered = false;
49     if (!listenerRegistered) {
50     pEngineChannel->GetSampler()->AddChannelCountListener(&eventHandler);
51     listenerRegistered = true;
52     }
53    
54    
55 schoenebeck 947 // already tell the engine which instrument to load
56     pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrumentIndex);
57    
58     command_t cmd;
59     cmd.type = command_t::DIRECT_LOAD;
60     cmd.pEngineChannel = pEngineChannel;
61 schoenebeck 989
62     mutex.Lock();
63     queue.push_back(cmd);
64     mutex.Unlock();
65    
66 schoenebeck 947 StartThread(); // ensure thread is running
67     conditionJobsLeft.Set(true); // wake up thread
68     }
69    
70     /**
71     * @brief Order changing the life-time strategy of an instrument.
72     *
73     * The request will go into a queue waiting to be processed by the
74     * class internal task thread. This method will immediately return and
75     * in case the instrument has to be loaded due to a mode change to
76     * PERSISTENT, it will be loaded in the background.
77     *
78     * @param pManager - InstrumentManager which manages the instrument
79     * @param ID - unique ID of the instrument
80     * @param Mode - life-time strategy to set for this instrument
81     */
82     void InstrumentManagerThread::StartSettingMode(InstrumentManager* pManager, const InstrumentManager::instrument_id_t& ID, InstrumentManager::mode_t Mode) {
83     command_t cmd;
84     cmd.type = command_t::INSTR_MODE;
85     cmd.pManager = pManager;
86     cmd.instrumentId = ID;
87     cmd.mode = Mode;
88 schoenebeck 989
89     mutex.Lock();
90     queue.push_back(cmd);
91     mutex.Unlock();
92    
93 schoenebeck 947 StartThread(); // ensure thread is running
94     conditionJobsLeft.Set(true); // wake up thread
95     }
96    
97     // Entry point for the task thread.
98     int InstrumentManagerThread::Main() {
99     while (true) {
100 nagata 1649
101     #if CONFIG_PTHREAD_TESTCANCEL
102     TestCancel();
103     #endif
104    
105 schoenebeck 989 while (!queue.empty()) {
106 schoenebeck 947 command_t cmd;
107 schoenebeck 989
108     // grab a new command from the queue
109     mutex.Lock();
110     cmd = queue.front();
111 iliev 1761 queue.pop_front();
112 schoenebeck 989 mutex.Unlock();
113    
114 schoenebeck 947 try {
115     switch (cmd.type) {
116     case command_t::DIRECT_LOAD:
117     cmd.pEngineChannel->LoadInstrument();
118     break;
119     case command_t::INSTR_MODE:
120     cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
121     break;
122     default:
123     std::cerr << "InstrumentManagerThread: unknown command - BUG!\n" << std::flush;
124     }
125 schoenebeck 1040 } catch (Exception e) {
126 schoenebeck 947 e.PrintMessage();
127 schoenebeck 1040 } catch (...) {
128     std::cerr << "InstrumentManagerThread: some exception occured, could not finish task\n" << std::flush;
129 schoenebeck 947 }
130     }
131    
132     // nothing left to do, sleep until new jobs arrive
133     conditionJobsLeft.WaitIf(false);
134     // reset flag
135     conditionJobsLeft.Set(false);
136     // unlock condition object so it can be turned again by other thread
137     conditionJobsLeft.Unlock();
138     }
139     }
140 iliev 1761
141     void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
142     /*
143     Removing from the queue an eventual scheduled loading of an instrument
144     to a sampler channel which is going to be removed.
145     */
146     pThread->mutex.Lock();
147     std::list<command_t>::iterator it;
148     for (it = pThread->queue.begin(); it != pThread->queue.end();){
149     if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
150     if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
151     it = pThread->queue.erase(it);
152     // we don't break here because the same engine channel could
153     // occur more than once in the queue, so don't make optimizations
154     } else {
155     ++it;
156     }
157     }
158     pThread->mutex.Unlock();
159     }
160 schoenebeck 947 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC