Commit a74f1a58 authored by sletz's avatar sletz
Browse files

Better handling of graph state read functions : never wait when used in the...

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
parent 152a1711
......@@ -24,6 +24,7 @@ Fernando Lopez-Lezcano
* Correct JackEngine::PortUnRegister, JackEngine::ClientCloseAux and JackEngine::ClientDeactivate to correctly send notifications.
* 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>
......
......@@ -248,12 +248,20 @@ static inline bool CheckBufferSize(jack_nframes_t buffer_size)
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));
}
}
}
......
......@@ -36,7 +36,7 @@ namespace Jack
{
#define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL))
JackClient::JackClient()
{}
......@@ -335,6 +335,9 @@ int JackClient::StartThread()
*/
bool JackClient::Execute()
{
if (!jack_tls_set(gRealTime, this))
jack_error("failed to set thread realtime key");
if (fThreadFun) {
// Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished)
WaitSync();
......
......@@ -22,6 +22,43 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace Jack
{
JackFactoryImpl* JackGlobals::fInstance;
JackFactoryImpl* JackGlobals::fInstance;
} // 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
......@@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define __JackGlobals__
#include "JackError.h"
#include "JackThread.h"
namespace Jack
{
......@@ -279,4 +280,18 @@ class JackGlobals
} // 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
......@@ -48,7 +48,7 @@ struct JackLibGlobals
#ifdef __APPLE__
std::map<mach_port_t, JackClient*> fClientTable; /*! Client table */
#endif
static int fClientCount;
static JackLibGlobals* fGlobals;
......
......@@ -219,3 +219,49 @@ void JackPosixThread::Terminate()
} // 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);
}
......@@ -108,4 +108,16 @@ class JackThread
} // 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
......@@ -257,3 +257,44 @@ void JackWinThread::Terminate()
} // 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);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment