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(); | ||||