Browse Source

New JackLockedEngine decorator class to serialize access from ALSA Midi thread, command thread and in-server clients.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2017 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.71
sletz 17 years ago
parent
commit
9a7839caa6
7 changed files with 237 additions and 39 deletions
  1. +1
    -0
      ChangeLog
  2. +29
    -27
      common/JackEngine.h
  3. +0
    -3
      common/JackGraphManager.cpp
  4. +1
    -2
      common/JackGraphManager.h
  5. +0
    -5
      common/JackInternalClient.cpp
  6. +204
    -0
      common/JackLockedEngine.h
  7. +2
    -2
      common/JackServer.cpp

+ 1
- 0
ChangeLog View File

@@ -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>


+ 29
- 27
common/JackEngine.h View File

@@ -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);
};




+ 0
- 3
common/JackGraphManager.cpp View File

@@ -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;


+ 1
- 2
common/JackGraphManager.h View File

@@ -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:


+ 0
- 5
common/JackInternalClient.cpp View File

@@ -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);
}



+ 204
- 0
common/JackLockedEngine.h View File

@@ -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


+ 2
- 2
common/JackServer.cpp View File

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


Loading…
Cancel
Save