| @@ -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)) | |||
| @@ -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) { | |||
| @@ -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 = | |||
| @@ -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 | |||
| @@ -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 <list> | |||
| @@ -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; } | |||
| @@ -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; | |||
| @@ -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 <vector> | |||
| #include <assert.h> | |||
| @@ -408,7 +409,7 @@ struct JackClientTiming | |||
| */ | |||
| PRE_PACKED_STRUCTURE | |||
| class SERVER_EXPORT JackConnectionManager | |||
| class SERVER_EXPORT JackConnectionManager : public JackGlobalsInterface | |||
| { | |||
| private: | |||
| @@ -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 | |||
| @@ -1052,6 +1052,12 @@ jackctl_server_open( | |||
| goto fail; | |||
| } | |||
| JackServerGlobals *global = JackGlobalsManager::Instance()->CreateGlobal<JackServerGlobals>(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"); | |||
| @@ -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. | |||
| @@ -126,6 +126,7 @@ typedef std::list<std::pair<std::string, std::pair<std::string, std::string> > > | |||
| class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||
| { | |||
| friend class JackThreadedDriver; | |||
| protected: | |||
| @@ -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; | |||
| @@ -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]) { | |||
| @@ -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, | |||
| @@ -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; | |||
| @@ -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; } | |||
| @@ -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 | |||
| @@ -20,9 +20,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #ifndef __JackGlobals__ | |||
| #define __JackGlobals__ | |||
| #include <memory> | |||
| #include <vector> | |||
| #include <string> | |||
| #include <algorithm> | |||
| #include <mutex> | |||
| #include "JackPlatformPlug.h" | |||
| #include "JackSystemDeps.h" | |||
| #include "JackConstants.h" | |||
| #include "JackError.h" | |||
| #ifdef __CLIENTDEBUG__ | |||
| #include <iostream> | |||
| @@ -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<JackGlobals*> fContexts; | |||
| inline static JackGlobalsManager* Instance() | |||
| { | |||
| return &fInstance; | |||
| } | |||
| template <class T> | |||
| 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<JackGlobals*> &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 <class T> | |||
| inline T* JackGlobalsManager::CreateGlobal(const std::string &server_name) | |||
| { | |||
| uint32_t context_num = fContexts.size(); | |||
| std::vector<JackGlobals*>::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<JackGlobals*>(global)); | |||
| } else { | |||
| *it = global; | |||
| } | |||
| } else { | |||
| global = dynamic_cast<T*>(*it); | |||
| } | |||
| if (global == nullptr) { | |||
| return global; | |||
| } | |||
| bool success = false; | |||
| { | |||
| std::lock_guard<std::mutex> 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<JackGlobals*>::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<std::mutex> lock(global->fMutex); | |||
| if (global->DelContext(fContexts.size()) == false) { | |||
| return; | |||
| } | |||
| } | |||
| delete global; | |||
| *it = nullptr; | |||
| } | |||
| } // end of namespace | |||
| @@ -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) | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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() | |||
| {} | |||
| @@ -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<JackLibGlobals>(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<JackLibGlobals>(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) | |||
| @@ -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<Jack::JackLibGlobals*>(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 @@ error: | |||
| 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 | |||
| @@ -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 | |||
| @@ -50,96 +50,126 @@ class JackClient; | |||
| \brief Global library static structure: singleton kind of pattern. | |||
| */ | |||
| struct JackLibGlobals | |||
| class JackLibGlobals : public JackGlobals | |||
| { | |||
| JackShmReadWritePtr<JackGraphManager> fGraphManager; /*! Shared memory Port manager */ | |||
| JackShmReadWritePtr<JackEngineControl> 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<JackGraphManager> fGraphManager; /*! Shared memory Port manager */ | |||
| JackShmReadWritePtr<JackEngineControl> 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 | |||
| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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 <assert.h> | |||
| 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(); | |||
| @@ -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) | |||
| { | |||
| @@ -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); | |||
| }; | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| @@ -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<JackServerGlobals>(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<JackServerGlobals>(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(); | |||
| @@ -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 <getopt.h> | |||
| #include <errno.h> | |||
| @@ -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 @@ error: | |||
| 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 | |||
| @@ -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 <map> | |||
| 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<std::string, JackDriverInfo*> fSlavesList; | |||
| static std::map<std::string, int> 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<std::string, JackDriverInfo*> fSlavesList; | |||
| static std::map<std::string, int> 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 | |||
| @@ -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(); | |||
| @@ -34,7 +34,9 @@ using namespace std; | |||
| namespace Jack | |||
| { | |||
| JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<jack_position_t>() | |||
| JackTransportEngine::JackTransportEngine(JackGlobals *global) | |||
| : JackAtomicArrayState<jack_position_t>() | |||
| , 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(); | |||
| @@ -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<jack_position_t> | |||
| class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_position_t>, public JackGlobalsInterface | |||
| { | |||
| private: | |||
| @@ -115,7 +116,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_posit | |||
| public: | |||
| JackTransportEngine(); | |||
| JackTransportEngine(JackGlobals *global); | |||
| ~JackTransportEngine() | |||
| {} | |||
| @@ -79,17 +79,17 @@ static int GetPID() | |||
| } | |||
| #ifdef USE_POSIX_SHM | |||
| static jack_shmtype_t jack_shmtype = shm_POSIX; | |||
| static const jack_shmtype_t jack_shmtype = shm_POSIX; | |||
| #elif WIN32 | |||
| static jack_shmtype_t jack_shmtype = shm_WIN32; | |||
| static const jack_shmtype_t jack_shmtype = shm_WIN32; | |||
| #else | |||
| static jack_shmtype_t jack_shmtype = shm_SYSV; | |||
| static const jack_shmtype_t jack_shmtype = shm_SYSV; | |||
| #endif | |||
| /* interface-dependent forward declarations */ | |||
| static int jack_access_registry (jack_shm_info_t *ri); | |||
| static int jack_create_registry (jack_shm_info_t *ri); | |||
| static void jack_remove_shm (jack_shm_id_t *id); | |||
| static void jack_remove_shm (const jack_shm_id_t id); | |||
| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |||
| * common interface-independent section | |||
| @@ -103,7 +103,13 @@ static void jack_remove_shm (jack_shm_id_t *id); | |||
| */ | |||
| /* per-process global data for the SHM interfaces */ | |||
| #ifdef USE_POSIX_SHM | |||
| static const jack_shm_id_t registry_id = "/jack-shm-registry"; | |||
| #elif WIN32 | |||
| static const jack_shm_id_t registry_id = "jack-shm-registry"; | |||
| #else | |||
| static jack_shm_id_t registry_id; /* SHM id for the registry */ | |||
| #endif | |||
| #ifdef WIN32 | |||
| static jack_shm_info_t registry_info = {/* SHM info for the registry */ | |||
| @@ -120,7 +126,6 @@ static jack_shm_info_t registry_info = { /* SHM info for the registry */ | |||
| /* pointers to registry header and array */ | |||
| static jack_shm_header_t *jack_shm_header = NULL; | |||
| static jack_shm_registry_t *jack_shm_registry = NULL; | |||
| static char jack_shm_server_prefix[JACK_SERVER_NAME_SIZE+1] = ""; | |||
| /* jack_shm_lock_registry() serializes updates to the shared memory | |||
| * segment JACK uses to keep track of the SHM segments allocated to | |||
| @@ -315,16 +320,16 @@ jack_shm_validate_registry () | |||
| * name, in the interest of portability we use colons instead. | |||
| */ | |||
| static void | |||
| jack_set_server_prefix (const char *server_name) | |||
| jack_get_server_prefix (const char* const server_name, char* const prefix, const size_t size) | |||
| { | |||
| #ifdef WIN32 | |||
| char buffer[UNLEN+1]={0}; | |||
| DWORD len = UNLEN+1; | |||
| GetUserName(buffer, &len); | |||
| snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), | |||
| snprintf (prefix, size, | |||
| "jack-%s:%s:", buffer, server_name); | |||
| #else | |||
| snprintf (jack_shm_server_prefix, sizeof (jack_shm_server_prefix), | |||
| snprintf (prefix, size, | |||
| "jack-%d:%s:", GetUID(), server_name); | |||
| #endif | |||
| } | |||
| @@ -349,7 +354,7 @@ jack_server_initialize_shm (int new_registry) | |||
| rc = jack_access_registry (®istry_info); | |||
| if (new_registry) { | |||
| jack_remove_shm (®istry_id); | |||
| jack_remove_shm (registry_id); | |||
| rc = ENOENT; | |||
| } | |||
| @@ -365,7 +370,7 @@ jack_server_initialize_shm (int new_registry) | |||
| /* Apparently, this registry was created by an older | |||
| * JACK version. Delete it so we can try again. */ | |||
| jack_release_shm (®istry_info); | |||
| jack_remove_shm (®istry_id); | |||
| jack_remove_shm (registry_id); | |||
| if ((rc = jack_create_registry (®istry_info)) != 0) { | |||
| jack_error ("incompatible shm registry (%s)", | |||
| strerror (errno)); | |||
| @@ -394,11 +399,12 @@ int | |||
| jack_initialize_shm (const char *server_name) | |||
| { | |||
| int rc; | |||
| char server_prefix[JACK_SERVER_NAME_SIZE+1]; | |||
| if (jack_shm_header) | |||
| return 0; /* already initialized */ | |||
| jack_set_server_prefix (server_name); | |||
| jack_get_server_prefix (server_name, server_prefix, sizeof(server_prefix)); | |||
| if (jack_shm_lock_registry () < 0) { | |||
| jack_error ("jack_shm_lock_registry fails..."); | |||
| @@ -429,7 +435,7 @@ jack_destroy_shm (jack_shm_info_t* si) | |||
| if (si->index == 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 | |||
| @@ -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; | |||
| } | |||
| @@ -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() | |||
| {} | |||
| @@ -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() | |||
| {} | |||
| @@ -321,7 +321,7 @@ OSStatus JackCoreAudioAdapter::Render(AudioUnitRenderActionFlags *ioActionFlags, | |||
| } | |||
| } | |||
| 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; | |||
| @@ -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 | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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 <sys/ioctl.h> | |||
| @@ -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: | |||
| @@ -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() | |||
| {} | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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() | |||
| {} | |||