diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 6789d9875..2c44dca40 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -291,7 +291,7 @@ static inline bool CheckBufferSize(jack_nframes_t buffer_size) return (buffer_size >= 1 && buffer_size <= BUFFER_SIZE_MAX); } -static inline void WaitGraphChange() +static inline void WaitGraphChange(JackGlobals *globals) { /* TLS key that is set only in RT thread, so never waits for pending @@ -299,8 +299,8 @@ static inline void WaitGraphChange() */ if (jack_tls_get(JackGlobals::fRealTimeThread) == NULL) { - JackGraphManager* manager = GetGraphManager(); - JackEngineControl* control = GetEngineControl(); + JackGraphManager* manager = globals->GetGraphManager(); + JackEngineControl* control = globals->GetEngineControl(); assert(manager); assert(control); if (manager->IsPendingChange()) { @@ -348,13 +348,17 @@ LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) { JackGlobals::CheckContext("jack_port_get_buffer"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_buffer called with an incorrect port %ld", myport); return NULL; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + if (!global) { + jack_error("jack_port_get_buffer called with invalid context (port %ld)", myport); + return NULL; + } + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetBuffer(myport, frames) : NULL); } } @@ -363,8 +367,7 @@ LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_uuid"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_uuid called with an incorrect port %ld", myport); return 0; @@ -377,13 +380,13 @@ LIB_EXPORT const char* jack_port_name(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_name"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_name called with an incorrect port %ld", myport); return NULL; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetName() : NULL); } } @@ -392,13 +395,13 @@ LIB_EXPORT const char* jack_port_short_name(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_short_name"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_short_name called with an incorrect port %ld", myport); return NULL; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetShortName() : NULL); } } @@ -407,13 +410,13 @@ LIB_EXPORT int jack_port_flags(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_flags"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_flags called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetFlags() : -1); } } @@ -422,13 +425,13 @@ LIB_EXPORT const char* jack_port_type(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_type"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_flags called an incorrect port %ld", myport); return NULL; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetType() : NULL); } } @@ -437,13 +440,13 @@ LIB_EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) { JackGlobals::CheckContext("jack_port_type_id"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_type_id called an incorrect port %ld", myport); return 0; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? GetPortTypeId(manager->GetPort(myport)->GetType()) : 0); } } @@ -452,14 +455,14 @@ LIB_EXPORT int jack_port_connected(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_connected"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_connected called with an incorrect port %ld", myport); return -1; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetConnectionsNum(myport) : -1); } } @@ -468,8 +471,7 @@ LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_ { JackGlobals::CheckContext("jack_port_connected_to"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t src = (jack_port_id_t)port_aux; + jack_port_id_t src = JackGlobals::PortId(port); if (!CheckPort(src)) { jack_error("jack_port_connected_to called with an incorrect port %ld", src); return -1; @@ -477,8 +479,9 @@ LIB_EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_ jack_error("jack_port_connected_to called with a NULL port name"); return -1; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); jack_port_id_t dst = (manager ? manager->GetPort(port_name) : NO_PORT); if (dst == NO_PORT) { jack_error("Unknown destination port port_name = %s", port_name); @@ -493,19 +496,22 @@ LIB_EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) { JackGlobals::CheckContext("jack_port_tie"); - uintptr_t src_aux = (uintptr_t)src; - jack_port_id_t mysrc = (jack_port_id_t)src_aux; + jack_port_id_t mysrc = JackGlobals::PortId(src); if (!CheckPort(mysrc)) { jack_error("jack_port_tie called with a NULL src port"); return -1; } - uintptr_t dst_aux = (uintptr_t)dst; - jack_port_id_t mydst = (jack_port_id_t)dst_aux; + jack_port_id_t mydst = JackGlobals::PortId(dst); if (!CheckPort(mydst)) { jack_error("jack_port_tie called with a NULL dst port"); return -1; } - JackGraphManager* manager = GetGraphManager(); + if (JackGlobals::PortContext(src) != JackGlobals::PortContext(dst)) { + jack_error("jack_port_tie called with ports not belonging to the same context"); + return -1; + } + JackGlobals *global = JackGlobals::PortGlobal(src); + JackGraphManager* manager = global->GetGraphManager(); if (manager && manager->GetPort(mysrc)->GetRefNum() != manager->GetPort(mydst)->GetRefNum()) { jack_error("jack_port_tie called with ports not belonging to the same client"); return -1; @@ -518,13 +524,13 @@ LIB_EXPORT int jack_port_untie(jack_port_t* port) { JackGlobals::CheckContext("jack_port_untie"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_untie called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->UnTie() : -1); } } @@ -533,14 +539,14 @@ LIB_EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_latency"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_latency called with an incorrect port %ld", myport); return 0; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetLatency() : 0); } } @@ -549,12 +555,12 @@ LIB_EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) { JackGlobals::CheckContext("jack_port_set_latency"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_set_latency called with an incorrect port %ld", myport); } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); if (manager) manager->GetPort(myport)->SetLatency(frames); } @@ -564,13 +570,13 @@ LIB_EXPORT void jack_port_get_latency_range(jack_port_t *port, jack_latency_call { JackGlobals::CheckContext("jack_port_get_latency_range"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_latency_range called with an incorrect port %ld", myport); } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); if (manager) manager->GetPort(myport)->GetLatencyRange(mode, range); } @@ -580,13 +586,13 @@ LIB_EXPORT void jack_port_set_latency_range(jack_port_t *port, jack_latency_call { JackGlobals::CheckContext("jack_port_set_latency_range"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_set_latency_range called with an incorrect port %ld", myport); } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); if (manager) manager->GetPort(myport)->SetLatencyRange(mode, range); } @@ -598,8 +604,7 @@ LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port JackClient* client = (JackClient*)ext_client; - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (client == NULL) { jack_error("jack_recompute_total_latency called with a NULL client"); return -1; @@ -607,8 +612,9 @@ LIB_EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port jack_error("jack_recompute_total_latency called with a NULL port"); return -1; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->ComputeTotalLatency(myport) : -1); } } @@ -634,7 +640,8 @@ LIB_EXPORT int jack_port_set_name(jack_port_t* port, const char* name) // Find a valid client jack_client_t* client = NULL; for (int i = 0; i < CLIENT_NUM; i++) { - if ((client = (jack_client_t*)JackGlobals::fClientTable[i])) { + JackGlobals *global = JackGlobals::PortGlobal(port); + if ((client = (jack_client_t*)global->fClientTable[i])) { break; } } @@ -647,8 +654,7 @@ LIB_EXPORT int jack_port_rename(jack_client_t* ext_client, jack_port_t* port, co JackGlobals::CheckContext("jack_port_rename"); JackClient* client = (JackClient*)ext_client; - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (client == NULL) { jack_error("jack_port_rename called with a NULL client"); return -1; @@ -667,8 +673,7 @@ LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_set_alias"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_set_alias called with an incorrect port %ld", myport); return -1; @@ -676,7 +681,8 @@ LIB_EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) jack_error("jack_port_set_alias called with a NULL port name"); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->SetAlias(name) : -1); } } @@ -685,8 +691,7 @@ LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) { JackGlobals::CheckContext("jack_port_unset_alias"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_unset_alias called with an incorrect port %ld", myport); return -1; @@ -694,7 +699,8 @@ LIB_EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) jack_error("jack_port_unset_alias called with a NULL port name"); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->UnsetAlias(name) : -1); } } @@ -703,13 +709,13 @@ LIB_EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliase { JackGlobals::CheckContext("jack_port_get_aliases"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_aliases called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetPort(myport)->GetAliases(aliases) : -1); } } @@ -718,13 +724,13 @@ LIB_EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) { JackGlobals::CheckContext("jack_port_request_monitor"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_request_monitor called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->RequestMonitor(myport, onoff) : -1); } } @@ -738,7 +744,7 @@ LIB_EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, cons jack_error("jack_port_request_monitor_by_name called with a NULL client"); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGraphManager* manager = client->GetGlobal()->GetGraphManager(); if (!manager) return -1; jack_port_id_t myport = manager->GetPort(port_name); @@ -755,13 +761,13 @@ LIB_EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) { JackGlobals::CheckContext("jack_port_ensure_monitor"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_ensure_monitor called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global ? global->GetGraphManager() : nullptr; return (manager ? manager->GetPort(myport)->EnsureMonitor(onoff) : -1); } } @@ -770,13 +776,13 @@ LIB_EXPORT int jack_port_monitoring_input(jack_port_t* port) { JackGlobals::CheckContext("jack_port_monitoring_input"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_monitoring_input called with an incorrect port %ld", myport); return -1; } else { - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + JackGraphManager* manager = global ? global->GetGraphManager() : nullptr; return (manager ? manager->GetPort(myport)->MonitoringInput() : -1); } } @@ -790,7 +796,7 @@ LIB_EXPORT int jack_is_realtime(jack_client_t* ext_client) jack_error("jack_is_realtime called with a NULL client"); return -1; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fRealTime : -1); } } @@ -1095,7 +1101,9 @@ LIB_EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char jack_error("jack_port_register called with a NULL port name or a NULL port_type"); return NULL; } else { - return (jack_port_t *)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size)); + JackGlobals* global =client->GetGlobal(); + jack_port_id_t port_id = (jack_port_id_t)((uintptr_t)client->PortRegister(port_name, port_type, flags, buffer_size)); + return global->PortById(port_id); } } @@ -1108,8 +1116,7 @@ LIB_EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port jack_error("jack_port_unregister called with a NULL client"); return -1; } - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_unregister called with an incorrect port %ld", myport); return -1; @@ -1126,8 +1133,7 @@ LIB_EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_por jack_error("jack_port_is_mine called with a NULL client"); return -1; } - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_is_mine called with an incorrect port %ld", myport); return -1; @@ -1139,14 +1145,14 @@ LIB_EXPORT const char** jack_port_get_connections(const jack_port_t* port) { JackGlobals::CheckContext("jack_port_get_connections"); - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_connections called with an incorrect port %ld", myport); return NULL; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetConnections(myport) : NULL); } } @@ -1162,14 +1168,14 @@ LIB_EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_c return NULL; } - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_all_connections called with an incorrect port %ld", myport); return NULL; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); return (manager ? manager->GetConnections(myport) : NULL); } } @@ -1184,14 +1190,14 @@ LIB_EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, return 0; } - uintptr_t port_aux = (uintptr_t)port; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(port); if (!CheckPort(myport)) { jack_error("jack_port_get_total_latency called with an incorrect port %ld", myport); return 0; } else { - WaitGraphChange(); - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = JackGlobals::PortGlobal(port); + WaitGraphChange(global); + JackGraphManager* manager = global->GetGraphManager(); if (manager) { manager->ComputeTotalLatency(myport); return manager->GetPort(myport)->GetTotalLatency(); @@ -1242,8 +1248,7 @@ LIB_EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) jack_error("jack_port_disconnect called with a NULL client"); return -1; } - uintptr_t port_aux = (uintptr_t)src; - jack_port_id_t myport = (jack_port_id_t)port_aux; + jack_port_id_t myport = JackGlobals::PortId(src); if (!CheckPort(myport)) { jack_error("jack_port_disconnect called with an incorrect port %ld", myport); return -1; @@ -1260,7 +1265,7 @@ LIB_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) jack_error("jack_get_sample_rate called with a NULL client"); return 0; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fSampleRate : 0); } } @@ -1274,7 +1279,7 @@ LIB_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) jack_error("jack_get_buffer_size called with a NULL client"); return 0; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fBufferSize : 0); } } @@ -1288,7 +1293,7 @@ LIB_EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* po jack_error("jack_get_ports called with a NULL client"); return NULL; } - JackGraphManager* manager = GetGraphManager(); + JackGraphManager* manager = client->GetGlobal()->GetGraphManager(); return (manager ? manager->GetPorts(port_name_pattern, type_name_pattern, flags) : NULL); } @@ -1307,10 +1312,11 @@ LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* return NULL; } - JackGraphManager* manager = GetGraphManager(); + JackGlobals *global = client->GetGlobal(); + JackGraphManager* manager = global->GetGraphManager(); if (manager) { - int res = manager->GetPort(portname); // returns a port index at least > 1 - return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res); + jack_port_id_t port_id = manager->GetPort(portname); // returns a port index at least > 1 + return (port_id == NO_PORT) ? NULL : global->PortById(port_id); } else { return NULL; } @@ -1343,7 +1349,7 @@ LIB_EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext JackGlobals::CheckContext("jack_frames_since_cycle_start"); JackTimer timer; - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = ((JackClient*)ext_client)->GetGlobal()->GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.FramesSinceCycleStart(GetMicroSeconds(), control->fSampleRate); @@ -1369,7 +1375,7 @@ LIB_EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack return 0; } else { JackTimer timer; - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.Frames2Time(frames, control->fBufferSize); @@ -1389,7 +1395,7 @@ LIB_EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, j return 0; } else { JackTimer timer; - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); if (control) { control->ReadFrameTime(&timer); return timer.Time2Frames(usecs, control->fBufferSize); @@ -1410,7 +1416,7 @@ LIB_EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) { JackGlobals::CheckContext("jack_last_frame_time"); - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = ((JackClient*)ext_client)->GetGlobal()->GetEngineControl(); return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0; } @@ -1422,7 +1428,7 @@ LIB_EXPORT int jack_get_cycle_times(const jack_client_t *client, { JackGlobals::CheckContext("jack_get_cycle_times"); - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = ((JackClient*)client)->GetGlobal()->GetEngineControl(); if (control) { JackTimer timer; control->ReadFrameTime(&timer); @@ -1441,7 +1447,7 @@ LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client) jack_error("jack_cpu_load called with a NULL client"); return 0.0f; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fCPULoad : 0.0f); } } @@ -1501,7 +1507,7 @@ LIB_EXPORT size_t jack_port_type_get_buffer_size(jack_client_t* ext_client, cons jack_error("jack_port_type_get_buffer_size called with an unknown port type = %s", port_type); return 0; } else { - return GetPortType(port_id)->size(); + return GetPortType(port_id)->size(client->GetGlobal()); } } } @@ -1666,7 +1672,7 @@ LIB_EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) jack_error("jack_get_max_delayed_usecs called with a NULL client"); return 0.f; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fMaxDelayedUsecs : 0.f); } } @@ -1680,7 +1686,7 @@ LIB_EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) jack_error("jack_get_xrun_delayed_usecs called with a NULL client"); return 0.f; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control ? control->fXrunDelayedUsecs : 0.f); } } @@ -1693,7 +1699,7 @@ LIB_EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) if (client == NULL) { jack_error("jack_reset_max_delayed_usecs called with a NULL client"); } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); control->ResetXRun(); } } @@ -1708,7 +1714,7 @@ LIB_EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) jack_error("jack_client_real_time_priority called with a NULL client"); return -1; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control->fRealTime) ? control->fClientPriority : -1; } } @@ -1722,17 +1728,19 @@ LIB_EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) jack_error("jack_client_max_real_time_priority called with a NULL client"); return -1; } else { - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = client->GetGlobal()->GetEngineControl(); return (control->fRealTime) ? control->fMaxClientPriority : -1; } } LIB_EXPORT int jack_acquire_real_time_scheduling(jack_native_thread_t thread, int priority) { - JackEngineControl* control = GetEngineControl(); - return (control - ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint) - : -1); + jack_error("jack_acquire_real_time_scheduling is not implemented"); + abort(); +// JackEngineControl* control = GetEngineControl(); +// return (control +// ? JackThread::AcquireRealTimeImp(thread, priority, control->fPeriod, control->fComputation, control->fConstraint) +// : -1); } LIB_EXPORT int jack_client_create_thread(jack_client_t* client, @@ -1744,7 +1752,7 @@ LIB_EXPORT int jack_client_create_thread(jack_client_t* client, { JackGlobals::CheckContext("jack_client_create_thread"); - JackEngineControl* control = GetEngineControl(); + JackEngineControl* control = ((JackClient*)client)->GetGlobal()->GetEngineControl(); int res = JackThread::StartImp(thread, priority, realtime, routine, arg); return (res == 0) ? ((realtime ? JackThread::AcquireRealTimeImp(*thread, priority, control->fPeriod, control->fComputation, control->fConstraint) : res)) diff --git a/common/JackAudioAdapterFactory.cpp b/common/JackAudioAdapterFactory.cpp index 9ceeee04a..514819835 100644 --- a/common/JackAudioAdapterFactory.cpp +++ b/common/JackAudioAdapterFactory.cpp @@ -60,9 +60,15 @@ extern "C" jack_nframes_t buffer_size = jack_get_buffer_size(jack_client); jack_nframes_t sample_rate = jack_get_sample_rate(jack_client); + + if (jack_client == NULL) { + jack_error("jack_internal_initialize called with NULL jack_client"); + return 1; + } + try { - adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackPlatformAdapter(buffer_size, sample_rate, params), params); + adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackPlatformAdapter(*((JackClient*) jack_client), buffer_size, sample_rate, params), params); assert(adapter); if (adapter->Open() == 0) { diff --git a/common/JackAudioPort.cpp b/common/JackAudioPort.cpp index ac8943ec5..fb15364aa 100644 --- a/common/JackAudioPort.cpp +++ b/common/JackAudioPort.cpp @@ -154,9 +154,9 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun } } -static size_t AudioBufferSize() +static size_t AudioBufferSize(JackGlobals *global) { - return GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); + return global->GetEngineControl()->fBufferSize * sizeof(jack_default_audio_sample_t); } const JackPortType gAudioPortType = diff --git a/common/JackClient.cpp b/common/JackClient.cpp index b03dbc25d..11e1972fa 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -39,9 +39,10 @@ namespace Jack #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL)) -JackClient::JackClient(JackSynchro* table):fThread(this) +JackClient::JackClient(JackGlobals* globals):JackGlobalsInterface(globals), + fThread(this) { - fSynchroTable = table; + fSynchroTable = globals->GetSynchroTable(); fProcess = NULL; fGraphOrder = NULL; fXrun = NULL; @@ -114,11 +115,12 @@ int JackClient::Close() fChannel->ClientClose(GetClientControl()->fRefNum, &result); fChannel->Close(); - assert(JackGlobals::fSynchroMutex); - JackGlobals::fSynchroMutex->Lock(); + assert(GetGlobal()); + assert(GetGlobal()->fSynchroMutex); + GetGlobal()->fSynchroMutex->Lock(); fSynchroTable[GetClientControl()->fRefNum].Disconnect(); - JackGlobals::fSynchroMutex->Unlock(); - JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL; + GetGlobal()->fSynchroMutex->Unlock(); + GetGlobal()->fClientTable[GetClientControl()->fRefNum] = nullptr; return result; } @@ -1345,6 +1347,5 @@ int JackClient::PropertyChangeNotify(jack_uuid_t subject, const char* key, jack_ return result; } - } // end of namespace diff --git a/common/JackClient.h b/common/JackClient.h index a0e506e7d..3ffc5cdbd 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackChannel.h" #include "JackRequest.h" #include "JackMetadata.h" +#include "JackGlobals.h" #include "varargs.h" #include @@ -45,7 +46,7 @@ struct JackEngineControl; \brief The base class for clients: share part of the implementation for JackInternalClient and JackLibClient. */ -class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnableInterface +class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnableInterface, public JackGlobalsInterface { friend class JackDebugClient; @@ -128,7 +129,7 @@ class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnable public: - JackClient(JackSynchro* table); + JackClient(JackGlobals* globals); virtual ~JackClient(); char* GetServerName() { return fServerName; } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index a0cc04391..a0caf77ce 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -57,7 +57,7 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const { jack_log("JackConnectionManager::IsLoopPathAux ref1 = %ld ref2 = %ld", ref1, ref2); - if (ref1 < GetEngineControl()->fDriverNum || ref2 < GetEngineControl()->fDriverNum) { + if (ref1 < GetGlobal()->GetEngineControl()->fDriverNum || ref2 < GetGlobal()->GetEngineControl()->fDriverNum) { return false; } else if (ref1 == ref2) { // Same refnum return true; diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index ead32092a..1c283c6d5 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackConstants.h" #include "JackActivationCount.h" #include "JackError.h" +#include "JackGlobals.h" #include "JackCompilerDeps.h" #include #include @@ -408,7 +409,7 @@ struct JackClientTiming */ PRE_PACKED_STRUCTURE -class SERVER_EXPORT JackConnectionManager +class SERVER_EXPORT JackConnectionManager : public JackGlobalsInterface { private: diff --git a/common/JackConstants.h b/common/JackConstants.h index cae545664..6d649e7a7 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -57,6 +57,12 @@ #define PORT_NUM_FOR_CLIENT 768 #endif +// used by JackLib when process has mulitple clients connecting to different Jack Servers +#define PORT_SERVER_CONTEXT_BITS (8) +#define PORT_SERVER_CONTEXT_MAX ((1 << PORT_SERVER_CONTEXT_BITS) - 1) +#define PORT_SERVER_CONTEXT_SHIFT (sizeof(jack_port_id_t) * 8 - PORT_SERVER_CONTEXT_BITS) +#define PORT_SERVER_CONTEXT_MASK (PORT_SERVER_CONTEXT_MAX << PORT_SERVER_CONTEXT_SHIFT) + #define FIRST_AVAILABLE_PORT 1 #define CONNECTION_NUM_FOR_PORT PORT_NUM_FOR_CLIENT diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index bbabbac1d..86d4a7cd8 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -1052,6 +1052,12 @@ jackctl_server_open( goto fail; } + JackServerGlobals *global = JackGlobalsManager::Instance()->CreateGlobal(server_ptr->name.str); + if (global == nullptr) { + jack_error("Failed to create global context"); + goto fail; + } + /* get the engine/driver started */ server_ptr->engine = new JackServer( server_ptr->sync.b, @@ -1063,7 +1069,8 @@ jackctl_server_open( server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->self_connect_mode.c, - server_ptr->name.str); + server_ptr->name.str, + global); if (server_ptr->engine == NULL) { jack_error("Failed to create new JackServer object"); diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index a7d11f9e4..e4a41b0da 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -35,7 +35,7 @@ namespace Jack { JackDebugClient::JackDebugClient(JackClient * client) - : JackClient(client->fSynchroTable) + : JackClient(client->GetGlobal()) { fTotalPortNumber = 1; // The total number of port opened and maybe closed. Historical view. fOpenPortNumber = 0; // The current number of opened port. diff --git a/common/JackDriver.h b/common/JackDriver.h index c66e2500e..a78af100f 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -126,6 +126,7 @@ typedef std::list > > class SERVER_EXPORT JackDriver : public JackDriverClientInterface { + friend class JackThreadedDriver; protected: diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 21ae35991..4c47afdb6 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -92,7 +92,11 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem JackEngineProfiling fProfiler; #endif - JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) + JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name, JackGlobals *global) + : fTransport(global) +#ifdef JACK_MONITOR + , fProfiler(global) +#endif { fBufferSize = 512; fSampleRate = 48000; diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index f70cc7e4e..a3084c76c 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) +JackEngineProfiling::JackEngineProfiling(JackGlobals *global):fGlobal(global), fAudioCycle(0),fMeasuredClient(0) { jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024)); @@ -354,7 +354,7 @@ void JackEngineProfiling::Profile(JackClientInterface** table, fProfileTable[fAudioCycle].fPrevCycleEnd = prev_cycle_end; fProfileTable[fAudioCycle].fAudioCycle = fAudioCycle; - for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { + for (int i = fGlobal->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; JackClientTiming* timing = manager->GetClientTiming(i); if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) { diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index 894566a14..bebb8207b 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackTypes.h" #include "JackConstants.h" #include "JackShmMem.h" +#include "JackGlobals.h" namespace Jack { @@ -111,6 +112,8 @@ class SERVER_EXPORT JackEngineProfiling private: + JackGlobals* fGlobal; + JackTimingMeasure fProfileTable[TIME_POINTS]; JackTimingClientInterval fIntervalTable[MEASURED_CLIENTS]; @@ -121,7 +124,7 @@ class SERVER_EXPORT JackEngineProfiling public: - JackEngineProfiling(); + JackEngineProfiling(JackGlobals *global); ~JackEngineProfiling(); void Profile(JackClientInterface** table, diff --git a/common/JackGenericClientChannel.cpp b/common/JackGenericClientChannel.cpp index 96401d29d..f02f68096 100644 --- a/common/JackGenericClientChannel.cpp +++ b/common/JackGenericClientChannel.cpp @@ -25,8 +25,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -JackGenericClientChannel::JackGenericClientChannel() -{} +JackGenericClientChannel::JackGenericClientChannel(JackGlobals *global) +{ + fGlobals = global; +} JackGenericClientChannel::~JackGenericClientChannel() {} @@ -52,8 +54,8 @@ void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, *result = -1; return; } - - if (!JackGlobals::fServerRunning) { + + if (!fGlobals->fServerRunning) { jack_error("Server is not running"); *result = -1; return; @@ -83,7 +85,7 @@ void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res return; } - if (!JackGlobals::fServerRunning) { + if (!fGlobals->fServerRunning) { jack_error("Server is not running"); *result = -1; return; diff --git a/common/JackGenericClientChannel.h b/common/JackGenericClientChannel.h index b2c7b4ad0..ccfa54a85 100644 --- a/common/JackGenericClientChannel.h +++ b/common/JackGenericClientChannel.h @@ -27,6 +27,7 @@ namespace Jack struct JackRequest; struct JackResult; +class JackGlobals; /*! \brief Generic JackClientChannel class. @@ -37,6 +38,8 @@ class JackGenericClientChannel : public detail::JackClientChannelInterface protected: + JackGlobals *fGlobals; + detail::JackClientRequestInterface* fRequest; void ServerSyncCall(JackRequest* req, JackResult* res, int* result); @@ -44,7 +47,7 @@ class JackGenericClientChannel : public detail::JackClientChannelInterface public: - JackGenericClientChannel(); + JackGenericClientChannel(JackGlobals *global); virtual ~JackGenericClientChannel(); virtual int Open(const char* server_name, const char* name, jack_uuid_t uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) { return -1; } diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index 1047d1691..8c84083b4 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -34,9 +34,8 @@ jack_tls_key JackGlobals::fKeyLogFunction; static bool fKeyLogFunctionInitialized = jack_tls_allocate_key(&JackGlobals::fKeyLogFunction); JackMutex* JackGlobals::fOpenMutex = new JackMutex(); -JackMutex* JackGlobals::fSynchroMutex = new JackMutex(); -volatile bool JackGlobals::fServerRunning = false; -JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; + +JackGlobalsManager JackGlobalsManager::fInstance; #ifndef WIN32 jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; @@ -78,4 +77,16 @@ void JackGlobals::CheckContext(const char* name) #endif +JackGlobals::JackGlobals(const std::string &server_name) + : fServerRunning(false) + , fSynchroMutex(new JackMutex) + , fServerName(server_name) +{ +} + +JackGlobals::~JackGlobals() +{ + delete fSynchroMutex; +} + } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 5d7c24214..d58dd86f8 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -20,9 +20,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackGlobals__ #define __JackGlobals__ +#include +#include +#include +#include +#include + #include "JackPlatformPlug.h" #include "JackSystemDeps.h" #include "JackConstants.h" +#include "JackError.h" #ifdef __CLIENTDEBUG__ #include @@ -33,32 +40,239 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { + class JackGlobals; + class JackGraphManager; + class JackServer; + struct JackEngineControl; // Globals used for client management on server or library side. -struct JackGlobals { - - static jack_tls_key fRealTimeThread; - static jack_tls_key fNotificationThread; - static jack_tls_key fKeyLogFunction; - static JackMutex* fOpenMutex; - static JackMutex* fSynchroMutex; - static volatile bool fServerRunning; - static JackClient* fClientTable[CLIENT_NUM]; - static bool fVerbose; +class JackGlobalsManager +{ + + /* This object is managed by JackGlobalsManager */ + private: + + static JackGlobalsManager fInstance; + + JackGlobalsManager() {} + ~JackGlobalsManager() {} + + public: + + std::vector fContexts; + + inline static JackGlobalsManager* Instance() + { + return &fInstance; + } + + template + inline T* CreateGlobal(const std::string &server_name); + + inline void DestroyGlobal(const std::string &server_name); + +}; + +// Globals used for client management on server or library side. +class JackGlobals +{ + + friend class JackGlobalsManager; + + protected: + + JackGlobals(const std::string &server_name); + virtual ~JackGlobals(); + + public: + + static jack_tls_key fRealTimeThread; + static jack_tls_key fNotificationThread; + static jack_tls_key fKeyLogFunction; + static JackMutex* fOpenMutex; + static bool fVerbose; #ifndef WIN32 - static jack_thread_creator_t fJackThreadCreator; + static jack_thread_creator_t fJackThreadCreator; #endif #ifdef __CLIENTDEBUG__ - static std::ofstream* fStream; + static std::ofstream* fStream; #endif - static void CheckContext(const char* name); + static void CheckContext(const char* name); + + volatile bool fServerRunning; + JackMutex* fSynchroMutex; + std::mutex fMutex; + std::string fServerName; + JackClient* fClientTable[CLIENT_NUM]; + + /* is called each time a context for specific server is added */ + virtual bool AddContext(const uint32_t &cntx_num, const std::string &server_name) = 0; + + /* is called each time a context for specific server is removed */ + virtual bool DelContext(const uint32_t &cntx_num) = 0; + + virtual JackGraphManager* GetGraphManager() = 0; + virtual JackEngineControl* GetEngineControl() = 0; + virtual JackSynchro* GetSynchroTable() = 0; + virtual JackServer* GetServer() = 0; + + inline static jack_port_id_t PortId(const jack_port_t* port) + { + uintptr_t port_aux = (uintptr_t)port; + jack_port_id_t port_masked = (jack_port_id_t)port_aux; + jack_port_id_t port_id = port_masked & ~PORT_SERVER_CONTEXT_MASK; + return port_id; + } + + inline static JackGlobals* PortGlobal(const jack_port_t* port) + { + jack_port_id_t context_id = PortContext(port); + + if (context_id >= JackGlobalsManager::Instance()->fContexts.size()) + { + jack_error("invalid context for port '%p' requested", port); + return nullptr; + } + + return JackGlobalsManager::Instance()->fContexts[context_id]; + } + + inline static jack_port_id_t PortContext(const jack_port_t* port) + { + uintptr_t port_aux = (uintptr_t)port; + jack_port_id_t port_masked = (jack_port_id_t)port_aux; + jack_port_id_t port_context = (port_masked & PORT_SERVER_CONTEXT_MASK) >> PORT_SERVER_CONTEXT_SHIFT; + return port_context; + } + + inline jack_port_id_t PortContext() + { + std::vector &contexts = JackGlobalsManager::Instance()->fContexts; + + auto it = std::find_if(contexts.begin(), contexts.end(), [this] (JackGlobals* i) { + return (i && i->fServerName.compare(this->fServerName) == 0); + }); + + if (it == contexts.end()) { + return PORT_SERVER_CONTEXT_MAX; + } + + return it - contexts.begin(); + } + + inline jack_port_t* PortById(const jack_port_id_t &port_id) + { + jack_port_id_t context_id = PortContext(); + if (context_id > PORT_SERVER_CONTEXT_MAX) { + return NULL; + } + + /* cast to uintptr_t required to avoid [-Wint-to-pointer-cast] warning */ + const uintptr_t port = ((context_id << PORT_SERVER_CONTEXT_SHIFT) | port_id); + return (jack_port_t*)port; + + + } + }; -// Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. -extern SERVER_EXPORT JackGraphManager* GetGraphManager(); -extern SERVER_EXPORT JackEngineControl* GetEngineControl(); -extern SERVER_EXPORT JackSynchro* GetSynchroTable(); +class JackGlobalsInterface +{ + + private: + + JackGlobals *fGlobal; + + public: + + JackGlobalsInterface(JackGlobals *global = nullptr) + : fGlobal(global) + { + + } + + ~JackGlobalsInterface() + { + + } + + inline JackGlobals* GetGlobal() const + { + return fGlobal; + } + + inline void SetGlobal(JackGlobals *global) + { + fGlobal = global; + } + +}; + +template +inline T* JackGlobalsManager::CreateGlobal(const std::string &server_name) +{ + uint32_t context_num = fContexts.size(); + + std::vector::iterator it = std::find_if(fContexts.begin(), fContexts.end(), [&server_name] (JackGlobals* i) { + return (i && (i->fServerName.compare(server_name) == 0)); + }); + + T* global = nullptr; + + if (it == fContexts.end()) { + global = new T(server_name); + it = std::find(fContexts.begin(), fContexts.end(), nullptr); + if (it == fContexts.end()) { + fContexts.push_back(static_cast(global)); + } else { + *it = global; + } + } else { + global = dynamic_cast(*it); + } + + if (global == nullptr) { + return global; + } + + bool success = false; + { + std::lock_guard lock(global->fMutex); + success = global->AddContext(context_num, server_name); + } + + if (success == false) { + DestroyGlobal(server_name); + return nullptr; + } + + return global; +} + +inline void JackGlobalsManager::DestroyGlobal(const std::string &server_name) +{ + std::vector::iterator it = std::find_if(fContexts.begin(), fContexts.end(), [&server_name] (JackGlobals* i) { + return (i && (i->fServerName.compare(server_name) == 0)); + }); + + if (it == fContexts.end()) { + return; + } + + JackGlobals *global = *it; + + { + std::lock_guard lock(global->fMutex); + + if (global->DelContext(fContexts.size()) == false) { + return; + } + } + + delete global; + *it = nullptr; +} } // end of namespace diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 4d5061b5e..cd52f7298 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -45,11 +45,12 @@ void JackGraphManager::AssertPort(jack_port_id_t port_index) } } -JackGraphManager* JackGraphManager::Allocate(int port_max) +JackGraphManager* JackGraphManager::Allocate(int port_max, JackGlobals* global) { // Using "Placement" new void* shared_ptr = JackShmMem::operator new(sizeof(JackGraphManager) + port_max * sizeof(JackPort)); - return new(shared_ptr) JackGraphManager(port_max); + JackGraphManager *manager = new(shared_ptr) JackGraphManager(port_max, global); + return manager; } void JackGraphManager::Destroy(JackGraphManager* manager) @@ -59,7 +60,7 @@ void JackGraphManager::Destroy(JackGraphManager* manager) JackShmMem::operator delete(manager); } -JackGraphManager::JackGraphManager(int port_max) +JackGraphManager::JackGraphManager(int port_max, JackGlobals *global) { assert(port_max <= PORT_NUM_MAX); @@ -68,6 +69,8 @@ JackGraphManager::JackGraphManager(int port_max) } fPortMax = port_max; + + ReadCurrentState()->SetGlobal(global); } JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 15f0275f2..731000d91 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -32,6 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +class JackGlobals; + /*! \brief Graph manager: contains the connection manager and the port array. */ @@ -57,7 +59,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState public: - JackGraphManager(int port_max); + JackGraphManager(int port_max, JackGlobals *global); ~JackGraphManager() {} @@ -134,7 +136,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); - static JackGraphManager* Allocate(int port_max); + static JackGraphManager* Allocate(int port_max, JackGlobals *global); static void Destroy(JackGraphManager* manager); } POST_PACKED_STRUCTURE; diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp index 2d34e0a47..331e204dd 100644 --- a/common/JackInternalClient.cpp +++ b/common/JackInternalClient.cpp @@ -37,25 +37,9 @@ namespace Jack JackGraphManager* JackInternalClient::fGraphManager = NULL; JackEngineControl* JackInternalClient::fEngineControl = NULL; -// Used for external C API (JackAPI.cpp) -SERVER_EXPORT JackGraphManager* GetGraphManager() +JackInternalClient::JackInternalClient(JackServerGlobals *globals): JackClient(globals) { - return JackServerGlobals::fInstance->GetGraphManager(); -} - -SERVER_EXPORT JackEngineControl* GetEngineControl() -{ - return JackServerGlobals::fInstance->GetEngineControl(); -} - -SERVER_EXPORT JackSynchro* GetSynchroTable() -{ - return JackServerGlobals::fInstance->GetSynchroTable(); -} - -JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table) -{ - fChannel = new JackInternalClientChannel(server); + fChannel = new JackInternalClientChannel(globals->fInstance); } JackInternalClient::~JackInternalClient() @@ -101,8 +85,8 @@ int JackInternalClient::Open(const char* server_name, const char* name, jack_uui } SetupDriverSync(false); - JackGlobals::fClientTable[fClientControl.fRefNum] = this; - JackGlobals::fServerRunning = true; + GetGlobal()->fClientTable[fClientControl.fRefNum] = this; + GetGlobal()->fServerRunning = true; jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum); return 0; @@ -193,8 +177,8 @@ int JackLoadableInternalClient2::Init(const char* so_name) return 0; } -JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data) - : JackLoadableInternalClient(server, table) +JackLoadableInternalClient1::JackLoadableInternalClient1(JackServerGlobals *global, const char* object_data) + : JackLoadableInternalClient(global) { if (object_data != NULL) strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT); @@ -202,8 +186,8 @@ JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, Jac memset(fObjectData, 0, sizeof(fObjectData)); } -JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters) - : JackLoadableInternalClient(server, table) +JackLoadableInternalClient2::JackLoadableInternalClient2(JackServerGlobals *global, const JSList* parameters) + : JackLoadableInternalClient(global) { fParameters = parameters; } diff --git a/common/JackInternalClient.h b/common/JackInternalClient.h index 12b204166..7631ebea4 100644 --- a/common/JackInternalClient.h +++ b/common/JackInternalClient.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackClient.h" #include "JackClientControl.h" +#include "JackServerGlobals.h" #include "driver_interface.h" namespace Jack @@ -43,7 +44,7 @@ class JackInternalClient : public JackClient public: - JackInternalClient(JackServer* server, JackSynchro* table); + JackInternalClient(JackServerGlobals *globals); virtual ~JackInternalClient(); int Open(const char* server_name, const char* name, jack_uuid_t uuid, jack_options_t options, jack_status_t* status); @@ -76,8 +77,8 @@ class JackLoadableInternalClient : public JackInternalClient public: - JackLoadableInternalClient(JackServer* server, JackSynchro* table) - :JackInternalClient(server, table), fHandle(NULL), fFinish(NULL), fDescriptor(NULL) + JackLoadableInternalClient(JackServerGlobals* global) + :JackInternalClient(global), fHandle(NULL), fFinish(NULL), fDescriptor(NULL) {} virtual ~JackLoadableInternalClient(); @@ -95,7 +96,7 @@ class JackLoadableInternalClient1 : public JackLoadableInternalClient public: - JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data); + JackLoadableInternalClient1(JackServerGlobals *global, const char* object_data); virtual ~JackLoadableInternalClient1() {} @@ -114,7 +115,7 @@ class JackLoadableInternalClient2 : public JackLoadableInternalClient public: - JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters); + JackLoadableInternalClient2(JackServerGlobals *global, const JSList* parameters); virtual ~JackLoadableInternalClient2() {} diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index e439f4735..ba8af64fe 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -65,9 +65,6 @@ static jack_client_t * jack_client_open_aux (const char *client_name, jack_options_t options, jack_status_t *status, va_list ap); -JackLibGlobals* JackLibGlobals::fGlobals = NULL; -int JackLibGlobals::fClientCount = 0; - jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status) { jack_varargs_t va; /* variable arguments */ @@ -95,24 +92,28 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio /* parse variable arguments */ jack_varargs_init(&va); - JackLibGlobals::Init(); // jack library initialisation + JackLibGlobals *global = JackGlobalsManager::Instance()->CreateGlobal(va.server_name); + if (global == nullptr) { + jack_error("jack failed to create global context"); + return 0; + } if (try_start_server(&va, options, status)) { jack_error("jack server is not running or cannot be started"); - JackLibGlobals::Destroy(); // jack library destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); // jack library destruction return 0; } if (JACK_DEBUG) { - client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode + client = new JackDebugClient(new JackLibClient(global)); // Debug mode } else { - client = new JackLibClient(GetSynchroTable()); + client = new JackLibClient(global); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; - JackLibGlobals::Destroy(); // jack library destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); // jack library destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; @@ -148,24 +149,28 @@ static jack_client_t* jack_client_open_aux(const char* client_name, jack_options /* parse variable arguments */ jack_varargs_parse(options, ap, &va); - JackLibGlobals::Init(); // jack library initialisation + JackLibGlobals *global = JackGlobalsManager::Instance()->CreateGlobal(va.server_name); + if (global == nullptr) { + jack_error("jack failed to create global context"); + return 0; + } if (try_start_server(&va, options, status)) { jack_error("jack server is not running or cannot be started"); - JackLibGlobals::Destroy(); // jack library destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); // jack library destruction return 0; } if (JACK_DEBUG) { - client = new JackDebugClient(new JackLibClient(GetSynchroTable())); // Debug mode + client = new JackDebugClient(new JackLibClient(global)); // Debug mode } else { - client = new JackLibClient(GetSynchroTable()); + client = new JackLibClient(global); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; - JackLibGlobals::Destroy(); // jack library destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); // jack library destruction int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; @@ -209,8 +214,8 @@ LIB_EXPORT int jack_client_close(jack_client_t* ext_client) jack_error("jack_client_close called with a NULL client"); } else { res = client->Close(); + JackGlobalsManager::Instance()->DestroyGlobal(client->GetGlobal()->fServerName); // jack library destruction delete client; - JackLibGlobals::Destroy(); // jack library destruction jack_log("jack_client_close res = %d", res); } JackGlobals::fOpenMutex->Unlock(); @@ -229,93 +234,117 @@ LIB_EXPORT int jack_set_property(jack_client_t* ext_client, jack_uuid_t subject, { JackGlobals::CheckContext("jack_set_property"); - JackClient* client = (JackClient*)ext_client; - jack_log("jack_set_property ext_client %x client %x ", ext_client, client); - if (client == NULL) { - jack_error("jack_set_property called with a NULL client"); - return -1; - } else { - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->SetProperty(client, subject, key, value, type) : -1); - } + jack_error("jack_set_property is not implemented"); + return -1; + +// JackClient* client = (JackClient*)ext_client; +// jack_log("jack_set_property ext_client %x client %x ", ext_client, client); +// if (client == NULL) { +// jack_error("jack_set_property called with a NULL client"); +// return -1; +// } else { +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->SetProperty(client, subject, key, value, type) : -1); +// } } LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type) { JackGlobals::CheckContext("jack_get_property"); - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->GetProperty(subject, key, value, type) : -1); + jack_error("jack_get_property is not implemented"); + return -1; + +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->GetProperty(subject, key, value, type) : -1); } LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_actual_description_too) { JackGlobals::CheckContext("jack_free_description"); - JackMetadata* metadata = GetMetadata(); - if (metadata) - metadata->FreeDescription(desc, free_actual_description_too); + jack_error("jack_free_description is not implemented"); + return; + +// JackMetadata* metadata = GetMetadata(); +// if (metadata) +// metadata->FreeDescription(desc, free_actual_description_too); } LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc) { JackGlobals::CheckContext("jack_get_properties"); - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->GetProperties(subject, desc) : -1); + jack_error("jack_get_properties is not implemented"); + return -1; + +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->GetProperties(subject, desc) : -1); } LIB_EXPORT int jack_get_all_properties(jack_description_t** descriptions) { JackGlobals::CheckContext("jack_get_all_properties"); - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->GetAllProperties(descriptions) : -1); + jack_error("jack_get_all_properties is not implemented"); + return -1; + +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->GetAllProperties(descriptions) : -1); } LIB_EXPORT int jack_remove_property(jack_client_t* ext_client, jack_uuid_t subject, const char* key) { JackGlobals::CheckContext("jack_remove_property"); - JackClient* client = (JackClient*)ext_client; - jack_log("jack_remove_property ext_client %x client %x ", ext_client, client); - if (client == NULL) { - jack_error("jack_remove_property called with a NULL client"); - return -1; - } else { - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->RemoveProperty(client, subject, key) : -1); - } + jack_error("jack_remove_property is not implemented"); + return -1; + +// JackClient* client = (JackClient*)ext_client; +// jack_log("jack_remove_property ext_client %x client %x ", ext_client, client); +// if (client == NULL) { +// jack_error("jack_remove_property called with a NULL client"); +// return -1; +// } else { +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->RemoveProperty(client, subject, key) : -1); +// } } LIB_EXPORT int jack_remove_properties(jack_client_t* ext_client, jack_uuid_t subject) { JackGlobals::CheckContext("jack_remove_properties"); - JackClient* client = (JackClient*)ext_client; - jack_log("jack_remove_properties ext_client %x client %x ", ext_client, client); - if (client == NULL) { - jack_error("jack_remove_properties called with a NULL client"); - return -1; - } else { - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->RemoveProperties(client, subject) : -1); - } + jack_error("jack_remove_properties is not implemented"); + return -1; + +// JackClient* client = (JackClient*)ext_client; +// jack_log("jack_remove_properties ext_client %x client %x ", ext_client, client); +// if (client == NULL) { +// jack_error("jack_remove_properties called with a NULL client"); +// return -1; +// } else { +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->RemoveProperties(client, subject) : -1); +// } } LIB_EXPORT int jack_remove_all_properties(jack_client_t* ext_client) { JackGlobals::CheckContext("jack_remove_all_properties"); - JackClient* client = (JackClient*)ext_client; - jack_log("jack_remove_all_properties ext_client %x client %x ", ext_client, client); - if (client == NULL) { - jack_error("jack_remove_all_properties called with a NULL client"); - return -1; - } else { - JackMetadata* metadata = GetMetadata(); - return (metadata ? metadata->RemoveAllProperties(client) : -1); - } + jack_error("jack_remove_all_properties is not implemented"); + return -1; + +// JackClient* client = (JackClient*)ext_client; +// jack_log("jack_remove_all_properties ext_client %x client %x ", ext_client, client); +// if (client == NULL) { +// jack_error("jack_remove_all_properties called with a NULL client"); +// return -1; +// } else { +// JackMetadata* metadata = GetMetadata(); +// return (metadata ? metadata->RemoveAllProperties(client) : -1); +// } } LIB_EXPORT int jack_set_property_change_callback(jack_client_t* ext_client, JackPropertyChangeCallback callback, void* arg) diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index 65e70a13e..1e1706eed 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -27,40 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -// Used for external C API (JackAPI.cpp) -JackGraphManager* GetGraphManager() -{ - if (JackLibGlobals::fGlobals) { - return JackLibGlobals::fGlobals->fGraphManager; - } else { - return NULL; - } -} - -JackEngineControl* GetEngineControl() -{ - if (JackLibGlobals::fGlobals) { - return JackLibGlobals::fGlobals->fEngineControl; - } else { - return NULL; - } -} - -JackSynchro* GetSynchroTable() -{ - return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0); -} - -// Used for client-side Metadata API (JackLibAPI.cpp) -JackMetadata* GetMetadata() -{ - if (JackLibGlobals::fGlobals) { - return JackLibGlobals::fGlobals->fMetadata; - } else { - return NULL; - } -} - //------------------- // Client management //------------------- @@ -75,14 +41,14 @@ ShutDown is called: void JackLibClient::ShutDown(jack_status_t code, const char* message) { jack_log("JackLibClient::ShutDown"); - JackGlobals::fServerRunning = false; + GetGlobal()->fServerRunning = false; JackClient::ShutDown(code, message); } -JackLibClient::JackLibClient(JackSynchro* table): JackClient(table) +JackLibClient::JackLibClient(JackGlobals* global): JackClient(global) { - jack_log("JackLibClient::JackLibClient table = %x", table); - fChannel = new JackClientChannel(); + jack_log("JackLibClient::JackLibClient table = %x", global->GetSynchroTable()); + fChannel = new JackClientChannel(global); } JackLibClient::~JackLibClient() @@ -129,8 +95,10 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_uuid_t u try { // Map shared memory segments - JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName); - JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); + JackLibGlobals *lib_globals = dynamic_cast(GetGlobal()); + assert(lib_globals); + lib_globals->fEngineControl.SetShmIndex(shared_engine, fServerName); + lib_globals->fGraphManager.SetShmIndex(shared_graph, fServerName); fClientControl.SetShmIndex(shared_client, fServerName); JackGlobals::fVerbose = GetEngineControl()->fVerbose; } catch (...) { @@ -141,16 +109,16 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_uuid_t u SetupDriverSync(false); // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process - assert(JackGlobals::fSynchroMutex); - JackGlobals::fSynchroMutex->Lock(); + assert(GetGlobal()->fSynchroMutex); + GetGlobal()->fSynchroMutex->Lock(); res = fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName); - JackGlobals::fSynchroMutex->Unlock(); + GetGlobal()->fSynchroMutex->Unlock(); if (!res) { jack_error("Cannot ConnectSemaphore %s client", name_res); goto error; } - JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; + GetGlobal()->fClientTable[GetClientControl()->fRefNum] = this; SetClockSource(GetEngineControl()->fClockSource); jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum); return 0; @@ -167,8 +135,8 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_uuid_t u int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; - assert(JackGlobals::fSynchroMutex); - JackGlobals::fSynchroMutex->Lock(); + assert(GetGlobal()->fSynchroMutex); + GetGlobal()->fSynchroMutex->Lock(); // Done all time switch (notify) { @@ -187,20 +155,20 @@ int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int break; } - JackGlobals::fSynchroMutex->Unlock(); + GetGlobal()->fSynchroMutex->Unlock(); return res; } JackGraphManager* JackLibClient::GetGraphManager() const { - assert(JackLibGlobals::fGlobals->fGraphManager); - return JackLibGlobals::fGlobals->fGraphManager; + assert(GetGlobal()->GetGraphManager()); + return GetGlobal()->GetGraphManager(); } JackEngineControl* JackLibClient::GetEngineControl() const { - assert(JackLibGlobals::fGlobals->fEngineControl); - return JackLibGlobals::fGlobals->fEngineControl; + assert(GetGlobal()->GetEngineControl()); + return GetGlobal()->GetEngineControl(); } JackClientControl* JackLibClient::GetClientControl() const diff --git a/common/JackLibClient.h b/common/JackLibClient.h index 9fe5d7837..7924dd468 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -41,7 +41,7 @@ class JackLibClient : public JackClient public: - JackLibClient(JackSynchro* table); + JackLibClient(JackGlobals* global); virtual ~JackLibClient(); int Open(const char* server_name, const char* name, jack_uuid_t uuid, jack_options_t options, jack_status_t* status); @@ -54,9 +54,6 @@ class JackLibClient : public JackClient JackClientControl* GetClientControl() const; }; -// Used for client-side Metadata API (JackLibAPI.cpp) -JackMetadata* GetMetadata(); - } // end of namespace #endif diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index bca775a37..85e78c25e 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -50,96 +50,126 @@ class JackClient; \brief Global library static structure: singleton kind of pattern. */ -struct JackLibGlobals +class JackLibGlobals : public JackGlobals { - JackShmReadWritePtr fGraphManager; /*! Shared memory Port manager */ - JackShmReadWritePtr fEngineControl; /*! Shared engine control */ // transport engine has to be writable - JackSynchro fSynchroTable[CLIENT_NUM]; /*! Shared synchro table */ - JackMetadata *fMetadata; /*! Shared metadata base */ - sigset_t fProcessSignals; - - static int fClientCount; - static JackLibGlobals* fGlobals; - - JackLibGlobals() - { - jack_log("JackLibGlobals"); - if (!JackMessageBuffer::Create()) { - jack_error("Cannot create message buffer"); - } - fGraphManager = -1; - fEngineControl = -1; - - fMetadata = new JackMetadata(false); - - // Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. - #ifdef WIN32 - // TODO - #else - sigset_t signals; - sigemptyset(&signals); - sigaddset(&signals, SIGPIPE); - sigprocmask(SIG_BLOCK, &signals, &fProcessSignals); - #endif - } - - ~JackLibGlobals() - { - jack_log("~JackLibGlobals"); - for (int i = 0; i < CLIENT_NUM; i++) { - fSynchroTable[i].Disconnect(); - } - JackMessageBuffer::Destroy(); - delete fMetadata; - fMetadata = NULL; + /* This object is managed by JackGlobalsManager */ + friend class JackGlobalsManager; - // Restore old signal mask - #ifdef WIN32 - // TODO - #else - sigprocmask(SIG_BLOCK, &fProcessSignals, 0); - #endif - } + private: - static void Init() - { - if (!JackGlobals::fServerRunning && fClientCount > 0) { + /* is called when first context for specific server is created */ + JackLibGlobals(const std::string &server_name) + : JackGlobals(server_name) + , fMetadata(server_name.c_str()) + { + fGraphManager = -1; + fEngineControl = -1; + fClientCount = 0; + + InitTime(); + } + + /* is called when last context for specific server is removed */ + ~JackLibGlobals() override + { + EndTime(); - // Cleanup remaining clients - jack_error("Jack server was closed but clients are still allocated, cleanup..."); for (int i = 0; i < CLIENT_NUM; i++) { - JackClient* client = JackGlobals::fClientTable[i]; - if (client) { - jack_error("Cleanup client ref = %d", i); - client->Close(); - delete client; + fSynchroTable[i].Disconnect(); + } + } + + public: + + JackShmReadWritePtr fGraphManager; /*! Shared memory Port manager */ + JackShmReadWritePtr fEngineControl; /*! Shared engine control */ // transport engine has to be writable + JackSynchro fSynchroTable[CLIENT_NUM]; /*! Shared synchro table */ + JackMetadata fMetadata; /*! Shared metadata base */ + sigset_t fProcessSignals; + + int fClientCount; + + /* is called each time a context for specific server is added */ + bool AddContext(const uint32_t &context_num, const std::string &server_name) override + { + if (!fServerRunning && fClientCount > 0) { + // Cleanup remaining clients + jack_error("Jack server was closed but clients are still allocated, cleanup..."); + for (int i = 0; i < CLIENT_NUM; i++) { + JackClient* client = fClientTable[i]; + if (client) { + jack_error("Cleanup client ref = %d", i); + client->Close(); + delete client; + } } + + // run destructors for all included objects, keeping the behaviour to previous revisions of JackGlobals source + this->~JackLibGlobals(); + // construct in place + new(this) JackLibGlobals(server_name); } - // Cleanup global context - fClientCount = 0; - delete fGlobals; - fGlobals = NULL; + fClientCount++; + + if (context_num == 0 && !JackMessageBuffer::Create()) { + jack_error("Cannot create message buffer"); + } + + // Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. +#ifdef WIN32 + // TODO +#else + sigset_t signals; + sigemptyset(&signals); + sigaddset(&signals, SIGPIPE); + sigprocmask(SIG_BLOCK, &signals, &fProcessSignals); +#endif + return true; } - if (fClientCount++ == 0 && !fGlobals) { - jack_log("JackLibGlobals Init %x", fGlobals); - InitTime(); - fGlobals = new JackLibGlobals(); + /* is called each time a context for specific server is removed */ + bool DelContext(const uint32_t &context_num) override + { +#ifdef WIN32 + // TODO +#else + sigprocmask(SIG_BLOCK, &fProcessSignals, nullptr); +#endif + if (context_num == 0 && !JackMessageBuffer::Destroy()) { + jack_error("Cannot destroy message buffer"); + } + + return --fClientCount == 0; } - } - static void Destroy() - { - if (--fClientCount == 0 && fGlobals) { - jack_log("JackLibGlobals Destroy %x", fGlobals); - EndTime(); - delete fGlobals; - fGlobals = NULL; + JackGraphManager *GetGraphManager() override + { + return fGraphManager; + } + + JackEngineControl *GetEngineControl() override + { + return fEngineControl; + } + + JackSynchro *GetSynchroTable() override + { + return fSynchroTable; + } + + /* must not be used in JackLibGlobals */ + JackServer *GetServer() override + { + assert(false); + return nullptr; } - } + JackMetadata* GetMetadata() + { + return &fMetadata; + } }; } // end of namespace diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp index 8731f1e14..56a78a250 100644 --- a/common/JackMidiPort.cpp +++ b/common/JackMidiPort.cpp @@ -146,8 +146,9 @@ static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count mix->lost_events += event_count - events_done; } -static size_t MidiBufferSize() +static size_t MidiBufferSize(JackGlobals *global) { + (void)(global); return BUFFER_SIZE_MAX * sizeof(jack_default_audio_sample_t); } diff --git a/common/JackMidiUtil.cpp b/common/JackMidiUtil.cpp index a0dc0bae6..135258a8a 100644 --- a/common/JackMidiUtil.cpp +++ b/common/JackMidiUtil.cpp @@ -55,26 +55,32 @@ Jack::ApplyRunningStatus(jack_midi_event_t *event, jack_nframes_t Jack::GetCurrentFrame() { - jack_time_t time = GetMicroSeconds(); - JackEngineControl *control = GetEngineControl(); - JackTimer timer; - control->ReadFrameTime(&timer); - return timer.Time2Frames(time, control->fBufferSize); + jack_error("Jack::GetCurrentFrame is not implemented"); + abort(); +// jack_time_t time = GetMicroSeconds(); +// JackEngineControl *control = GetEngineControl(); +// JackTimer timer; +// control->ReadFrameTime(&timer); +// return timer.Time2Frames(time, control->fBufferSize); } jack_nframes_t Jack::GetFramesFromTime(jack_time_t time) { - JackEngineControl* control = GetEngineControl(); - JackTimer timer; - control->ReadFrameTime(&timer); - return timer.Time2Frames(time, control->fBufferSize); + jack_error("Jack::GetFramesFromTime is not implemented"); + abort(); +// JackEngineControl* control = GetEngineControl(); +// JackTimer timer; +// control->ReadFrameTime(&timer); +// return timer.Time2Frames(time, control->fBufferSize); } jack_nframes_t Jack::GetLastFrame() { - return GetEngineControl()->fFrameTimer.ReadCurrentState()->CurFrame(); + jack_error("Jack::GetLastFrame is not implemented"); + abort(); +// return GetEngineControl()->fFrameTimer.ReadCurrentState()->CurFrame(); } int @@ -114,8 +120,10 @@ Jack::GetMessageLength(jack_midi_data_t status_byte) jack_time_t Jack::GetTimeFromFrames(jack_nframes_t frames) { - JackEngineControl* control = GetEngineControl(); - JackTimer timer; - control->ReadFrameTime(&timer); - return timer.Frames2Time(frames, control->fBufferSize); + jack_error("Jack::GetTimeFromFrames is not implemented"); + abort(); +// JackEngineControl* control = GetEngineControl(); +// JackTimer timer; +// control->ReadFrameTime(&timer); +// return timer.Frames2Time(frames, control->fBufferSize); } diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index dc254a15f..e3aa53008 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackEngineControl.h" #include "JackArgParser.h" +#include "JackClient.h" #include namespace Jack @@ -245,9 +246,10 @@ namespace Jack SetAdaptedSampleRate(fParams.fSampleRate); // Will do "something" on OSX only... - fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); + JackEngineControl *control = ((JackClient*)fClient)->GetGlobal()->GetEngineControl(); + fThread.SetParams(control->fPeriod, control->fComputation, control->fConstraint); - if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { + if (fThread.AcquireSelfRealTime(control->fClientPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); diff --git a/common/JackPortType.cpp b/common/JackPortType.cpp index 940ef492e..86bc876cc 100644 --- a/common/JackPortType.cpp +++ b/common/JackPortType.cpp @@ -30,7 +30,7 @@ static const JackPortType* gPortTypes[] = &gMidiPortType, }; -jack_port_type_id_t PORT_TYPES_MAX = sizeof(gPortTypes) / sizeof(gPortTypes[0]); +const jack_port_type_id_t PORT_TYPES_MAX = sizeof(gPortTypes) / sizeof(gPortTypes[0]); jack_port_type_id_t GetPortTypeId(const char* port_type) { diff --git a/common/JackPortType.h b/common/JackPortType.h index efb8ca2f0..65b7e7d0c 100644 --- a/common/JackPortType.h +++ b/common/JackPortType.h @@ -27,12 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -extern jack_port_type_id_t PORT_TYPES_MAX; +class JackGlobals; + +extern const jack_port_type_id_t PORT_TYPES_MAX; struct JackPortType { const char* fName; - size_t (*size)(); + size_t (*size)(JackGlobals *global); void (*init)(void* buffer, size_t buffer_size, jack_nframes_t nframes); void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); }; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 5cee13fbd..8e0bd40f0 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -43,7 +43,8 @@ namespace Jack //---------------- // Server control //---------------- -JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name) +JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name, JackServerGlobals *global) + : fGlobal(global) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); @@ -53,8 +54,9 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio jack_info("self-connect-mode is \"%s\"", jack_get_self_connect_mode_description(self_connect_mode)); - fGraphManager = JackGraphManager::Allocate(port_max); - fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); + fConnectionState.SetGlobal(global); + fGraphManager = JackGraphManager::Allocate(port_max, global); + fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name, global); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode); // A distinction is made between the threaded freewheel driver and the @@ -196,14 +198,14 @@ bool JackServer::IsRunning() int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, jack_uuid_t uuid, int* status) { - JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data); + JackLoadableInternalClient* client = new JackLoadableInternalClient1(fGlobal, objet_data); assert(client); return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, jack_uuid_t uuid, int* status) { - JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters); + JackLoadableInternalClient* client = new JackLoadableInternalClient2(fGlobal, parameters); assert(client); return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status); } diff --git a/common/JackServer.h b/common/JackServer.h index 71192e9e1..c42a62aaf 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -26,7 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" #include "JackDriverInfo.h" #include "JackConnectionManager.h" -#include "JackGlobals.h" #include "JackPlatformPlug.h" #include "jslist.h" @@ -38,6 +37,7 @@ class JackDriverClientInterface; struct JackEngineControl; class JackLockedEngine; class JackLoadableInternalClient; +class JackServerGlobals; /*! \brief The Jack server. @@ -60,11 +60,13 @@ class SERVER_EXPORT JackServer JackSynchro fSynchroTable[CLIENT_NUM]; bool fFreewheel; + JackServerGlobals *fGlobal; + int InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, jack_uuid_t uuid, int* status); public: - JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name); + JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, char self_connect_mode, const char* server_name, JackServerGlobals* global); ~JackServer(); // Server control diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index ff86dec5a..64bd90336 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -74,22 +74,32 @@ jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t optio /* parse variable arguments */ jack_varargs_init(&va); - if (!JackServerGlobals::Init()) { // jack server initialisation + // jack server init and start + JackServerGlobals *global = JackGlobalsManager::Instance()->CreateGlobal(va.server_name); + if (global == nullptr) { + int my_status1 = (JackFailure | JackServerError); + *status = (jack_status_t)my_status1; + return NULL; + } + + if (!global->Init()) { + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } if (JACK_DEBUG) { - client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode + client = new JackDebugClient(new JackInternalClient(global)); // Debug mode } else { - client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); + client = new JackInternalClient(global); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; - JackServerGlobals::Destroy(); // jack server destruction + // jack server stop and destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; @@ -125,22 +135,30 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti /* parse variable arguments */ jack_varargs_parse(options, ap, &va); - if (!JackServerGlobals::Init()) { // jack server initialisation + JackServerGlobals *global = JackGlobalsManager::Instance()->CreateGlobal(va.server_name); + if (global == nullptr) { + int my_status1 = (JackFailure | JackServerError); + *status = (jack_status_t)my_status1; + return NULL; + } + + if (!global->Init()) { + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; } if (JACK_DEBUG) { - client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode + client = new JackDebugClient(new JackInternalClient(global)); // Debug mode } else { - client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable()); + client = new JackInternalClient(global); } int res = client->Open(va.server_name, client_name, va.session_id, options, status); if (res < 0) { delete client; - JackServerGlobals::Destroy(); // jack server destruction + JackGlobalsManager::Instance()->DestroyGlobal(va.server_name); int my_status1 = (JackFailure | JackServerError); *status = (jack_status_t)my_status1; return NULL; @@ -184,8 +202,8 @@ SERVER_EXPORT int jack_client_close(jack_client_t* ext_client) jack_error("jack_client_close called with a NULL client"); } else { res = client->Close(); + JackGlobalsManager::Instance()->DestroyGlobal(client->GetGlobal()->fServerName); delete client; - JackServerGlobals::Destroy(); // jack server destruction jack_log("jack_client_close res = %d", res); } JackGlobals::fOpenMutex->Unlock(); diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 3f08711a6..a71a69ab1 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackServerGlobals.h" #include "JackLockedEngine.h" #include "JackTools.h" +#include "JackServer.h" #include "shm.h" #include #include @@ -52,7 +53,7 @@ int JackServerGlobals::Start(const char* server_name, char self_connect_mode) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); - new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, self_connect_mode, server_name); // Will setup fInstance and fUserCount globals + new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, self_connect_mode, server_name, this); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } @@ -64,7 +65,7 @@ void JackServerGlobals::Stop() fInstance->Close(); } -void JackServerGlobals::Delete() +void JackServerGlobals::Destroy() { jack_log("Jackdmp: delete server"); @@ -351,7 +352,7 @@ bool JackServerGlobals::Init() int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source, JACK_DEFAULT_SELF_CONNECT_MODE); if (res < 0) { jack_error("Cannot start server... exit"); - Delete(); + Destroy(); jack_cleanup_shm(); JackTools::CleanupFiles(server_name); jack_unregister_server(server_name); @@ -400,22 +401,42 @@ bool JackServerGlobals::Init() if (master_driver_params) { jack_free_driver_params(master_driver_params); } - Destroy(); + Deinit(); return false; } -void JackServerGlobals::Destroy() +void JackServerGlobals::Deinit() { if (--fUserCount == 0) { jack_log("JackServerGlobals Destroy"); Stop(); - Delete(); + Destroy(); jack_cleanup_shm(); JackTools::CleanupFiles(server_name); jack_unregister_server(server_name); } } +JackGraphManager *JackServerGlobals::GetGraphManager() +{ + return fInstance->GetGraphManager(); +} + +JackEngineControl *JackServerGlobals::GetEngineControl() +{ + return fInstance->GetEngineControl(); +} + +JackSynchro *JackServerGlobals::GetSynchroTable() +{ + return fInstance->GetSynchroTable(); +} + +JackServer *JackServerGlobals::GetServer() +{ + return fInstance; +} + } // end of namespace diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index 15fdfd973..5a64d238f 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriverLoader.h" #include "JackCompilerDeps.h" #include "JackServer.h" +#include "JackGlobals.h" #include namespace Jack @@ -35,36 +36,60 @@ class JackClient; \brief Global server static structure: singleton kind of pattern. */ -struct SERVER_EXPORT JackServerGlobals +class SERVER_EXPORT JackServerGlobals : public JackGlobals { - static JackServer* fInstance; - static unsigned int fUserCount; - static std::map fSlavesList; - static std::map fInternalsList; - - static bool (* on_device_acquire)(const char* device_name); - static void (* on_device_release)(const char* device_name); - static void (* on_device_reservation_loop)(void); - - JackServerGlobals(); - ~JackServerGlobals(); - - static bool Init(); - static void Destroy(); - static int Start(const char* server_name, - jack_driver_desc_t* driver_desc, - JSList* driver_params, - int sync, - int temporary, - int time_out_ms, - int rt, - int priority, - int port_max, - int verbose, - jack_timer_type_t clock, - char self_connect_mode); - static void Stop(); - static void Delete(); + + /* This object is managed by JackGlobalsManager */ + friend class JackGlobalsManager; + + private: + + JackServerGlobals(const std::string &server_name) : JackGlobals(server_name) {} + ~JackServerGlobals() override {} + + public: + + static JackServer* fInstance; + static unsigned int fUserCount; + static std::map fSlavesList; + static std::map fInternalsList; + + static bool (* on_device_acquire)(const char* device_name); + static void (* on_device_release)(const char* device_name); + static void (* on_device_reservation_loop)(void); + + bool Init(); + void Deinit(); + int Start(const char* server_name, + jack_driver_desc_t* driver_desc, + JSList* driver_params, + int sync, + int temporary, + int time_out_ms, + int rt, + int priority, + int port_max, + int verbose, + jack_timer_type_t clock, + char self_connect_mode); + void Stop(); + void Destroy(); + + bool AddContext(const uint32_t &context_num, const std::string &server_name) override + { + return true; + } + + bool DelContext(const uint32_t &context_num) override + { + return true; + } + + JackGraphManager* GetGraphManager() override; + JackEngineControl* GetEngineControl() override; + JackSynchro* GetSynchroTable() override; + JackServer* GetServer() override; + }; } // end of namespace diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index b56a7343a..7c1ccf63b 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -259,10 +259,10 @@ void JackThreadedDriver::SetRealTime() if (fDriver->IsRealTime()) { jack_log("JackThreadedDriver::Init real-time"); // Will do "something" on OSX only... - GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; - GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000; - fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { + fDriver->fEngineControl->fPeriod = fDriver->fEngineControl->fConstraint = fDriver->fEngineControl->fPeriodUsecs * 1000; + fDriver->fEngineControl->fComputation = JackTools::ComputationMicroSec(fDriver->fEngineControl->fBufferSize) * 1000; + fThread.SetParams(fDriver->fEngineControl->fPeriod, fDriver->fEngineControl->fComputation, fDriver->fEngineControl->fConstraint); + if (fThread.AcquireSelfRealTime(fDriver->fEngineControl->fServerPriority) < 0) { jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 5c0fa8d09..213d40e78 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -34,7 +34,9 @@ using namespace std; namespace Jack { -JackTransportEngine::JackTransportEngine(): JackAtomicArrayState() +JackTransportEngine::JackTransportEngine(JackGlobals *global) + : JackAtomicArrayState() + , JackGlobalsInterface(global) { fTransportState = JackTransportStopped; fTransportCmd = fPreviousCmd = TransportCommandStop; @@ -92,7 +94,7 @@ int JackTransportEngine::SetTimebaseMaster(int refnum, bool conditionnal) // RT bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) { - for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { + for (int i = GetGlobal()->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client && client->GetClientControl()->fTransportState != JackTransportRolling) { jack_log("CheckAllRolling ref = %ld is not rolling", i); @@ -106,7 +108,7 @@ bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) // RT void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table) { - for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { + for (int i = GetGlobal()->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); @@ -122,7 +124,7 @@ void JackTransportEngine::MakeAllStartingLocating(JackClientInterface** table) // RT void JackTransportEngine::MakeAllStopping(JackClientInterface** table) { - for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { + for (int i = GetGlobal()->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); @@ -137,7 +139,7 @@ void JackTransportEngine::MakeAllStopping(JackClientInterface** table) // RT void JackTransportEngine::MakeAllLocating(JackClientInterface** table) { - for (int i = GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { + for (int i = GetGlobal()->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) { JackClientInterface* client = table[i]; if (client) { JackClientControl* control = client->GetClientControl(); diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index e00a31384..f396106b6 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackAtomicArrayState.h" #include "JackCompilerDeps.h" +#include "JackGlobals.h" #include "types.h" namespace Jack @@ -90,7 +91,7 @@ We have: class JackClientInterface; PRE_PACKED_STRUCTURE -class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState +class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState, public JackGlobalsInterface { private: @@ -115,7 +116,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayStateindex == JACK_SHM_NULL_INDEX) return; /* segment not allocated */ - jack_remove_shm (&jack_shm_registry[si->index].id); + jack_remove_shm (jack_shm_registry[si->index].id); jack_release_shm_info (si->index); } @@ -490,8 +496,9 @@ int jack_register_server (const char *server_name, int new_registry) { int i, res = 0; + char server_prefix[JACK_SERVER_NAME_SIZE+1]; - jack_set_server_prefix (server_name); + jack_get_server_prefix (server_name, server_prefix, sizeof(server_prefix)); if (jack_server_initialize_shm (new_registry)) return ENOMEM; @@ -507,8 +514,8 @@ jack_register_server (const char *server_name, int new_registry) for (i = 0; i < MAX_SERVERS; i++) { if (strncmp (jack_shm_header->server[i].name, - jack_shm_server_prefix, - JACK_SERVER_NAME_SIZE) != 0) + server_prefix, + sizeof(server_prefix)) != 0) continue; /* no match */ if (jack_shm_header->server[i].pid == GetPID()){ @@ -548,8 +555,8 @@ jack_register_server (const char *server_name, int new_registry) /* claim it */ jack_shm_header->server[i].pid = GetPID(); strncpy (jack_shm_header->server[i].name, - jack_shm_server_prefix, - JACK_SERVER_NAME_SIZE); + server_prefix, + sizeof(server_prefix)); unlock: jack_shm_unlock_registry (); @@ -630,7 +637,7 @@ jack_cleanup_shm () int index = copy.index; if ((index >= 0) && (index < MAX_SHM_ID)) { - jack_remove_shm (&jack_shm_registry[index].id); + jack_remove_shm (jack_shm_registry[index].id); jack_release_shm_entry (index); } r->size = 0; @@ -715,8 +722,6 @@ jack_access_registry (jack_shm_info_t *ri) /* registry must be locked */ int shm_fd; - strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id)); - /* try to open an existing segment */ if ((shm_fd = shm_open (registry_id, O_RDWR, 0666)) < 0) { int rc = errno; @@ -759,8 +764,6 @@ jack_create_registry (jack_shm_info_t *ri) /* registry must be locked */ int shm_fd; - strncpy (registry_id, "/jack-shm-registry", sizeof (registry_id)); - if ((shm_fd = shm_open (registry_id, O_RDWR|O_CREAT, 0666)) < 0) { int rc = errno; jack_error ("Cannot create shm registry segment (%s)", @@ -779,7 +782,7 @@ jack_create_registry (jack_shm_info_t *ri) if (ftruncate (shm_fd, JACK_SHM_REGISTRY_SIZE) < 0) { int rc = errno; jack_error ("Cannot set registry size (%s)", strerror (errno)); - jack_remove_shm (®istry_id); + jack_remove_shm (registry_id); close (shm_fd); return rc; } @@ -789,7 +792,7 @@ jack_create_registry (jack_shm_info_t *ri) MAP_SHARED, shm_fd, 0)) == MAP_FAILED) { jack_error ("Cannot mmap shm registry segment (%s)", strerror (errno)); - jack_remove_shm (®istry_id); + jack_remove_shm (registry_id); close (shm_fd); return EINVAL; } @@ -806,10 +809,10 @@ jack_create_registry (jack_shm_info_t *ri) } static void -jack_remove_shm (jack_shm_id_t *id) +jack_remove_shm (const jack_shm_id_t id) { /* registry may or may not be locked */ - shm_unlink ((char *) id); + shm_unlink (id); } void @@ -955,7 +958,6 @@ jack_access_registry (jack_shm_info_t *ri) { /* registry must be locked */ HANDLE shm_fd; - strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); /* try to open an existing segment */ @@ -969,7 +971,7 @@ jack_access_registry (jack_shm_info_t *ri) if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); - jack_remove_shm (®istry_id); + jack_remove_shm (registry_id); CloseHandle (shm_fd); return EINVAL; } @@ -989,8 +991,6 @@ jack_create_registry (jack_shm_info_t *ri) /* registry must be locked */ HANDLE shm_fd; - strncpy (registry_id, "jack-shm-registry", sizeof (registry_id)); - if ((shm_fd = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, JACK_SHM_REGISTRY_SIZE, @@ -1002,7 +1002,7 @@ jack_create_registry (jack_shm_info_t *ri) if ((ri->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, JACK_SHM_REGISTRY_SIZE)) == NULL) { jack_error ("Cannot mmap shm registry segment (%ld)", GetLastError()); - jack_remove_shm (®istry_id); + jack_remove_shm (registry_id); CloseHandle (shm_fd); return EINVAL; } @@ -1020,7 +1020,7 @@ jack_create_registry (jack_shm_info_t *ri) } static void -jack_remove_shm (jack_shm_id_t *id) +jack_remove_shm (jack_shm_id_t id) { /* nothing to do */ } @@ -1102,7 +1102,7 @@ jack_attach_shm (jack_shm_info_t* si) if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_ALL_ACCESS, 0, 0, registry->size)) == NULL) { jack_error ("Cannot mmap shm segment (%ld)", GetLastError()); - jack_remove_shm (®istry_id); + jack_remove_shm (registry_id); CloseHandle (shm_fd); return -1; } @@ -1125,7 +1125,7 @@ jack_attach_shm_read (jack_shm_info_t* si) if ((si->ptr.attached_at = MapViewOfFile (shm_fd, FILE_MAP_READ, 0, 0, registry->size)) == NULL) { jack_error("Cannot mmap shm segment (%ld)", GetLastError()); - jack_remove_shm(®istry_id); + jack_remove_shm(registry_id); CloseHandle(shm_fd); return -1; } @@ -1224,10 +1224,10 @@ jack_create_registry (jack_shm_info_t *ri) } static void -jack_remove_shm (jack_shm_id_t *id) +jack_remove_shm (jack_shm_id_t id) { /* registry may or may not be locked */ - shmctl (*id, IPC_RMID, NULL); + shmctl (id, IPC_RMID, NULL); } void diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index 25686c08f..62a4cc560 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -24,14 +24,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAlsaAdapter.h" #include "JackGlobals.h" #include "JackEngineControl.h" +#include "JackClient.h" namespace Jack { - JackAlsaAdapter::JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) : + JackAlsaAdapter::JackAlsaAdapter ( JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) : JackAudioAdapterInterface ( buffer_size, sample_rate ), fThread ( this ), - fAudioInterface ( buffer_size, sample_rate ) + fAudioInterface ( buffer_size, sample_rate ), + fClient( jack_client ) { const JSList* node; const jack_driver_param_t* param; @@ -110,7 +112,7 @@ namespace Jack fAudioInterface.longinfo(); //turn the thread realtime - fThread.AcquireRealTime(GetEngineControl()->fClientPriority); + fThread.AcquireRealTime(fClient.GetGlobal()->GetEngineControl()->fClientPriority); return 0; } diff --git a/linux/alsa/JackAlsaAdapter.h b/linux/alsa/JackAlsaAdapter.h index 38a459439..53a1644dc 100644 --- a/linux/alsa/JackAlsaAdapter.h +++ b/linux/alsa/JackAlsaAdapter.h @@ -602,9 +602,10 @@ namespace Jack private: JackThread fThread; AudioInterface fAudioInterface; + JackClient &fClient; public: - JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); + JackAlsaAdapter ( JackClient &client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); ~JackAlsaAdapter() {} diff --git a/macosx/coreaudio/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index 42c995e4c..57e0a3805 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -150,7 +150,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface public: - JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); + JackCoreAudioAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackCoreAudioAdapter() {} diff --git a/macosx/coreaudio/JackCoreAudioAdapter.mm b/macosx/coreaudio/JackCoreAudioAdapter.mm index 2d86e1526..2d87d5431 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.mm +++ b/macosx/coreaudio/JackCoreAudioAdapter.mm @@ -321,7 +321,7 @@ static void printError(OSStatus err) } } -JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) +JackCoreAudioAdapter::JackCoreAudioAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { const JSList* node; diff --git a/posix/JackPosixServerLaunch.cpp b/posix/JackPosixServerLaunch.cpp index 6911143c0..3dbf7a962 100644 --- a/posix/JackPosixServerLaunch.cpp +++ b/posix/JackPosixServerLaunch.cpp @@ -242,7 +242,7 @@ static int start_server(const char* server_name, jack_options_t options) static int server_connect(char* server_name) { - JackClientChannel channel; + JackClientChannel channel(nullptr); int res = channel.ServerCheck(server_name); channel.Close(); JackSleep(2000); // Added by JE - 02-01-2009 (gives diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 5d5adac8f..cc851d1c4 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -26,8 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -JackSocketClientChannel::JackSocketClientChannel() - :JackGenericClientChannel(), fThread(this) +JackSocketClientChannel::JackSocketClientChannel(JackGlobals *global) + :JackGenericClientChannel(global), fThread(this) { fRequest = new JackClientSocket(); fNotificationSocket = NULL; @@ -53,7 +53,7 @@ int JackSocketClientChannel::Open(const char* server_name, const char* name, jac } // OK so server is there... - JackGlobals::fServerRunning = true; + client->GetGlobal()->fServerRunning = true; // Check name in server ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index 1dc0ed7b2..120d3036c 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -46,7 +46,7 @@ class JackSocketClientChannel : public JackGenericClientChannel, public JackRunn public: - JackSocketClientChannel(); + JackSocketClientChannel(JackGlobals *global); virtual ~JackSocketClientChannel(); int Open(const char* server_name, const char* name, jack_uuid_t uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index 552f00107..71eb63541 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackOSSAdapter.h" #include "JackServerGlobals.h" #include "JackEngineControl.h" +#include "JackClient.h" #include "memops.h" #include @@ -103,13 +104,14 @@ void JackOSSAdapter::SetSampleFormat() } } -JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) +JackOSSAdapter::JackOSSAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate) ,fThread(this), fInFD(-1), fOutFD(-1), fBits(OSS_DRIVER_DEF_BITS), fSampleFormat(0), fNperiods(OSS_DRIVER_DEF_NPERIODS), fRWMode(0), fIgnoreHW(true), fExcl(false), fInputBufferSize(0), fOutputBufferSize(0), - fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true) + fInputBuffer(NULL), fOutputBuffer(NULL), fFirstCycle(true), + fClient(jack_client) { const JSList* node; const jack_driver_param_t* param; @@ -496,7 +498,7 @@ int JackOSSAdapter::Open() } //turn the thread realtime - fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority); + fThread.AcquireRealTime(fClient.GetGlobal()->GetEngineControl()->fClientPriority); return 0; error: diff --git a/solaris/oss/JackOSSAdapter.h b/solaris/oss/JackOSSAdapter.h index 4c5eba02b..5aa755f0b 100644 --- a/solaris/oss/JackOSSAdapter.h +++ b/solaris/oss/JackOSSAdapter.h @@ -32,6 +32,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { +class JackClient; + typedef jack_default_audio_sample_t jack_sample_t; #define OSS_DRIVER_DEF_DEV "/dev/dsp" @@ -86,9 +88,11 @@ class JackOSSAdapter : public JackAudioAdapterInterface, public JackRunnableInte void SetSampleFormat(); void DisplayDeviceInfo(); + JackClient &fClient; + public: - JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); + JackOSSAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackOSSAdapter() {} diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index 64c561024..fa8876fe1 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -27,8 +27,8 @@ namespace Jack { -JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel() - :JackGenericClientChannel(),fThread(this) +JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel(JackGlobals *global) + :JackGenericClientChannel(global),fThread(this) { fRequest = new JackWinNamedPipeClient(); } @@ -60,7 +60,7 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam } // OK so server is there... - JackGlobals::fServerRunning = true; + client->GetGlobal()->fServerRunning = true; // Check name in server ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index 298cb5c2e..994a5858b 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -29,6 +29,7 @@ namespace Jack { +class JackGlobals; class JackClient; /*! @@ -46,7 +47,7 @@ class JackWinNamedPipeClientChannel : public JackGenericClientChannel, public Ja public: - JackWinNamedPipeClientChannel(); + JackWinNamedPipeClientChannel(JackGlobals *global); virtual ~JackWinNamedPipeClientChannel(); int Open(const char* server_name, const char* name, jack_uuid_t uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index 7c380193c..a6522d0f8 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -34,7 +34,7 @@ namespace Jack return paContinue; } - JackPortAudioAdapter::JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) + JackPortAudioAdapter::JackPortAudioAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) : JackAudioAdapterInterface(buffer_size, sample_rate) { jack_log("JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size, sample_rate); diff --git a/windows/portaudio/JackPortAudioAdapter.h b/windows/portaudio/JackPortAudioAdapter.h index 3d67978b5..086e19963 100644 --- a/windows/portaudio/JackPortAudioAdapter.h +++ b/windows/portaudio/JackPortAudioAdapter.h @@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { + class JackClient; /*! \brief Audio adapter using PortAudio API. @@ -49,7 +50,7 @@ namespace Jack public: - JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); + JackPortAudioAdapter(JackClient &jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackPortAudioAdapter() {}