git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2017 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.71
| @@ -23,6 +23,7 @@ Fernando Lopez-Lezcano | |||||
| 2008-03-16 Stephane Letz <letz@grame.fr> | 2008-03-16 Stephane Letz <letz@grame.fr> | ||||
| * Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. | * Use engine in JackAlsaDriver::port_register and JackAlsaDriver::port_unregister. | ||||
| * New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients. | |||||
| 2008-03-15 Stephane Letz <letz@grame.fr> | 2008-03-15 Stephane Letz <letz@grame.fr> | ||||
| @@ -70,50 +70,52 @@ class JackEngine | |||||
| public: | public: | ||||
| JackEngine() | |||||
| {} | |||||
| JackEngine(JackGraphManager* manager, JackSynchro** table, JackEngineControl* controler); | JackEngine(JackGraphManager* manager, JackSynchro** table, JackEngineControl* controler); | ||||
| virtual ~JackEngine(); | virtual ~JackEngine(); | ||||
| int Open(); | |||||
| int Close(); | |||||
| virtual int Open(); | |||||
| virtual int Close(); | |||||
| // Client management | // Client management | ||||
| int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status); | |||||
| int ClientExternalOpen(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); | |||||
| int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait); | |||||
| virtual int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status); | |||||
| virtual int ClientExternalOpen(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); | |||||
| virtual int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait); | |||||
| int ClientExternalClose(int refnum); | |||||
| int ClientInternalClose(int refnum, bool wait); | |||||
| virtual int ClientExternalClose(int refnum); | |||||
| virtual int ClientInternalClose(int refnum, bool wait); | |||||
| int ClientActivate(int refnum); | |||||
| int ClientDeactivate(int refnum); | |||||
| virtual int ClientActivate(int refnum); | |||||
| virtual int ClientDeactivate(int refnum); | |||||
| // Internal client management | // Internal client management | ||||
| int GetInternalClientName(int int_ref, char* name_res); | |||||
| int InternalClientHandle(const char* client_name, int* status, int* int_ref); | |||||
| int InternalClientUnload(int refnum, int* status); | |||||
| virtual int GetInternalClientName(int int_ref, char* name_res); | |||||
| virtual int InternalClientHandle(const char* client_name, int* status, int* int_ref); | |||||
| virtual int InternalClientUnload(int refnum, int* status); | |||||
| // Port management | // Port management | ||||
| int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index); | |||||
| int PortUnRegister(int refnum, jack_port_id_t port); | |||||
| virtual int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, unsigned int* port); | |||||
| virtual int PortUnRegister(int refnum, jack_port_id_t port); | |||||
| int PortConnect(int refnum, const char* src, const char* dst); | |||||
| int PortDisconnect(int refnum, const char* src, const char* dst); | |||||
| virtual int PortConnect(int refnum, const char* src, const char* dst); | |||||
| virtual int PortDisconnect(int refnum, const char* src, const char* dst); | |||||
| int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); | |||||
| int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst); | |||||
| virtual int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); | |||||
| virtual int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst); | |||||
| // Graph | // Graph | ||||
| bool Process(jack_time_t callback_usecs); | |||||
| virtual bool Process(jack_time_t callback_usecs); | |||||
| // Notifications | // Notifications | ||||
| void NotifyXRun(jack_time_t callback_usecs); | |||||
| void NotifyXRun(int refnum); | |||||
| void NotifyGraphReorder(); | |||||
| void NotifyBufferSize(jack_nframes_t nframes); | |||||
| void NotifyFreewheel(bool onoff); | |||||
| void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); | |||||
| void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); | |||||
| void NotifyActivate(int refnum); | |||||
| virtual void NotifyXRun(jack_time_t callback_usecs); | |||||
| virtual void NotifyXRun(int refnum); | |||||
| virtual void NotifyGraphReorder(); | |||||
| virtual void NotifyBufferSize(jack_nframes_t nframes); | |||||
| virtual void NotifyFreewheel(bool onoff); | |||||
| virtual void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); | |||||
| virtual void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); | |||||
| virtual void NotifyActivate(int refnum); | |||||
| }; | }; | ||||
| @@ -274,7 +274,6 @@ int JackGraphManager::ComputeTotalLatencies() | |||||
| // Server | // Server | ||||
| void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) | void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) | ||||
| { | { | ||||
| JackLock lock (this); | |||||
| jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); | jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); | ||||
| jack_port_id_t port_index; | jack_port_id_t port_index; | ||||
| @@ -307,7 +306,6 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na | |||||
| // Server | // Server | ||||
| jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size) | jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags, jack_nframes_t buffer_size) | ||||
| { | { | ||||
| JackLock lock (this); | |||||
| JackConnectionManager* manager = WriteNextStateStart(); | JackConnectionManager* manager = WriteNextStateStart(); | ||||
| jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags); | jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags); | ||||
| @@ -336,7 +334,6 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, | |||||
| // Server | // Server | ||||
| int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) | int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) | ||||
| { | { | ||||
| JackLock lock (this); | |||||
| JackConnectionManager* manager = WriteNextStateStart(); | JackConnectionManager* manager = WriteNextStateStart(); | ||||
| JackPort* port = GetPort(port_index); | JackPort* port = GetPort(port_index); | ||||
| int res; | int res; | ||||
| @@ -26,7 +26,6 @@ This program is free software; you can redistribute it and/or modify | |||||
| #include "JackConstants.h" | #include "JackConstants.h" | ||||
| #include "JackConnectionManager.h" | #include "JackConnectionManager.h" | ||||
| #include "JackAtomicState.h" | #include "JackAtomicState.h" | ||||
| #include "JackMutex.h" | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -35,7 +34,7 @@ namespace Jack | |||||
| \brief Graph manager: contains the connection manager and the port array. | \brief Graph manager: contains the connection manager and the port array. | ||||
| */ | */ | ||||
| class JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectionManager>, public JackLockAble | |||||
| class JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectionManager> | |||||
| { | { | ||||
| private: | private: | ||||
| @@ -56,11 +56,6 @@ JackSynchro** GetSynchroTable() | |||||
| JackInternalClient::JackInternalClient(JackServer* server, JackSynchro** table): JackClient(table) | JackInternalClient::JackInternalClient(JackServer* server, JackSynchro** table): JackClient(table) | ||||
| { | { | ||||
| fClientControl = new JackClientControl(); | fClientControl = new JackClientControl(); | ||||
| /* | |||||
| TODO: here we use a "direct access" to server internal, which is not safe if library clients access the server using | |||||
| the "command thread" at the same time. So using the "command thread" also for internal clients would be safer. | |||||
| We may want to keep the "direct access" to server internal mode for "server embeded in client process" kind of use. | |||||
| */ | |||||
| fChannel = new JackInternalClientChannel(server); | fChannel = new JackInternalClientChannel(server); | ||||
| } | } | ||||
| @@ -0,0 +1,204 @@ | |||||
| /* | |||||
| Copyright (C) 2008 Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU General Public License as published by | |||||
| the Free Software Foundation; either version 2 of the License, or | |||||
| (at your option) any later version. | |||||
| This program is distributed in the hope that it will be useful, | |||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU General Public License for more details. | |||||
| You should have received a copy of the GNU General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| */ | |||||
| #ifndef __JackLockedEngine__ | |||||
| #define __JackLockedEngine__ | |||||
| #include "JackEngine.h" | |||||
| #include "JackMutex.h" | |||||
| namespace Jack | |||||
| { | |||||
| /*! | |||||
| \brief Locked Engine. | |||||
| */ | |||||
| class JackLockedEngine : public JackEngine, public JackLockAble | |||||
| { | |||||
| private: | |||||
| JackEngine* fEngine; | |||||
| public: | |||||
| JackLockedEngine(JackEngine* engine):fEngine(engine) | |||||
| {} | |||||
| virtual ~JackLockedEngine() | |||||
| { | |||||
| delete fEngine; | |||||
| } | |||||
| int Open() | |||||
| { | |||||
| // No lock needed | |||||
| return fEngine->Open(); | |||||
| } | |||||
| int Close() | |||||
| { | |||||
| // No lock needed | |||||
| return fEngine->Close(); | |||||
| } | |||||
| // Client management | |||||
| int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientCheck(name, name_res, protocol, options, status); | |||||
| } | |||||
| int ClientExternalOpen(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientExternalOpen(name, ref, shared_engine, shared_client, shared_graph_manager); | |||||
| } | |||||
| int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); | |||||
| } | |||||
| int ClientExternalClose(int refnum) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientExternalClose(refnum); | |||||
| } | |||||
| int ClientInternalClose(int refnum, bool wait) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientInternalClose(refnum, wait); | |||||
| } | |||||
| int ClientActivate(int refnum) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientActivate(refnum); | |||||
| } | |||||
| int ClientDeactivate(int refnum) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->ClientDeactivate(refnum); | |||||
| } | |||||
| // Internal client management | |||||
| int GetInternalClientName(int int_ref, char* name_res) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->GetInternalClientName(int_ref, name_res); | |||||
| } | |||||
| int InternalClientHandle(const char* client_name, int* status, int* int_ref) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->InternalClientHandle(client_name, status, int_ref); | |||||
| } | |||||
| int InternalClientUnload(int refnum, int* status) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->InternalClientUnload(refnum, status); | |||||
| } | |||||
| // Port management | |||||
| int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, unsigned int* port) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortRegister(refnum, name, type, flags, buffer_size, port); | |||||
| } | |||||
| int PortUnRegister(int refnum, jack_port_id_t port) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortUnRegister(refnum, port); | |||||
| } | |||||
| int PortConnect(int refnum, const char* src, const char* dst) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortConnect(refnum, src, dst); | |||||
| } | |||||
| int PortDisconnect(int refnum, const char* src, const char* dst) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortDisconnect(refnum, src, dst); | |||||
| } | |||||
| int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortConnect(refnum, src, dst); | |||||
| } | |||||
| int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->PortDisconnect(refnum, src, dst); | |||||
| } | |||||
| // Graph | |||||
| bool Process(jack_time_t callback_usecs) | |||||
| { | |||||
| // RT : no lock | |||||
| return fEngine->Process(callback_usecs); | |||||
| } | |||||
| // Notifications | |||||
| void NotifyXRun(jack_time_t callback_usecs) | |||||
| { | |||||
| // RT : no lock | |||||
| fEngine->NotifyXRun(callback_usecs); | |||||
| } | |||||
| void NotifyXRun(int refnum) | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyXRun(refnum); | |||||
| } | |||||
| void NotifyGraphReorder() | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyGraphReorder(); | |||||
| } | |||||
| void NotifyBufferSize(jack_nframes_t nframes) | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyBufferSize(nframes); | |||||
| } | |||||
| void NotifyFreewheel(bool onoff) | |||||
| { | |||||
| JackLock lock(this); | |||||
| return fEngine->NotifyFreewheel(onoff); | |||||
| } | |||||
| void NotifyPortRegistation(jack_port_id_t port_index, bool onoff) | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyPortRegistation(port_index, onoff); | |||||
| } | |||||
| void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyPortConnect(src, dst, onoff); | |||||
| } | |||||
| void NotifyActivate(int refnum) | |||||
| { | |||||
| JackLock lock(this); | |||||
| fEngine->NotifyActivate(refnum); | |||||
| } | |||||
| }; | |||||
| } // end of namespace | |||||
| #endif | |||||
| @@ -28,7 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackLoopbackDriver.h" | #include "JackLoopbackDriver.h" | ||||
| #include "JackThreadedDriver.h" | #include "JackThreadedDriver.h" | ||||
| #include "JackGlobals.h" | #include "JackGlobals.h" | ||||
| #include "JackEngine.h" | |||||
| #include "JackLockedEngine.h" | |||||
| #include "JackAudioDriver.h" | #include "JackAudioDriver.h" | ||||
| #include "JackChannel.h" | #include "JackChannel.h" | ||||
| #include "JackClientControl.h" | #include "JackClientControl.h" | ||||
| @@ -49,7 +49,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr | |||||
| fSynchroTable[i] = JackGlobals::MakeSynchro(); | fSynchroTable[i] = JackGlobals::MakeSynchro(); | ||||
| fGraphManager = new JackGraphManager(); | fGraphManager = new JackGraphManager(); | ||||
| fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name); | fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name); | ||||
| fEngine = new JackEngine(fGraphManager, fSynchroTable, fEngineControl); | |||||
| fEngine = new JackLockedEngine(new JackEngine(fGraphManager, fSynchroTable, fEngineControl)); | |||||
| fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver("freewheel", fEngine, fSynchroTable)); | fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver("freewheel", fEngine, fSynchroTable)); | ||||
| fLoopbackDriver = new JackLoopbackDriver("loopback", fEngine, fSynchroTable); | fLoopbackDriver = new JackLoopbackDriver("loopback", fEngine, fSynchroTable); | ||||
| fChannel = JackGlobals::MakeServerChannel(); | fChannel = JackGlobals::MakeServerChannel(); | ||||