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