Browse Source

Better handling of graph state read functions : never wait when used in the real-time thread, current state is used.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2302 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.90
sletz 17 years ago
parent
commit
a74f1a586e
9 changed files with 173 additions and 10 deletions
  1. +1
    -0
      ChangeLog
  2. +14
    -6
      common/JackAPI.cpp
  3. +4
    -1
      common/JackClient.cpp
  4. +39
    -2
      common/JackGlobals.cpp
  5. +15
    -0
      common/JackGlobals.h
  6. +1
    -1
      common/JackLibGlobals.h
  7. +46
    -0
      common/JackPosixThread.cpp
  8. +12
    -0
      common/JackThread.h
  9. +41
    -0
      windows/JackWinThread.cpp

+ 1
- 0
ChangeLog View File

@@ -24,6 +24,7 @@ Fernando Lopez-Lezcano


* Correct JackEngine::PortUnRegister, JackEngine::ClientCloseAux and JackEngine::ClientDeactivate to correctly send notifications. * Correct JackEngine::PortUnRegister, JackEngine::ClientCloseAux and JackEngine::ClientDeactivate to correctly send notifications.
* New jack_get_client_pid API, implemented on server side. * New jack_get_client_pid API, implemented on server side.
* Better handling of graph state read functions : never wait when used in the real-time thread, current state is used.


2008-05-20 Stephane Letz <letz@grame.fr> 2008-05-20 Stephane Letz <letz@grame.fr>




+ 14
- 6
common/JackAPI.cpp View File

@@ -248,12 +248,20 @@ static inline bool CheckBufferSize(jack_nframes_t buffer_size)


static inline void WaitGraphChange() static inline void WaitGraphChange()
{ {
JackGraphManager* manager = GetGraphManager();
JackEngineControl* control = GetEngineControl();

if (manager && control && manager->IsPendingChange()) {
jack_log("WaitGraphChange...");
JackSleep(int(control->fPeriodUsecs * 1.1f));
/*
TLS key that is set only in RT thread, so never waits for pending
graph change in RT context (just read the current graph state).
*/
if (jack_tls_get(gRealTime) == NULL) {
JackGraphManager* manager = GetGraphManager();
JackEngineControl* control = GetEngineControl();
assert(manager);
assert(control);
if (manager->IsPendingChange()) {
jack_log("WaitGraphChange...");
JackSleep(int(control->fPeriodUsecs * 1.1f));
}
} }
} }




+ 4
- 1
common/JackClient.cpp View File

@@ -36,7 +36,7 @@ namespace Jack
{ {


#define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL)) #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL))
JackClient::JackClient() JackClient::JackClient()
{} {}


@@ -335,6 +335,9 @@ int JackClient::StartThread()
*/ */
bool JackClient::Execute() bool JackClient::Execute()
{ {
if (!jack_tls_set(gRealTime, this))
jack_error("failed to set thread realtime key");
if (fThreadFun) { if (fThreadFun) {
// Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished) // Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished)
WaitSync(); WaitSync();


+ 39
- 2
common/JackGlobals.cpp View File

@@ -22,6 +22,43 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack namespace Jack
{ {


JackFactoryImpl* JackGlobals::fInstance;
JackFactoryImpl* JackGlobals::fInstance;
} // end of namespace } // end of namespace

static bool gKeyRealtimeInitialized = false;
jack_tls_key gRealTime;

void jack_realtime_init()
{
if (!gKeyRealtimeInitialized) {
gKeyRealtimeInitialized = jack_tls_allocate_key(&gRealTime);
}
}

void jack_realtime_uninit()
{
if (gKeyRealtimeInitialized) {
jack_tls_free_key(gRealTime);
gKeyRealtimeInitialized = false;
}
}

// Initialisation at library load time

#ifdef WIN32

BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
jack_realtime_init();
break;
case DLL_PROCESS_DETACH:
jack_realtime_uninit();
break;
}
return TRUE;
}

#endif

+ 15
- 0
common/JackGlobals.h View File

@@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define __JackGlobals__ #define __JackGlobals__


#include "JackError.h" #include "JackError.h"
#include "JackThread.h"


namespace Jack namespace Jack
{ {
@@ -279,4 +280,18 @@ class JackGlobals


} // end of namespace } // end of namespace


#ifdef __cplusplus
extern "C"
{
#endif
extern jack_tls_key gRealTime;
void __attribute__ ((constructor)) jack_realtime_init();
void __attribute__ ((destructor)) jack_realtime_uninit();

#ifdef __cplusplus
}
#endif

#endif #endif

+ 1
- 1
common/JackLibGlobals.h View File

@@ -48,7 +48,7 @@ struct JackLibGlobals
#ifdef __APPLE__ #ifdef __APPLE__
std::map<mach_port_t, JackClient*> fClientTable; /*! Client table */ std::map<mach_port_t, JackClient*> fClientTable; /*! Client table */
#endif #endif
static int fClientCount; static int fClientCount;
static JackLibGlobals* fGlobals; static JackLibGlobals* fGlobals;




+ 46
- 0
common/JackPosixThread.cpp View File

@@ -219,3 +219,49 @@ void JackPosixThread::Terminate()


} // end of namespace } // end of namespace


bool jack_tls_allocate_key(jack_tls_key *key_ptr)
{
int ret;
ret = pthread_key_create(key_ptr, NULL);
if (ret != 0)
{
jack_error("pthread_key_create() failed with error %d errno %s", ret, strerror(errno));
return false;
}
return true;
}

bool jack_tls_free_key(jack_tls_key key)
{
int ret;
ret = pthread_key_delete(key);
if (ret != 0)
{
jack_error("pthread_key_delete() failed with error %d errno %s", ret, strerror(errno));
return false;
}
return true;
}

bool jack_tls_set(jack_tls_key key, void *data_ptr)
{
int ret;
ret = pthread_setspecific(key, (const void *)data_ptr);
if (ret != 0)
{
jack_error("pthread_setspecific() failed with error %d errno %s", ret, strerror(errno));
return false;
}
return true;
}

void *jack_tls_get(jack_tls_key key)
{
return pthread_getspecific(key);
}

+ 12
- 0
common/JackThread.h View File

@@ -108,4 +108,16 @@ class JackThread


} // end of namespace } // end of namespace


#if defined(WIN32)
typedef DWORD jack_tls_key;
#else
typedef pthread_key_t jack_tls_key;
#endif

bool jack_tls_allocate_key(jack_tls_key *key_ptr);
bool jack_tls_free_key(jack_tls_key key);

bool jack_tls_set(jack_tls_key key, void *data_ptr);
void *jack_tls_get(jack_tls_key key);

#endif #endif

+ 41
- 0
windows/JackWinThread.cpp View File

@@ -257,3 +257,44 @@ void JackWinThread::Terminate()


} // end of namespace } // end of namespace


bool jack_tls_allocate_key(jack_tls_key *key_ptr)
{
DWORD key;
key = TlsAlloc();
if (key == TLS_OUT_OF_INDEXES)
{
jack_error("TlsAlloc() failed. Error is %d", (unsigned int)GetLastError());
return false;
}
*key_ptr = key;
return true;
}

bool jack_tls_free_key(jack_tls_key key)
{
if (!TlsFree(key))
{
jack_error("TlsFree() failed. Error is %d", (unsigned int)GetLastError());
return false;
}
return true;
}

bool jack_tls_set(jack_tls_key key, void *data_ptr)
{
if (!TlsSetValue(key, data_ptr))
{
jack_error("TlsSetValue() failed. Error is %d", (unsigned int)GetLastError());
return false;
}
return true;
}

void *jack_tls_get(jack_tls_key key)
{
return TlsGetValue(key);
}

Loading…
Cancel
Save