Commit 00a8d52a authored by sletz's avatar sletz
Browse files

Correct crash bug when closing clients in Windows version

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1231 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 50a70c51
......@@ -344,7 +344,7 @@ int JackEngine::ClientNew(const char* name, int* ref, int* shared_engine, int* s
// Used for external clients
int JackEngine::ClientExternalNew(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager, JackExternalClient* client)
{
JackLog("JackEngine::ClientNew: name %s \n", name);
JackLog("JackEngine::ClientNew: name = %s \n", name);
int refnum = fGraphManager->AllocateRefNum();
if (refnum < 0) {
......@@ -390,7 +390,7 @@ error:
// Used for server driver clients
int JackEngine::ClientInternalNew(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client)
{
JackLog("JackEngine::ClientInternalNew: name %s\n", name);
JackLog("JackEngine::ClientInternalNew: name = %s\n", name);
int refnum = fGraphManager->AllocateRefNum();
if (refnum < 0) {
......@@ -529,7 +529,7 @@ int JackEngine::PortRegister(int refnum, const char* name, unsigned int flags, u
int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index)
{
JackLog("JackEngine::PortUnRegister ref = %ld port_index = %ld\n", refnum, port_index);
JackLog("JackEngine::PortUnRegister ref = %ld port_index = %ld\n", refnum, port_index);
assert(fClientTable[refnum]);
if (fGraphManager->RemovePort(refnum, port_index) == 0) {
......
......@@ -49,7 +49,7 @@ int JackExternalClient::Open(const char* name, int refnum, int* shared_client)
try {
if (fChannel->Open(name) < 0) {
jack_error("Cannot connect to client name = %s port\n", name);
jack_error("Cannot connect to client name = %s\n", name);
return -1;
}
......
......@@ -104,7 +104,7 @@ int JackLibClient::Open(const char* name)
goto error;
}
JackLog("JackLibClient::Open: name, refnum %s %ld\n", name, fClientControl->fRefNum);
JackLog("JackLibClient::Open name = %s refnum = %ld\n", name, fClientControl->fRefNum);
return 0;
error:
......
......@@ -43,12 +43,10 @@ void* JackPosixThread::ThreadHandler(void* arg)
JackLog("ThreadHandler: start\n");
// If Init succeed start the thread loop
bool res = true;
while (obj->fRunning && res) {
res = runnable->Execute();
//pthread_testcancel();
}
// If Init succeed, start the thread loop
while ((obj->fRunning = runnable->Execute())) {
//pthread_testcancel();
}
JackLog("ThreadHandler: exit\n");
return 0;
......@@ -134,7 +132,8 @@ int JackPosixThread::Kill()
JackLog("JackPosixThread::Kill\n");
void* status;
pthread_cancel(fThread);
pthread_join(fThread, &status);
pthread_join(fThread, &status);
fRunning = false;
return 0;
} else {
return -1;
......
......@@ -153,10 +153,11 @@ struct JackClientNewResult : public JackResult
int fSharedPorts;
uint32_t fProtocolVersion;
JackClientNewResult()
JackClientNewResult()
:fSharedEngine(-1), fSharedClient(-1), fSharedPorts(-1), fProtocolVersion(0)
{}
JackClientNewResult(int32_t status, int index1, int index2, int index3)
: JackResult(status), fSharedEngine(index1), fSharedClient(index2), fSharedPorts(index3), fProtocolVersion(0)
: JackResult(status), fSharedEngine(index1), fSharedClient(index2), fSharedPorts(index3), fProtocolVersion(0)
{}
virtual int Read(JackChannelTransaction* trans)
......
......@@ -154,8 +154,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::ClientNew\n");
JackClientNewRequest req;
JackClientNewResult res;
req.Read(socket);
AddClient(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedPorts, &res.fResult);
if (req.Read(socket) == 0)
AddClient(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedPorts, &res.fResult);
res.Write(socket);
break;
}
......@@ -164,8 +164,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::ClientClose\n");
JackClientCloseRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->ClientClose(req.fRefNum);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->ClientClose(req.fRefNum);
res.Write(socket);
RemoveClient(fd, req.fRefNum);
break;
......@@ -175,8 +175,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackActivateRequest req;
JackResult res;
JackLog("JackRequest::ActivateClient\n");
req.Read(socket);
res.fResult = fServer->Activate(req.fRefNum);
if (req.Read(socket) == 0)
res.fResult = fServer->Activate(req.fRefNum);
res.Write(socket);
break;
}
......@@ -185,8 +185,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::DeactivateClient\n");
JackDeactivateRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->Deactivate(req.fRefNum);
if (req.Read(socket) == 0)
res.fResult = fServer->Deactivate(req.fRefNum);
res.Write(socket);
break;
}
......@@ -195,8 +195,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::RegisterPort\n");
JackPortRegisterRequest req;
JackPortRegisterResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex);
res.Write(socket);
break;
}
......@@ -205,8 +205,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::UnRegisterPort\n");
JackPortUnRegisterRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
res.Write(socket);
break;
}
......@@ -215,8 +215,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectNameRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(socket);
break;
}
......@@ -225,8 +225,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectNameRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(socket);
break;
}
......@@ -235,8 +235,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(socket);
break;
}
......@@ -245,8 +245,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(socket);
break;
}
......@@ -255,8 +255,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::SetBufferSize\n");
JackSetBufferSizeRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->SetBufferSize(req.fBufferSize);
if (req.Read(socket) == 0)
res.fResult = fServer->SetBufferSize(req.fBufferSize);
res.Write(socket);
break;
}
......@@ -265,8 +265,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::SetFreeWheel\n");
JackSetFreeWheelRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->SetFreewheel(req.fOnOff);
if (req.Read(socket) == 0)
res.fResult = fServer->SetFreewheel(req.fOnOff);
res.Write(socket);
break;
}
......@@ -275,8 +275,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::kReleaseTimebase\n");
JackReleaseTimebaseRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->ReleaseTimebase(req.fRefNum);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->ReleaseTimebase(req.fRefNum);
res.Write(socket);
break;
}
......@@ -285,8 +285,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
JackLog("JackRequest::kSetTimebaseCallback\n");
JackSetTimebaseCallbackRequest req;
JackResult res;
req.Read(socket);
res.fResult = fServer->GetEngine()->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
if (req.Read(socket) == 0)
res.fResult = fServer->GetEngine()->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
res.Write(socket);
break;
}
......@@ -294,8 +294,8 @@ int JackSocketServerChannel::HandleRequest(int fd)
case JackRequest::kNotification: {
JackLog("JackRequest::Notification\n");
JackClientNotificationRequest req;
req.Read(socket);
fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
if (req.Read(socket) == 0)
fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
break;
}
......
......@@ -89,7 +89,12 @@ class JackThread
virtual void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX...
{}
virtual pthread_t GetThreadID() = 0;
virtual pthread_t GetThreadID() = 0;
bool IsRunning()
{
return fRunning;
}
};
} // end of namespace
......
......@@ -32,7 +32,7 @@ int JackWinNamedPipeNotifyChannel::Open(const char* name)
// Connect to client listen pipe
if (fNotifyPipe.Connect(jack_client_dir, name, 0) < 0) {
jack_error("Cannot connect client socket");
jack_error("Cannot connect client pipe");
return -1;
}
// TODO : use a time out for notifications
......
......@@ -32,8 +32,7 @@ namespace Jack
HANDLE JackClientPipeThread::fMutex = NULL; // never released....
// fRefNum = 0 is used as a "running" state for the JackWinNamedPipeServerNotifyChannel object
// fRefNum = -1 correspond to a not running client
// fRefNum = -1 correspond to already removed client
JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe)
: fPipe(pipe), fServer(NULL), fRefNum(0)
......@@ -66,209 +65,209 @@ void JackClientPipeThread::Close() // Close the Server/Client connection
{
fThread->Kill();
}
bool JackClientPipeThread::Execute()
{
JackLog("JackClientPipeThread::Execute\n");
return (HandleRequest(fPipe) == 0);
bool JackClientPipeThread::Execute()
{
JackLog("JackClientPipeThread::Execute\n");
return (HandleRequest() == 0);
}
int JackClientPipeThread::HandleRequest(JackWinNamedPipeClient* pipe)
int JackClientPipeThread::HandleRequest()
{
// Read header
JackRequest header;
if (header.Read(pipe) < 0) {
jack_error("HandleRequest: cannot read header");
// Lock the global mutex
if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED)
jack_error("JackClientPipeThread::HandleRequest: mutex wait error");
KillClient(fPipe);
// Unlock the global mutex
ReleaseMutex(fMutex);
return -1;
}
JackRequest header;
int res = header.Read(fPipe);
int ret = 0;
// Lock the global mutex
if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED)
jack_error("JackClientPipeThread::HandleRequest: mutex wait error");
// Read data
switch (header.fType) {
case JackRequest::kClientNew: {
JackLog("JackRequest::ClientNew\n");
JackClientNewRequest req;
JackClientNewResult res;
req.Read(pipe);
AddClient(pipe, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedPorts, &res.fResult);
res.Write(pipe);
break;
}
case JackRequest::kClientClose: {
JackLog("JackRequest::ClientClose\n");
JackClientCloseRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->ClientClose(req.fRefNum);
res.Write(pipe);
RemoveClient(pipe, req.fRefNum);
break;
}
case JackRequest::kActivateClient: {
JackActivateRequest req;
JackResult res;
JackLog("JackRequest::ActivateClient\n");
req.Read(pipe);
res.fResult = fServer->Activate(req.fRefNum);
res.Write(pipe);
break;
}
case JackRequest::kDeactivateClient: {
JackLog("JackRequest::DeactivateClient\n");
JackDeactivateRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->Deactivate(req.fRefNum);
res.Write(pipe);
break;
}
case JackRequest::kRegisterPort: {
JackLog("JackRequest::RegisterPort\n");
JackPortRegisterRequest req;
JackPortRegisterResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex);
res.Write(pipe);
break;
}
case JackRequest::kUnRegisterPort: {
JackLog("JackRequest::UnRegisterPort\n");
JackPortUnRegisterRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
res.Write(pipe);
break;
}
case JackRequest::kConnectNamePorts: {
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectNameRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(pipe);
break;
}
case JackRequest::kDisconnectNamePorts: {
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectNameRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(pipe);
break;
}
case JackRequest::kConnectPorts: {
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(pipe);
break;
}
case JackRequest::kDisconnectPorts: {
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(pipe);
break;
}
case JackRequest::kSetBufferSize: {
JackLog("JackRequest::SetBufferSize\n");
JackSetBufferSizeRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->SetBufferSize(req.fBufferSize);
res.Write(pipe);
break;
}
case JackRequest::kSetFreeWheel: {
JackLog("JackRequest::SetFreeWheel\n");
JackSetFreeWheelRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->SetFreewheel(req.fOnOff);
res.Write(pipe);
break;
}
case JackRequest::kReleaseTimebase: {
JackLog("JackRequest::kReleaseTimebase\n");
JackReleaseTimebaseRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->ReleaseTimebase(req.fRefNum);
res.Write(pipe);
break;
}
case JackRequest::kSetTimebaseCallback: {
JackLog("JackRequest::kSetTimebaseCallback\n");
JackSetTimebaseCallbackRequest req;
JackResult res;
req.Read(pipe);
res.fResult = fServer->GetEngine()->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
res.Write(pipe);
break;
}
case JackRequest::kNotification: {
JackLog("JackRequest::Notification\n");
JackClientNotificationRequest req;
req.Read(pipe);
fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
break;
}
default:
JackLog("Unknown request %ld\n", header.fType);
break;
}
jack_error("JackClientPipeThread::HandleRequest: mutex wait error");
if (res < 0) {
jack_error("HandleRequest: cannot read header");
KillClient();
ret = -1;
} else {
// Read data
switch (header.fType) {
case JackRequest::kClientNew: {
JackLog("JackRequest::ClientNew\n");
JackClientNewRequest req;
JackClientNewResult res;
if (req.Read(fPipe) == 0)
AddClient(req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedPorts, &res.fResult);
res.Write(fPipe);
break;
}
case JackRequest::kClientClose: {
JackLog("JackRequest::ClientClose\n");
JackClientCloseRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->ClientClose(req.fRefNum);
res.Write(fPipe);
RemoveClient(req.fRefNum);
break;
}
case JackRequest::kActivateClient: {
JackActivateRequest req;
JackResult res;
JackLog("JackRequest::ActivateClient\n");
if (req.Read(fPipe) == 0)
res.fResult = fServer->Activate(req.fRefNum);
res.Write(fPipe);
break;
}
case JackRequest::kDeactivateClient: {
JackLog("JackRequest::DeactivateClient\n");
JackDeactivateRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->Deactivate(req.fRefNum);
res.Write(fPipe);
break;
}
case JackRequest::kRegisterPort: {
JackLog("JackRequest::RegisterPort\n");
JackPortRegisterRequest req;
JackPortRegisterResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex);
res.Write(fPipe);
break;
}
case JackRequest::kUnRegisterPort: {
JackLog("JackRequest::UnRegisterPort\n");
JackPortUnRegisterRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
res.Write(fPipe);
break;
}
case JackRequest::kConnectNamePorts: {
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectNameRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(fPipe);
break;
}
case JackRequest::kDisconnectNamePorts: {
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectNameRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(fPipe);
break;
}
case JackRequest::kConnectPorts: {
JackLog("JackRequest::ConnectPorts\n");
JackPortConnectRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(fPipe);
break;
}
case JackRequest::kDisconnectPorts: {
JackLog("JackRequest::DisconnectPorts\n");
JackPortDisconnectRequest req;
JackResult res;
if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
res.Write(fPipe);
break;
}
case JackRequest::kSetBufferSize: {
JackLog("JackRequest::SetBufferSize\n");