--- linuxsampler/trunk/src/network/lscpserver.cpp 2008/12/07 01:26:46 1800 +++ linuxsampler/trunk/src/network/lscpserver.cpp 2009/11/01 18:47:59 2025 @@ -3,7 +3,7 @@ * LinuxSampler - modular, streaming capable sampler * * * * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * - * Copyright (C) 2005 - 2008 Christian Schoenebeck * + * Copyright (C) 2005 - 2009 Christian Schoenebeck * * * * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -24,6 +24,7 @@ #include #include +#include "../common/File.h" #include "lscpserver.h" #include "lscpresultset.h" #include "lscpevent.h" @@ -140,6 +141,8 @@ } LSCPServer::~LSCPServer() { + CloseAllConnections(); + InstrumentManager::StopBackgroundThread(); #if defined(WIN32) if (hSocket >= 0) closesocket(hSocket); #else @@ -334,6 +337,24 @@ } #endif // HAVE_SQLITE3 +void LSCPServer::RemoveListeners() { + pSampler->RemoveChannelCountListener(&eventHandler); + pSampler->RemoveAudioDeviceCountListener(&eventHandler); + pSampler->RemoveMidiDeviceCountListener(&eventHandler); + pSampler->RemoveVoiceCountListener(&eventHandler); + pSampler->RemoveStreamCountListener(&eventHandler); + pSampler->RemoveBufferFillListener(&eventHandler); + pSampler->RemoveTotalStreamCountListener(&eventHandler); + pSampler->RemoveTotalVoiceCountListener(&eventHandler); + pSampler->RemoveFxSendCountListener(&eventHandler); + MidiInstrumentMapper::RemoveMidiInstrumentCountListener(&eventHandler); + MidiInstrumentMapper::RemoveMidiInstrumentInfoListener(&eventHandler); + MidiInstrumentMapper::RemoveMidiInstrumentMapCountListener(&eventHandler); + MidiInstrumentMapper::RemoveMidiInstrumentMapInfoListener(&eventHandler); +#if HAVE_SQLITE3 + InstrumentsDb::GetInstrumentsDb()->RemoveInstrumentsDbListener(&dbInstrumentsEventHandler); +#endif +} /** * Blocks the calling thread until the LSCP Server is initialized and @@ -507,7 +528,7 @@ int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout); - if (retval == 0) + if (retval == 0 || (retval == -1 && errno == EINTR)) continue; //Nothing try again if (retval == -1) { std::cerr << "LSCPServer: Socket select error." << std::endl; @@ -534,6 +555,13 @@ exit(EXIT_FAILURE); } #else + struct linger linger; + linger.l_onoff = 1; + linger.l_linger = 0; + if(setsockopt(socket, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger))) { + std::cerr << "LSCPServer: Failed to set SO_LINGER\n"; + } + if (fcntl(socket, F_SETFL, O_NONBLOCK)) { std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl; exit(EXIT_FAILURE); @@ -605,6 +633,14 @@ NotifyMutex.Unlock(); } +void LSCPServer::CloseAllConnections() { + std::vector::iterator iter = Sessions.begin(); + while(iter != Sessions.end()) { + CloseConnection(iter); + iter = Sessions.begin(); + } +} + void LSCPServer::LockRTNotify() { RTNotifyMutex.Lock(); } @@ -1259,6 +1295,7 @@ for (;iter != parameters.end(); iter++) { if (s != "") s += ","; s += iter->first; + delete iter->second; } result.Add("PARAMETERS", s); } @@ -1283,6 +1320,7 @@ for (;iter != parameters.end(); iter++) { if (s != "") s += ","; s += iter->first; + delete iter->second; } result.Add("PARAMETERS", s); } @@ -1313,6 +1351,7 @@ if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin); if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax); if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities); + delete pParameter; } catch (Exception e) { result.Error(e); @@ -1340,6 +1379,7 @@ if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin); if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax); if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities); + delete pParameter; } catch (Exception e) { result.Error(e); @@ -1806,7 +1846,6 @@ pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params); // Make it with at least one initial port. std::map parameters = pDevice->DeviceParameters(); - parameters["PORTS"]->SetValue("1"); } // Must have a device... if (pDevice == NULL) @@ -2458,6 +2497,10 @@ pMidiDevice->SendNoteOffToDevice(Arg1, Arg2); bool b = pMidiDevice->SendNoteOffToSampler(Arg1, Arg2); if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2)); + } else if (MidiMsg == "CC") { + pMidiDevice->SendCCToDevice(Arg1, Arg2); + bool b = pMidiDevice->SendCCToSampler(Arg1, Arg2); + if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2)); } else { throw Exception("Unknown MIDI message type: " + MidiMsg); } @@ -2800,17 +2843,9 @@ throw Exception("Directory is specified"); } #else - struct stat statBuf; - int res = stat(Filename.c_str(), &statBuf); - if (res) { - std::stringstream ss; - ss << "Fail to stat `" << Filename << "`: " << strerror(errno); - throw Exception(ss.str()); - } - - if (S_ISDIR(statBuf.st_mode)) { - throw Exception("Directory is specified"); - } + File f(Filename); + if(!f.Exist()) throw Exception(f.GetErrorMsg()); + if (f.IsDirectory()) throw Exception("Directory is specified"); #endif }