20 #include "JackConnectionManager.h"    21 #include "JackClientControl.h"    22 #include "JackEngineControl.h"    23 #include "JackGlobals.h"    24 #include "JackError.h"    32 JackConnectionManager::JackConnectionManager()
    35     jack_log(
"JackConnectionManager::InitConnections size = %ld ", 
sizeof(JackConnectionManager));
    37     for (i = 0; i < PORT_NUM_MAX; i++) {
    38         fConnection[i].Init();
    43     jack_log(
"JackConnectionManager::InitClients");
    44     for (i = 0; i < CLIENT_NUM; i++) {
    49 JackConnectionManager::~JackConnectionManager()
    56 bool JackConnectionManager::IsLoopPathAux(
int ref1, 
int ref2)
 const    58     jack_log(
"JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", ref1, ref2);
    60     if (ref1 < GetEngineControl()->fDriverNum || ref2 < GetEngineControl()->fDriverNum) {
    62     } 
else if (ref1 == ref2) {  
    65         jack_int_t output[CLIENT_NUM];
    68         if (fConnectionRef.IsInsideTable(ref2, output)) { 
    71             for (
int i = 0; i < CLIENT_NUM && output[i] != EMPTY; i++) { 
    72                 if (IsLoopPathAux(output[i], ref2)) {
    90     jack_log(
"JackConnectionManager::Connect port_src = %ld port_dst = %ld", port_src, port_dst);
    92     if (fConnection[port_src].AddItem(port_dst)) {
   105     jack_log(
"JackConnectionManager::Disconnect port_src = %ld port_dst = %ld", port_src, port_dst);
   107     if (fConnection[port_src].RemoveItem(port_dst)) {
   120     return fConnection[port_src].CheckItem(port_dst);
   128     return fConnection[port_index].GetItems();
   140     if (fInputPort[refnum].AddItem(port_index)) {
   141         jack_log(
"JackConnectionManager::AddInputPort ref = %ld port = %ld", refnum, port_index);
   144         jack_error(
"Maximum number of input ports is reached for application ref = %ld", refnum);
   154     if (fOutputPort[refnum].AddItem(port_index)) {
   155         jack_log(
"JackConnectionManager::AddOutputPort ref = %ld port = %ld", refnum, port_index);
   158         jack_error(
"Maximum number of output ports is reached for application ref = %ld", refnum);
   168     jack_log(
"JackConnectionManager::RemoveInputPort ref = %ld port_index = %ld ", refnum, port_index);
   170     if (fInputPort[refnum].RemoveItem(port_index)) {
   173         jack_error(
"Input port index = %ld not found for application ref = %ld", port_index, refnum);
   183     jack_log(
"JackConnectionManager::RemoveOutputPort ref = %ld port_index = %ld ", refnum, port_index);
   185     if (fOutputPort[refnum].RemoveItem(port_index)) {
   188         jack_error(
"Output port index = %ld not found for application ref = %ld", port_index, refnum);
   198     return fInputPort[refnum].GetItems();
   206     return fOutputPort[refnum].GetItems();
   214     fInputPort[refnum].Init();
   215     fOutputPort[refnum].Init();
   216     fConnectionRef.Init(refnum);
   217     fInputCounter[refnum].SetValue(0);
   226     for (
int i = 0; i < CLIENT_NUM; i++) {
   227         fInputCounter[i].Reset();
   228         timing[i].fStatus = NotTriggered;
   238     if ((res = table[control->fRefNum].TimedWait(time_out_usec))) {
   239         timing[control->fRefNum].fStatus = Running;
   240         timing[control->fRefNum].fAwakeAt = GetMicroSeconds();
   242     return (res) ? 0 : -1;
   250     jack_time_t current_date = GetMicroSeconds();
   251     const jack_int_t* output_ref = fConnectionRef.GetItems(control->fRefNum);
   255     timing[control->fRefNum].fStatus = Finished;
   256     timing[control->fRefNum].fFinishedAt = current_date;
   258     for (
int i = 0; i < CLIENT_NUM; i++) {
   261         if (output_ref[i] > 0) {
   264             timing[i].fStatus = Triggered;
   265             timing[i].fSignaledAt = current_date;
   267             if (!fInputCounter[i].Signal(table + i, control)) {
   268                 jack_log(
"JackConnectionManager::ResumeRefNum error: ref = %ld output = %ld ", control->fRefNum, i);
   277 static bool HasNoConnection(jack_int_t* table)
   279     for (
int ref = 0; ref < CLIENT_NUM; ref++) {
   280         if (table[ref] > 0) 
return false;
   287 void JackConnectionManager::TopologicalSort(std::vector<jack_int_t>& sorted)
   290     std::set<jack_int_t> level;
   292     fConnectionRef.Copy(*tmp);
   295     level.insert(AUDIO_DRIVER_REFNUM);
   296     level.insert(FREEWHEEL_DRIVER_REFNUM);
   298     while (level.size() > 0) {
   299         jack_int_t refnum = *level.begin();
   300         sorted.push_back(refnum);
   301         level.erase(level.begin());
   302         const jack_int_t* output_ref1 = tmp->GetItems(refnum);
   303         for (
int dst = 0; dst < CLIENT_NUM; dst++) {
   304             if (output_ref1[dst] > 0) {
   305                 tmp->ClearItem(refnum, dst);
   306                 jack_int_t output_ref2[CLIENT_NUM];
   307                 tmp->GetOutputTable1(dst, output_ref2);
   308                 if (HasNoConnection(output_ref2)) {
   326     assert(ref1 >= 0 && ref2 >= 0);
   329     jack_log(
"JackConnectionManager::IncConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
   340     assert(ref1 >= 0 && ref2 >= 0);
   343     jack_log(
"JackConnectionManager::DecConnectionRef: ref1 = %ld ref2 = %ld", ref1, ref2);
   351     assert(ref1 >= 0 && ref2 >= 0);
   353     if (fConnectionRef.IncItem(ref1, ref2) == 1) { 
   354         jack_log(
"JackConnectionManager::DirectConnect first: ref1 = %ld ref2 = %ld", ref1, ref2);
   355         fInputCounter[ref2].IncValue();
   364     assert(ref1 >= 0 && ref2 >= 0);
   366     if (fConnectionRef.DecItem(ref1, ref2) == 0) { 
   367         jack_log(
"JackConnectionManager::DirectDisconnect last: ref1 = %ld ref2 = %ld", ref1, ref2);
   368         fInputCounter[ref2].DecValue();
   377     assert(ref1 >= 0 && ref2 >= 0);
   378     return (fConnectionRef.GetItemCount(ref1, ref2) > 0);
   386     for (
int i = 0; i < CLIENT_NUM; i++) {
   387         if (fInputPort[i].CheckItem(port_index)) {
   400     for (
int i = 0; i < CLIENT_NUM; i++) {
   401         if (fOutputPort[i].CheckItem(port_index)) {
   417 bool JackConnectionManager::IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
 const   422 bool JackConnectionManager::IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
   428     jack_log(
"JackConnectionManager::IncFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
   429     assert(ref1 >= 0 && ref2 >= 0);
   435     return fLoopFeedback.IncConnection(ref1, ref2); 
   438 bool JackConnectionManager::DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
   444     jack_log(
"JackConnectionManager::DecFeedbackConnection ref1 = %ld ref2 = %ld", ref1, ref2);
   445     assert(ref1 >= 0 && ref2 >= 0);
   451     return fLoopFeedback.DecConnection(ref1, ref2); 
 void DirectDisconnect(int ref1, int ref2)
Directly disconnect 2 reference numbers. 
int GetOutputRefNum(jack_port_id_t port_index) const
Get the client refnum of a given ouput port. 
int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst)
Disconnect port_src from port_dst. 
bool IsDirectConnection(int ref1, int ref2) const
Returns the connections state between 2 refnum. 
void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
Increment the number of ports between 2 clients, if the 2 clients become connected, then the Activation counter is updated. 
int GetConnectionIndex(int ref1, int ref2) const
Test if a connection between 2 refnum is a feedback connection. 
int SuspendRefNum(JackClientControl *control, JackSynchro *table, JackClientTiming *timing, long time_out_usec)
Wait on the input synchro. 
Inter process synchronization using POSIX semaphore. 
void ResetGraph(JackClientTiming *timing)
Reset all clients activation. 
SERVER_EXPORT void jack_error(const char *fmt,...)
int RemoveInputPort(int refnum, jack_port_id_t port_index)
Remove an input port from a client. 
int AddOutputPort(int refnum, jack_port_id_t port_index)
Add an output port to a client. 
void GetOutputTable(jack_int_t index, jack_int_t *output) const
Get the output indexes of a given index. 
int GetInputRefNum(jack_port_id_t port_index) const
Get the client refnum of a given input port. 
void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst)
Decrement the number of ports between 2 clients, if the 2 clients become disconnected, then the Activation counter is updated. 
int Connect(jack_port_id_t port_src, jack_port_id_t port_dst)
Connect port_src to port_dst. 
const jack_int_t * GetOutputPorts(int refnum)
Get the output port array of a given refnum. 
bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const
Test is a connection path exists between port_src and port_dst. 
void DirectConnect(int ref1, int ref2)
Directly connect 2 reference numbers. 
int RemoveOutputPort(int refnum, jack_port_id_t port_index)
Remove an output port from a client. 
For client timing measurements. 
void InitRefNum(int refnum)
Init the refnum. 
int AddInputPort(int refnum, jack_port_id_t port_index)
Add an input port to a client. 
int ResumeRefNum(JackClientControl *control, JackSynchro *table, JackClientTiming *timing)
Signal clients connected to the given client. 
bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const
Check if port_src and port_dst are connected. 
const jack_int_t * GetConnections(jack_port_id_t port_index) const
Get the connection port array. 
SERVER_EXPORT void jack_log(const char *fmt,...)
const jack_int_t * GetInputPorts(int refnum)
Get the input port array of a given refnum. 
Client control possibly in shared memory.