git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1370 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.62
@@ -137,7 +137,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) | |||
{ | |||
bool res = true; | |||
// Transport | |||
// Transport begin | |||
fEngineControl->CycleBegin(callback_usecs); | |||
// Timing | |||
@@ -162,7 +162,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) | |||
} | |||
} | |||
// Transport | |||
// Transport end | |||
fEngineControl->CycleEnd(fClientTable); | |||
return res; | |||
} | |||
@@ -257,8 +257,9 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value) | |||
{ | |||
JackClientInterface* client = fClientTable[refnum]; | |||
// The client may be notified by the RT thread while closing | |||
if (client && (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value) < 0)) { | |||
jack_error("NotifyClient fails name = %s event = %ld = val = %ld", client->GetClientControl()->fName, event, value); | |||
if (client) { | |||
if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value) < 0) | |||
jack_error("NotifyClient fails name = %s event = %ld = val = %ld", client->GetClientControl()->fName, event, value); | |||
} else { | |||
JackLog("JackEngine::NotifyClient: client not available anymore\n"); | |||
} | |||
@@ -280,10 +281,14 @@ int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* nam | |||
for (int i = 0; i < CLIENT_NUM; i++) { | |||
JackClientInterface* old_client = fClientTable[i]; | |||
if (old_client) { | |||
if (old_client->ClientNotify(refnum, name, JackNotifyChannelInterface::kAddClient, true, 0) < 0) | |||
return -1; | |||
if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, JackNotifyChannelInterface::kAddClient, true, 0) < 0) | |||
return -1; | |||
if (old_client->ClientNotify(refnum, name, JackNotifyChannelInterface::kAddClient, true, 0) < 0) { | |||
jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName); | |||
return -1; | |||
} | |||
if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, JackNotifyChannelInterface::kAddClient, true, 0) < 0) { | |||
jack_error("NotifyAddClient new_client fails name = %s", name); | |||
return -1; | |||
} | |||
} | |||
} | |||
@@ -341,7 +346,7 @@ void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) | |||
void JackEngine::NotifyActivate(int refnum) | |||
{ | |||
NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, false, 0); | |||
NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, true, 0); | |||
} | |||
//------------------- | |||
@@ -513,8 +518,10 @@ int JackEngine::ClientActivate(int refnum) | |||
assert(fClientTable[refnum]); | |||
JackLog("JackEngine::ClientActivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | |||
fGraphManager->Activate(refnum); | |||
// Wait for graph state change to be effective | |||
if (!fSignal->TimedWait(fEngineControl->fPeriodUsecs * 10)) { | |||
if (!fSignal->TimedWait(fEngineControl->fTimeOutUsecs * 10)) { | |||
jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | |||
return -1; | |||
} else { | |||
@@ -530,10 +537,12 @@ int JackEngine::ClientDeactivate(int refnum) | |||
if (client == NULL) | |||
return -1; | |||
JackLog("JackEngine::ClientDeactivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | |||
fGraphManager->DisconnectAllPorts(refnum); | |||
JackLog("JackEngine::ClientDeactivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | |||
fGraphManager->Deactivate(refnum); | |||
fLastSwitchUsecs = 0; // Force switch will occur next cycle, even when called with "dead" clients | |||
// Wait for graph state change to be effective | |||
if (!fSignal->TimedWait(fEngineControl->fPeriodUsecs * 10)) { | |||
if (!fSignal->TimedWait(fEngineControl->fTimeOutUsecs * 10)) { | |||
jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | |||
return -1; | |||
} else { | |||
@@ -193,6 +193,7 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff | |||
} | |||
} | |||
// Server | |||
int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // Client | |||
{ | |||
AssertPort(port_index); | |||
@@ -221,6 +222,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C | |||
return 0; | |||
} | |||
// Server | |||
jack_nframes_t JackGraphManager::GetTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) | |||
{ | |||
const jack_int_t* connections = manager->GetConnections(port_index); | |||
@@ -245,6 +247,7 @@ jack_nframes_t JackGraphManager::GetTotalLatencyAux(jack_port_id_t port_index, j | |||
return max_latency + latency; | |||
} | |||
// Server | |||
jack_nframes_t JackGraphManager::GetTotalLatency(jack_port_id_t port_index) | |||
{ | |||
UInt16 cur_index; | |||
@@ -293,6 +296,7 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, | |||
} else { | |||
res = manager->AddInputPort(refnum, port_index); | |||
} | |||
// Insertion failure | |||
if (res < 0) { | |||
JackPort* port = GetPort(port_index); | |||
assert(port); | |||
@@ -417,6 +421,38 @@ int JackGraphManager::DisconnectAll(jack_port_id_t port_index) | |||
return 0; | |||
} | |||
// Server | |||
void JackGraphManager::Activate(int refnum) | |||
{ | |||
DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||
DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||
} | |||
/* | |||
Disconnection from the FW must be done in last otherwise an intermediate "unconnected" | |||
(thus unactivated) state may happen where the client is still checked for its end. | |||
*/ | |||
// Server | |||
void JackGraphManager::Deactivate(int refnum) | |||
{ | |||
DisconnectAllPorts(refnum); | |||
// Disconnect only when needed | |||
if (IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) { | |||
DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||
} else { | |||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||
} | |||
// Disconnect only when needed | |||
if (IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) { | |||
DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||
} else { | |||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||
} | |||
} | |||
// Server | |||
int JackGraphManager::GetInputRefNum(jack_port_id_t port_index) | |||
{ | |||
@@ -633,12 +669,14 @@ void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const c | |||
res[i] = NULL; | |||
} | |||
// Client | |||
/* | |||
Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. | |||
The operation is lock-free since there is no intermediate state in the write operation that could cause the | |||
read to loop forever. | |||
*/ | |||
// Client | |||
const char** JackGraphManager::GetConnections(jack_port_id_t port_index) | |||
{ | |||
const char** res = (const char**)malloc(sizeof(char*) * (CONNECTION_NUM + 1)); | |||
@@ -88,6 +88,9 @@ class JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectio | |||
int RemovePort(int refnum, jack_port_id_t port_index); | |||
void RemoveAllPorts(int refnum); | |||
void DisconnectAllPorts(int refnum); | |||
void Activate(int refnum); | |||
void Deactivate(int refnum); | |||
int GetInputRefNum(jack_port_id_t port_index); | |||
int GetOutputRefNum(jack_port_id_t port_index); | |||
@@ -17,10 +17,10 @@ along with this program; if not, write to the Free Software | |||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#ifdef WIN32 | |||
#pragma warning (disable : 4786) | |||
#endif | |||
#ifdef WIN32 | |||
#pragma warning (disable : 4786) | |||
#endif | |||
#include "JackInternalClient.h" | |||
#include "JackEngine.h" | |||
@@ -31,7 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#include "JackInternalClientChannel.h" | |||
#include <assert.h> | |||
namespace Jack | |||
{ | |||
@@ -54,11 +54,13 @@ class JackInternalClientChannel : public JackClientChannelInterface | |||
} | |||
void ClientActivate(int refnum, int* result) | |||
{ | |||
*result = fServer->Activate(refnum); | |||
//*result = fServer->Activate(refnum); | |||
*result = fEngine->ClientActivate(refnum); | |||
} | |||
void ClientDeactivate(int refnum, int* result) | |||
{ | |||
*result = fServer->Deactivate(refnum); | |||
//*result = fServer->Deactivate(refnum); | |||
*result = fEngine->ClientDeactivate(refnum); | |||
} | |||
void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) | |||
@@ -188,11 +188,11 @@ int JackServer::Stop() | |||
return fAudioDriver->Stop(); | |||
} | |||
/* | |||
int JackServer::Activate(int refnum) | |||
{ | |||
int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||
fGraphManager->DirectConnect(fw_refnum, refnum); | |||
fGraphManager->DirectConnect(refnum, fw_refnum); | |||
fGraphManager->DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||
fGraphManager->DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||
return fEngine->ClientActivate(refnum); | |||
} | |||
@@ -201,18 +201,17 @@ int JackServer::Activate(int refnum) | |||
int JackServer::Deactivate(int refnum) | |||
{ | |||
int res = fEngine->ClientDeactivate(refnum); | |||
int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||
// Disconnect only when needed | |||
if (fGraphManager->IsDirectConnection(refnum, fw_refnum)) { | |||
fGraphManager->DirectDisconnect(refnum, fw_refnum); | |||
if (fGraphManager->IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) { | |||
fGraphManager->DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||
} else { | |||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||
} | |||
// Disconnect only when needed | |||
if (fGraphManager->IsDirectConnection(fw_refnum, refnum)) { | |||
fGraphManager->DirectDisconnect(fw_refnum, refnum); | |||
if (fGraphManager->IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) { | |||
fGraphManager->DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||
} else { | |||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||
} | |||
@@ -220,6 +219,17 @@ int JackServer::Deactivate(int refnum) | |||
return res; | |||
} | |||
int JackServer::Activate(int refnum) | |||
{ | |||
return fEngine->ClientActivate(refnum); | |||
} | |||
int JackServer::Deactivate(int refnum) | |||
{ | |||
return fEngine->ClientDeactivate(refnum); | |||
} | |||
*/ | |||
int JackServer::SetBufferSize(jack_nframes_t buffer_size) | |||
{ | |||
JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size); | |||
@@ -305,8 +315,10 @@ void JackServer::Notify(int refnum, int notify, int value) | |||
case JackNotifyChannelInterface::kDeadClient: | |||
JackLog("JackServer: kDeadClient ref = %ld\n", refnum); | |||
if (Deactivate(refnum) < 0) | |||
jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!\n", refnum); | |||
//if (Deactivate(refnum) < 0) | |||
// jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!", refnum); | |||
if (fEngine->ClientDeactivate(refnum) < 0) | |||
jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!", refnum); | |||
fEngine->ClientClose(refnum); | |||
break; | |||
} | |||
@@ -72,8 +72,8 @@ class EXPORT JackServer | |||
int Start(); | |||
int Stop(); | |||
int Activate(int refnum); | |||
int Deactivate(int refnum); | |||
//int Activate(int refnum); | |||
//int Deactivate(int refnum); | |||
int SetBufferSize(jack_nframes_t buffer_size); | |||
int SetFreewheel(bool onoff); | |||
@@ -176,7 +176,8 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||
JackResult res; | |||
JackLog("JackRequest::ActivateClient\n"); | |||
if (req.Read(socket) == 0) | |||
res.fResult = fServer->Activate(req.fRefNum); | |||
//res.fResult = fServer->Activate(req.fRefNum); | |||
res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum); | |||
res.Write(socket); | |||
break; | |||
} | |||
@@ -186,7 +187,8 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||
JackDeactivateRequest req; | |||
JackResult res; | |||
if (req.Read(socket) == 0) | |||
res.fResult = fServer->Deactivate(req.fRefNum); | |||
//res.fResult = fServer->Deactivate(req.fRefNum); | |||
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); | |||
res.Write(socket); | |||
break; | |||
} | |||
@@ -547,7 +547,7 @@ int main(int argc, char* argv[]) | |||
int res = JackStart(sample_sate, buffer_size, chan_in, chan_out, name, audiodevice, sync, timeout, rt); | |||
if (res < 0) { | |||
jack_error("Cannot start server... exit\n"); | |||
jack_error("Cannot start server... exit"); | |||
JackDelete(); | |||
return 0; | |||
} | |||
@@ -55,9 +55,6 @@ typedef uint32_t jack_nframes_t; | |||
#ifdef WIN32 | |||
typedef int64_t jack_time_t; | |||
//typedef double jack_time_t; | |||
//typedef uint64_t jack_time_t; | |||
#else | |||
typedef uint64_t jack_time_t; | |||
#endif | |||
@@ -55,7 +55,8 @@ rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, i | |||
JackLog("rpc_jack_client_activate\n"); | |||
JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | |||
assert(channel); | |||
*result = channel->GetServer()->Activate(refnum); | |||
//*result = channel->GetServer()->Activate(refnum); | |||
*result = channel->GetEngine()->ClientActivate(refnum); | |||
return KERN_SUCCESS; | |||
} | |||
@@ -64,7 +65,8 @@ rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, | |||
JackLog("rpc_jack_client_deactivate\n"); | |||
JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | |||
assert(channel); | |||
*result = channel->GetServer()->Deactivate(refnum); | |||
//*result = channel->GetServer()->Deactivate(refnum); | |||
*result = channel->GetEngine()->ClientDeactivate(refnum); | |||
return KERN_SUCCESS; | |||
} | |||