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)
289 JackFixedMatrix<CLIENT_NUM>* tmp =
new JackFixedMatrix<CLIENT_NUM>;
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);