Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Multi server by same client support #597

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

twischer-adit
Copy link
Contributor

These PR add support for Jack "multi client" mode. By multi client I mean allowing to create multiple clients who connect to different servers from one process.

In current Jack version this would result in overwriting synchronization and signalling primitives of shared memory. Each created client would overwrite client before, so that previous client would not be able to accept process and other callbacks and notify server of graph competition.

The patch introduces "global context" reference that holds instance of global and shared memory variables for each created client. This global context reference is then passed to all objects who require it.

Please note this PR disables functionality of metadata - this area is still under development and requires some architectural decisions on how to pass the global pointer to metadata.

It replaces #547

Timo Wischer and others added 6 commits June 5, 2020 11:41
Change-Id: I5f5b4a2d0a52ef12ac4e396f40002e8dec916cfb
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Change-Id: I66e0960c9ab1a097de3098d4f51e0fff4d064186
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
fix to reflect programming style of other classes in Jack Audio

Change-Id: I86f5d190d4a9df26a30c5de1b504421efe0202c1
Signed-off-by: Adam Miartus <external.adam.miartus@de.bosch.com>
no functional change is introduced by this commit, tested with:

jack_lsp
jack_simple_client
jack_connect

Change-Id: Iec690b8f3a37867a98af8f197742dae988d274ea
Signed-off-by: Adam Miartus <external.adam.miartus@de.bosch.com>
metadata:
problem here is that we don't have knowledge of the server, each server is
supposed to have its own metadata instance as can be seen in Metadata
implementation

midi:
does not have reference to global context

Change-Id: I80fde1facde3eca40431464264afdf76a002c752
Signed-off-by: Adam Miartus <external.adam.miartus@de.bosch.com>
rework to allow creating multiple clients that connecting to different
jack servers in one process

done by creating a client context which holds server id, this context
is then evaluated against global variables that were extended to hold
multiple synchronization instances for each client

Change-Id: I3a6b4a44fe9d820ba6b6bbbeb06b158d9ad43fce
Signed-off-by: Adam Miartus <external.adam.miartus@de.bosch.com>
@twischer-adit
Copy link
Contributor Author

This PR introduces the following diff compared to #547

diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp
index 3503a52..2c44dca 100644
--- a/common/JackAPI.cpp
+++ b/common/JackAPI.cpp
@@ -354,6 +354,10 @@ LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
         return NULL;
     } else {
         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);
     }
diff --git a/common/JackClient.cpp b/common/JackClient.cpp
index d937464..11e1972 100644
--- a/common/JackClient.cpp
+++ b/common/JackClient.cpp
@@ -39,8 +39,8 @@ namespace Jack
 
 #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL))
 
-JackClient::JackClient(JackGlobals* globals):fThread(this)
-    , JackGlobalsInterface(globals)
+JackClient::JackClient(JackGlobals* globals):JackGlobalsInterface(globals),
+    fThread(this)
 {
     fSynchroTable = globals->GetSynchroTable();
     fProcess = NULL;
diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp
index 595435b..a3084c7 100644
--- a/common/JackEngineProfiling.cpp
+++ b/common/JackEngineProfiling.cpp
@@ -31,12 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 namespace Jack
 {
 
-JackEngineProfiling::JackEngineProfiling(JackGlobals *global):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));
 
-    fGlobal.SetGlobal(global);
-
     // Force memory page in
     memset(fProfileTable, 0, sizeof(fProfileTable));
 }
@@ -356,7 +354,7 @@ void JackEngineProfiling::Profile(JackClientInterface** table,
     fProfileTable[fAudioCycle].fPrevCycleEnd = prev_cycle_end;
     fProfileTable[fAudioCycle].fAudioCycle = fAudioCycle;
 
-    for (int i = fGlobal.GetGlobal()->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
+    for (int i = fGlobal->GetEngineControl()->fDriverNum; i < CLIENT_NUM; i++) {
         JackClientInterface* client = table[i];
         JackClientTiming* timing = manager->GetClientTiming(i);
         if (client && client->GetClientControl()->fActive && client->GetClientControl()->fCallback[kRealTimeCallback]) {
diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h
index bd1fada..bebb820 100644
--- a/common/JackEngineProfiling.h
+++ b/common/JackEngineProfiling.h
@@ -112,14 +112,14 @@ class SERVER_EXPORT JackEngineProfiling
 
     private:
 
+        JackGlobals* fGlobal;
+
         JackTimingMeasure fProfileTable[TIME_POINTS];
         JackTimingClientInterval fIntervalTable[MEASURED_CLIENTS];
 
         unsigned int fAudioCycle;
         unsigned int fMeasuredClient;
 
-        JackGlobalsInterface fGlobal;
-
         bool CheckClient(const char* name, int cur_point);
 
     public:
diff --git a/common/JackGlobals.h b/common/JackGlobals.h
index 97c8fea..d58dd86 100644
--- a/common/JackGlobals.h
+++ b/common/JackGlobals.h
@@ -168,7 +168,11 @@ class JackGlobals
                 return NULL;
             }
 
-            return (jack_port_t*) ((context_id << PORT_SERVER_CONTEXT_SHIFT) | port_id);
+            /* 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;
+
+
         }
 
 };
diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp
index 4e81b33..ba8af64 100644
--- a/common/JackLibAPI.cpp
+++ b/common/JackLibAPI.cpp
@@ -235,7 +235,7 @@ LIB_EXPORT int jack_set_property(jack_client_t* ext_client, jack_uuid_t subject,
     JackGlobals::CheckContext("jack_set_property");
 
     jack_error("jack_set_property is not implemented");
-    abort();
+    return -1;
 
 //    JackClient* client = (JackClient*)ext_client;
 //    jack_log("jack_set_property ext_client %x client %x ", ext_client, client);
@@ -253,7 +253,7 @@ LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** va
     JackGlobals::CheckContext("jack_get_property");
 
     jack_error("jack_get_property is not implemented");
-    abort();
+    return -1;
 
 //    JackMetadata* metadata = GetMetadata();
 //    return (metadata ? metadata->GetProperty(subject, key, value, type) : -1);
@@ -264,7 +264,7 @@ LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_actual_
     JackGlobals::CheckContext("jack_free_description");
 
     jack_error("jack_free_description is not implemented");
-    abort();
+    return;
 
 //    JackMetadata* metadata = GetMetadata();
 //    if (metadata)
@@ -276,7 +276,7 @@ LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc
     JackGlobals::CheckContext("jack_get_properties");
 
     jack_error("jack_get_properties is not implemented");
-    abort();
+    return -1;
 
 //    JackMetadata* metadata = GetMetadata();
 //    return (metadata ? metadata->GetProperties(subject, desc) : -1);
@@ -287,7 +287,7 @@ LIB_EXPORT int jack_get_all_properties(jack_description_t** descriptions)
     JackGlobals::CheckContext("jack_get_all_properties");
 
     jack_error("jack_get_all_properties is not implemented");
-    abort();
+    return -1;
 
 //    JackMetadata* metadata = GetMetadata();
 //    return (metadata ? metadata->GetAllProperties(descriptions) : -1);
@@ -298,7 +298,7 @@ LIB_EXPORT int jack_remove_property(jack_client_t* ext_client, jack_uuid_t subje
     JackGlobals::CheckContext("jack_remove_property");
 
     jack_error("jack_remove_property is not implemented");
-    abort();
+    return -1;
 
 //    JackClient* client = (JackClient*)ext_client;
 //    jack_log("jack_remove_property ext_client %x client %x ", ext_client, client);
@@ -316,7 +316,7 @@ LIB_EXPORT int jack_remove_properties(jack_client_t* ext_client, jack_uuid_t sub
     JackGlobals::CheckContext("jack_remove_properties");
 
     jack_error("jack_remove_properties is not implemented");
-    abort();
+    return -1;
 
 //    JackClient* client = (JackClient*)ext_client;
 //    jack_log("jack_remove_properties ext_client %x client %x ", ext_client, client);
@@ -334,7 +334,7 @@ LIB_EXPORT int jack_remove_all_properties(jack_client_t* ext_client)
     JackGlobals::CheckContext("jack_remove_all_properties");
 
     jack_error("jack_remove_all_properties is not implemented");
-    abort();
+    return -1;
 
 //    JackClient* client = (JackClient*)ext_client;
 //    jack_log("jack_remove_all_properties ext_client %x client %x ", ext_client, client);
diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h
index eba9a05..120d303 100644
--- a/posix/JackSocketClientChannel.h
+++ b/posix/JackSocketClientChannel.h
@@ -29,7 +29,6 @@ namespace Jack
 {
 
 class JackClient;
-class JackGlobal;
 
 /*!
 \brief JackClientChannel using sockets.

This changes are mainly required to solve compiler warnings.

@falkTX
Copy link
Member

falkTX commented Jun 6, 2020

First of all, thanks a lot for the all the small patches.

Please set this specific PR as draft though, since it is not complete.

One thing to note about meta-data, is that it is not implemented on the server-side, only client-side.
So external clients can change and read meta-data, but internal clients cannot.
This is a flaw in the original design from JACK1, which got adopted into JACK2 (so not considered a regression).

@twischer-adit twischer-adit changed the title Multi server by same client support [DRAFT] Multi server by same client support Jun 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants