From 2ab14659132c96aad3b7da78005082f2c3f081b8 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 26 Feb 2008 11:11:13 +0000 Subject: [PATCH] New experimental alternate threading model git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1883 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackAPI.cpp | 17 ++++++++++++++++- common/JackClient.cpp | 34 +++++++++++++++++++++++----------- common/JackClient.h | 4 +++- common/JackPosixThread.cpp | 4 ++-- common/jack/jack.h | 9 ++++++--- common/jack/types.h | 3 +++ 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 2187603c..979ea1b8 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -69,6 +69,7 @@ extern "C" // new EXPORT jack_nframes_t jack_cycle_wait (jack_client_t*); EXPORT void jack_cycle_signal (jack_client_t*, int status); + EXPORT int jack_set_process_thread(jack_client_t* client, JackRTThread fun, void *arg); EXPORT int jack_set_thread_init_callback (jack_client_t *client, JackThreadInitCallback thread_init_callback, @@ -701,11 +702,25 @@ EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) JackClient* client = (JackClient*)ext_client; if (client == NULL) { jack_error("jack_cycle_signal called with a NULL client"); - } else { + } else { client->CycleSignal(status); } } +EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackRTThread fun, void *arg) +{ +#ifdef __CLIENTDEBUG__ + JackLibGlobals::CheckContext(); +#endif + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_set_process_thread called with a NULL client"); + return -1; + } else { + return client->SetProcessThread(fun, arg); + } +} + EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg) { #ifdef __CLIENTDEBUG__ diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 7cb2df35..864daa01 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -65,8 +65,9 @@ JackClient::JackClient(JackSynchro** table) fPortRegistrationArg = NULL; fPortConnectArg = NULL; fSyncArg = NULL; + fThreadFun = NULL; + fThreadFunArg = NULL; fConditionnal = 0; // Temporary?? - fWait = false; } JackClient::~JackClient() @@ -249,10 +250,8 @@ int JackClient::Activate() #endif */ - if (fProcess || !fWait) { // Start thread only of process cb has been setup - if (StartThread() < 0) - return -1; - } + if (StartThread() < 0) + return -1; int result = -1; fChannel->ClientActivate(GetClientControl()->fRefNum, &result); @@ -293,9 +292,7 @@ int JackClient::Deactivate() fThread->Kill(); #endif */ - //if (fProcess || fWait) { // Kill thread only of process cb has been setup - fThread->Kill(); - //} + fThread->Kill(); return result; } @@ -344,8 +341,12 @@ int JackClient::StartThread() */ bool JackClient::Execute() { - if (WaitFirstSync()) - ExecuteThread(); + if (fThreadFun) { + fThreadFun(fThreadFunArg); + } else { + if (WaitFirstSync()) + ExecuteThread(); + } return false; // Never reached } @@ -399,13 +400,24 @@ jack_nframes_t JackClient::Wait(int status) jack_nframes_t JackClient::CycleWait() { - fWait = true; if (!WaitSync()) return Error(); CallSyncCallback(); return GetEngineControl()->fBufferSize; } +int JackClient::SetProcessThread(JackRTThread fun, void *arg) +{ + if (IsActive()) { + jack_error("You cannot set callbacks on an active client"); + return -1; + } else { + fThreadFun = fun; + fThreadFunArg = arg; + return 0; + } +} + void JackClient::CycleSignal(int status) { if (status == 0) diff --git a/common/JackClient.h b/common/JackClient.h index c730d2f6..26c50d78 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -65,6 +65,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackPortConnectCallback fPortConnect; JackTimebaseCallback fTimebase; JackSyncCallback fSync; + JackRTThread fThreadFun; void* fProcessArg; void* fGraphOrderArg; @@ -78,6 +79,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void* fPortConnectArg; void* fTimebaseArg; void* fSyncArg; + void* fThreadFunArg; int fConditionnal; char fServerName[64]; @@ -175,7 +177,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual jack_nframes_t CycleWait(); void CycleSignal(int status); - bool fWait; + int SetProcessThread(JackRTThread fun, void *arg); // JackRunnableInterface interface bool Init(); diff --git a/common/JackPosixThread.cpp b/common/JackPosixThread.cpp index 360eb609..d087053d 100644 --- a/common/JackPosixThread.cpp +++ b/common/JackPosixThread.cpp @@ -107,7 +107,7 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi jack_error("Cannot set scheduling scope for RT thread %d %s", res, strerror(errno)); return -1; } - + memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; @@ -116,7 +116,7 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi return -1; } - if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { + if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { jack_error("setting thread stack size%d %s", res, strerror(errno)); return -1; } diff --git a/common/jack/jack.h b/common/jack/jack.h index 2ad2e76a..265a1e02 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -198,9 +198,12 @@ extern "C" */ jack_nframes_t jack_thread_wait (jack_client_t*, int status); - // experimental... - jack_nframes_t jack_cycle_wait (jack_client_t*); - void jack_cycle_signal (jack_client_t*, int status); + // New experimental alternate threading model + jack_nframes_t jack_cycle_wait (jack_client_t* client); + + void jack_cycle_signal (jack_client_t* client, int status); + + int jack_set_process_thread(jack_client_t* client, JackRTThread fun, void *arg); /** * Tell JACK to call @a thread_init_callback once just after diff --git a/common/jack/types.h b/common/jack/types.h index 18792279..502a97c8 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -214,6 +214,9 @@ typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int */ typedef void (*JackFreewheelCallback)(int starting, void *arg); + +typedef void *(*JackRTThread)(void* arg); + /** * Used for the type argument of jack_port_register() for default * audio ports and midi ports.