git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2321 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -20,9 +20,14 @@ Fernando Lopez-Lezcano | |||
Jackdmp changes log | |||
--------------------------- | |||
2008-05-23 Stephane Letz <letz@grame.fr> | |||
* Use StartSync to start the client notification thread, otherwise initial notifications from the server may be lost. | |||
2008-05-22 Stephane Letz <letz@grame.fr> | |||
* Correct JackPort::ClearBuffer. | |||
* Correct JackEngine inheritance graph. | |||
2008-05-21 Stephane Letz <letz@grame.fr> | |||
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include "JackPosixThread.h" | |||
#include "JackError.h" | |||
#include "JackTime.h" | |||
#include <string.h> // for memset | |||
namespace Jack | |||
@@ -34,16 +35,17 @@ void* JackPosixThread::ThreadHandler(void* arg) | |||
if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) { | |||
jack_error("pthread_setcanceltype err = %s", strerror(err)); | |||
} | |||
// Signal creation thread when started with StartSync | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// Call Init method | |||
if (!runnable->Init()) { | |||
jack_error("Thread init fails: thread quits"); | |||
return 0; | |||
} | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// If Init succeed, start the thread loop | |||
bool res = true; | |||
while (obj->fStatus == kRunning && res) { | |||
@@ -66,7 +68,23 @@ int JackPosixThread::Start() | |||
return 0; | |||
} | |||
} | |||
int JackPosixThread::StartSync() | |||
{ | |||
fStatus = kStarting; | |||
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
fStatus = kIdle; | |||
return -1; | |||
} else { | |||
int count = 0; | |||
while (fStatus != kRunning && ++count < 1000) { | |||
JackSleep(1000); | |||
} | |||
return (count == 1000) ? -1 : 0; | |||
} | |||
} | |||
int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) | |||
{ | |||
pthread_attr_t attributes; | |||
@@ -123,12 +141,6 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi | |||
return 0; | |||
} | |||
int JackPosixThread::StartSync() | |||
{ | |||
jack_error("Not implemented yet"); | |||
return -1; | |||
} | |||
int JackPosixThread::Kill() | |||
{ | |||
if (fThread != (pthread_t)NULL) { // If thread has been started | |||
@@ -227,13 +227,12 @@ struct JackClientOpenResult : public JackResult | |||
int fSharedEngine; | |||
int fSharedClient; | |||
int fSharedGraph; | |||
uint32_t fProtocolVersion; | |||
JackClientOpenResult() | |||
: JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1), fProtocolVersion(0) | |||
: JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1) | |||
{} | |||
JackClientOpenResult(int32_t result, int index1, int index2, int index3) | |||
: JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3), fProtocolVersion(0) | |||
: JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3) | |||
{} | |||
int Read(JackChannelTransaction* trans) | |||
@@ -242,8 +241,7 @@ struct JackClientOpenResult : public JackResult | |||
CheckRes(trans->Read(&fSharedEngine, sizeof(int))); | |||
CheckRes(trans->Read(&fSharedClient, sizeof(int))); | |||
CheckRes(trans->Read(&fSharedGraph, sizeof(int))); | |||
CheckRes(trans->Read(&fProtocolVersion, sizeof(uint32_t))); | |||
return 0; | |||
return 0; | |||
} | |||
int Write(JackChannelTransaction* trans) | |||
@@ -252,7 +250,6 @@ struct JackClientOpenResult : public JackResult | |||
CheckRes(trans->Write(&fSharedEngine, sizeof(int))); | |||
CheckRes(trans->Write(&fSharedClient, sizeof(int))); | |||
CheckRes(trans->Write(&fSharedGraph, sizeof(int))); | |||
CheckRes(trans->Write(&fProtocolVersion, sizeof(uint32_t))); | |||
return 0; | |||
} | |||
}; | |||
@@ -98,7 +98,10 @@ void JackSocketClientChannel::Close() | |||
int JackSocketClientChannel::Start() | |||
{ | |||
jack_log("JackSocketClientChannel::Start"); | |||
if (fThread->Start() != 0) { | |||
/* | |||
To be sure notification thread is started before ClientOpen is called. | |||
*/ | |||
if (fThread->StartSync() != 0) { | |||
jack_error("Cannot start Jack client listener"); | |||
return -1; | |||
} else { | |||
@@ -62,7 +62,7 @@ class JackThread | |||
{ | |||
public: | |||
enum kThreadState { kIdle, kStarting, kRunning}; | |||
enum kThreadState {kIdle, kStarting, kRunning}; | |||
protected: | |||
@@ -111,7 +111,10 @@ void JackMachClientChannel::Close() | |||
int JackMachClientChannel::Start() | |||
{ | |||
jack_log("JackMachClientChannel::Start"); | |||
if (fThread->Start() != 0) { | |||
/* | |||
To be sure notification thread is started before ClientOpen is called. | |||
*/ | |||
if (fThread->StartSync() != 0) { | |||
jack_error("Cannot start Jack client listener"); | |||
return -1; | |||
} else { | |||
@@ -30,22 +30,15 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) | |||
JackWinThread* obj = (JackWinThread*)arg; | |||
JackRunnableInterface* runnable = obj->fRunnable; | |||
// Signal creation thread when started with StartSync | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// Call Init method | |||
if (!runnable->Init()) { | |||
jack_error("Thread init fails: thread quits"); | |||
return 0; | |||
} | |||
// TODO: Signal creation thread when started with StartSync | |||
/* | |||
if (!obj->fRunning) { | |||
obj->fRunning = true; | |||
SetEvent(obj->fEvent); | |||
} | |||
*/ | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// If Init succeed, start the thread loop | |||
bool res = true; | |||
@@ -73,12 +66,6 @@ JackWinThread::~JackWinThread() | |||
int JackWinThread::Start() | |||
{ | |||
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
if (fEvent == NULL) { | |||
jack_error("Cannot create event error = %d", GetLastError()); | |||
return -1; | |||
} | |||
fStatus = kStarting; | |||
// Check if the thread was correctly started | |||
@@ -89,6 +76,22 @@ int JackWinThread::Start() | |||
return 0; | |||
} | |||
} | |||
int JackWinThread::StartSync() | |||
{ | |||
fStatus = kStarting; | |||
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
fStatus = kIdle; | |||
return -1; | |||
} else { | |||
int count = 0; | |||
while (fStatus != kRunning && ++count < 1000) { | |||
JackSleep(1000); | |||
} | |||
return (count == 1000) ? -1 : 0; | |||
} | |||
} | |||
int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg) | |||
{ | |||
@@ -103,7 +106,6 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa | |||
if (realtime) { | |||
jack_log("Create RT thread"); | |||
if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
jack_error("Cannot set priority class = %d", GetLastError()); | |||
return -1; | |||
@@ -116,64 +118,6 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa | |||
return 0; | |||
} | |||
int JackWinThread::StartSync() | |||
{ | |||
jack_error("Not implemented yet"); | |||
return -1; | |||
/* | |||
DWORD id; | |||
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
if (fEvent == NULL) { | |||
jack_error("Cannot create event error = %d", GetLastError()); | |||
return -1; | |||
} | |||
fStatus = kStarting; | |||
if (fRealTime) { | |||
jack_log("Create RT thread"); | |||
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); | |||
if (fThread == NULL) { | |||
jack_error("Cannot create thread error = %d", GetLastError()); | |||
return -1; | |||
} | |||
if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec | |||
jack_error("Thread has not started"); | |||
return -1; | |||
} | |||
if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
jack_error("Cannot set priority class = %d", GetLastError()); | |||
return -1; | |||
} | |||
return 0; | |||
} else { | |||
jack_log("Create non RT thread"); | |||
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); | |||
if (fThread == NULL) { | |||
jack_error("Cannot create thread error = %d", GetLastError()); | |||
return -1; | |||
} | |||
if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec | |||
jack_error("Thread has not started"); | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
*/ | |||
} | |||
// voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx | |||
int JackWinThread::Kill() | |||