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> | |||
| * 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> | |||
| @@ -70,50 +70,52 @@ class JackEngine | |||
| public: | |||
| JackEngine() | |||
| {} | |||
| JackEngine(JackGraphManager* manager, JackSynchro** table, JackEngineControl* controler); | |||
| virtual ~JackEngine(); | |||
| int Open(); | |||
| int Close(); | |||
| virtual int Open(); | |||
| virtual int Close(); | |||
| // 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 | |||
| 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 | |||
| 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 | |||
| bool Process(jack_time_t callback_usecs); | |||
| virtual bool Process(jack_time_t callback_usecs); | |||
| // 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 | |||
| void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) | |||
| { | |||
| JackLock lock (this); | |||
| jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); | |||
| jack_port_id_t port_index; | |||
| @@ -307,7 +306,6 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na | |||
| // Server | |||
| 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(); | |||
| 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 | |||
| int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) | |||
| { | |||
| JackLock lock (this); | |||
| JackConnectionManager* manager = WriteNextStateStart(); | |||
| JackPort* port = GetPort(port_index); | |||
| int res; | |||
| @@ -26,7 +26,6 @@ This program is free software; you can redistribute it and/or modify | |||
| #include "JackConstants.h" | |||
| #include "JackConnectionManager.h" | |||
| #include "JackAtomicState.h" | |||
| #include "JackMutex.h" | |||
| namespace Jack | |||
| { | |||
| @@ -35,7 +34,7 @@ namespace Jack | |||
| \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: | |||
| @@ -56,11 +56,6 @@ JackSynchro** GetSynchroTable() | |||
| JackInternalClient::JackInternalClient(JackServer* server, JackSynchro** table): JackClient(table) | |||
| { | |||
| 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); | |||
| } | |||
| @@ -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 "JackThreadedDriver.h" | |||
| #include "JackGlobals.h" | |||
| #include "JackEngine.h" | |||
| #include "JackLockedEngine.h" | |||
| #include "JackAudioDriver.h" | |||
| #include "JackChannel.h" | |||
| #include "JackClientControl.h" | |||
| @@ -49,7 +49,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr | |||
| fSynchroTable[i] = JackGlobals::MakeSynchro(); | |||
| fGraphManager = new JackGraphManager(); | |||
| 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)); | |||
| fLoopbackDriver = new JackLoopbackDriver("loopback", fEngine, fSynchroTable); | |||
| fChannel = JackGlobals::MakeServerChannel(); | |||