File jack2-PR_386.patch of Package jack

From 51cf95bff1feceddaa1e48a98422b2d2db98ee87 Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Tue, 23 Oct 2018 15:16:15 +0200
Subject: [PATCH 1/8] JackSocket: Continue read/write if only partly done

If a message was only written partly this has not to be interpreted as a
fatal error.
With this change it tries to continue reading/writing as long as there
are bytes read/written.

In addition errno is only valid in case of a return value of -1.
Therefore errno will only be read on a negative error value, now.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 posix/JackSocket.cpp | 60 ++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp
index 73f1fc44..c2e93f5f 100644
--- a/posix/JackSocket.cpp
+++ b/posix/JackSocket.cpp
@@ -165,6 +165,8 @@ int JackClientSocket::Close()
 
 int JackClientSocket::Read(void* data, int len)
 {
+    int pos = 0;
+    uint8_t* buffer = (uint8_t*)data;
     int res;
 
 #if defined(__sun__) || defined(sun)
@@ -192,25 +194,31 @@ int JackClientSocket::Read(void* data, int len)
     }
 #endif
 
-    if ((res = read(fSocket, data, len)) != len) {
-        if (errno == EWOULDBLOCK || errno == EAGAIN) {
-            jack_error("JackClientSocket::Read time out");
-            return 0;  // For a non blocking socket, a read failure is not considered as an error
-        } else if (res != 0) {
-            jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
-            //return 0;
-            return -1;
-        } else {
-            jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
+    while ((res = read(fSocket, &buffer[pos], len)) != len) {
+        if (res < 0) {
+            if (errno == EWOULDBLOCK || errno == EAGAIN) {
+                jack_error("JackClientSocket::Read time out");
+                return 0;  // For a non blocking socket, a read failure is not considered as an error
+            } else {
+                jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
+                return -1;
+            }
+        } else if (res == 0) {
+            jack_error("Cannot read socket fd = %d err = connection closed", fSocket);
             return -1;
         }
-    } else {
-        return 0;
+
+        pos += res;
+        len -= res;
     }
+
+    return 0;
 }
 
 int JackClientSocket::Write(void* data, int len)
 {
+    int pos = 0;
+    uint8_t* buffer = (uint8_t*)data;
     int res;
 
 #if defined(__sun__) || defined(sun)
@@ -238,21 +246,25 @@ int JackClientSocket::Write(void* data, int len)
    }
 #endif
 
-    if ((res = write(fSocket, data, len)) != len) {
-        if (errno == EWOULDBLOCK || errno == EAGAIN) {
-            jack_log("JackClientSocket::Write time out");
-            return 0;  // For a non blocking socket, a write failure is not considered as an error
-        } else if (res != 0) {
-            jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
-            //return 0;
-            return -1;
-        } else {
-            jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
+    while ((res = write(fSocket, &buffer[pos], len)) != len) {
+        if (res < 0) {
+            if (errno == EWOULDBLOCK || errno == EAGAIN) {
+                jack_log("JackClientSocket::Write time out");
+                return 0;  // For a non blocking socket, a write failure is not considered as an error
+            } else {
+                jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
+                return -1;
+            }
+        } else if (res == 0) {
+            jack_error("Cannot write socket fd = %ld err = connection closed", fSocket);
             return -1;
         }
-    } else {
-        return 0;
+
+        pos += res;
+        len -= res;
     }
+
+    return 0;
 }
 
 JackServerSocket::JackServerSocket(): fSocket( -1)

From d9307b4fbc048d09bf6cd2469be02b9af968bb8f Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Thu, 25 Oct 2018 12:27:13 +0200
Subject: [PATCH 2/8] JackSocket: Print file descriptor in log messages

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 posix/JackSocket.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp
index c2e93f5f..3315a14c 100644
--- a/posix/JackSocket.cpp
+++ b/posix/JackSocket.cpp
@@ -132,7 +132,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A
 
     addr.sun_family = AF_UNIX;
     BuildName(name, addr.sun_path, dir, which, sizeof(addr.sun_path), fPromiscuous);
-    jack_log("JackClientSocket::Connect : addr.sun_path %s", addr.sun_path);
+    jack_log("JackClientSocket::Connect : addr.sun_path %s (fd %d)", addr.sun_path, fSocket);
 
     if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
         jack_error("Cannot connect to server socket err = %s", strerror(errno));
@@ -197,7 +197,7 @@ int JackClientSocket::Read(void* data, int len)
     while ((res = read(fSocket, &buffer[pos], len)) != len) {
         if (res < 0) {
             if (errno == EWOULDBLOCK || errno == EAGAIN) {
-                jack_error("JackClientSocket::Read time out");
+                jack_error("JackClientSocket::Read time out on socket fd = %d", fSocket);
                 return 0;  // For a non blocking socket, a read failure is not considered as an error
             } else {
                 jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
@@ -249,7 +249,7 @@ int JackClientSocket::Write(void* data, int len)
     while ((res = write(fSocket, &buffer[pos], len)) != len) {
         if (res < 0) {
             if (errno == EWOULDBLOCK || errno == EAGAIN) {
-                jack_log("JackClientSocket::Write time out");
+                jack_log("JackClientSocket::Write time out on socket fd = %d", fSocket);
                 return 0;  // For a non blocking socket, a write failure is not considered as an error
             } else {
                 jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));

From 77141c93be93502d23dceabc17998d55752135fd Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Mon, 22 Oct 2018 14:49:05 +0200
Subject: [PATCH 3/8] JackRequest: Make ReadType method static

Therefore no object of the class has to be created to detect the type only.
In addition the member variable fType can be const.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackRequest.h                      | 6 ++++--
 common/JackRequestDecoder.cpp             | 6 +++---
 posix/JackSocketServerChannel.cpp         | 6 +++---
 windows/JackWinNamedPipeServerChannel.cpp | 6 +++---
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/common/JackRequest.h b/common/JackRequest.h
index af843191..0ae5126c 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -105,9 +105,11 @@ struct JackRequest
     virtual ~JackRequest()
     {}
 
-    virtual int Read(detail::JackChannelTransactionInterface* trans)
+    static int ReadType(detail::JackChannelTransactionInterface* trans, RequestType& type)
     {
-        return trans->Read(&fType, sizeof(RequestType));
+        type = (RequestType)0;
+        CheckRes(trans->Read(&type, sizeof(fType)));
+        return 0;
     }
 
     virtual int Write(detail::JackChannelTransactionInterface* trans) { return -1; }
diff --git a/common/JackRequestDecoder.cpp b/common/JackRequestDecoder.cpp
index 46bbd1f3..3c18f964 100644
--- a/common/JackRequestDecoder.cpp
+++ b/common/JackRequestDecoder.cpp
@@ -58,9 +58,9 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             CheckWriteName("JackRequest::ClientCheck", socket);
             // Atomic ClientCheck followed by ClientOpen on same socket
             if (req.fOpen) {
-                JackRequest header;
-                header.Read(socket);
-                return HandleRequest(socket, header.fType);
+                JackRequest::RequestType type;
+                JackRequest::ReadType(socket, type);
+                return HandleRequest(socket, type);
             }
             break;
         }
diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp
index eccb5ff0..04cd2385 100644
--- a/posix/JackSocketServerChannel.cpp
+++ b/posix/JackSocketServerChannel.cpp
@@ -237,14 +237,14 @@ bool JackSocketServerChannel::Execute()
                 } else if (fPollTable[i].revents & POLLIN) {
                     JackClientSocket* socket = fSocketTable[fd].second;
                     // Decode header
-                    JackRequest header;
-                    if (header.Read(socket) < 0) {
+                    JackRequest::RequestType type;
+                    if (JackRequest::ReadType(socket, type) < 0) {
                         jack_log("JackSocketServerChannel::Execute : cannot decode header");
                         ClientKill(fd);
                     // Decode request
                     } else {
                         // Result is not needed here
-                        fDecoder->HandleRequest(socket, header.fType);
+                        fDecoder->HandleRequest(socket, type);
                     }
                 }
             }
diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp
index bdd8fcb4..9f700516 100644
--- a/windows/JackWinNamedPipeServerChannel.cpp
+++ b/windows/JackWinNamedPipeServerChannel.cpp
@@ -83,8 +83,8 @@ bool JackClientPipeThread::Execute()
     try {
 
         jack_log("JackClientPipeThread::Execute %x", this);
-        JackRequest header;
-        int res = header.Read(fPipe);
+        JackRequest::RequestType type;
+        int res = JackRequest::ReadType(fPipe, type);
         bool ret = true;
 
         // Lock the global mutex
@@ -98,7 +98,7 @@ bool JackClientPipeThread::Execute()
             ClientKill();
             ret = false;
         // Decode request
-        } else if (fDecoder->HandleRequest(fPipe, header.fType) < 0) {
+        } else if (fDecoder->HandleRequest(fPipe, type) < 0) {
             ret = false;
         }
 

From 53db7d045de4c4fec90f51ff80b7cfbe35feaf81 Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Mon, 22 Oct 2018 15:44:07 +0200
Subject: [PATCH 4/8] JackRequest: Do not provide default constructor

to always use the same initialization of the object.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackRequest.h | 146 ++++++++-----------------------------------
 1 file changed, 27 insertions(+), 119 deletions(-)

diff --git a/common/JackRequest.h b/common/JackRequest.h
index 0ae5126c..3ffba705 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -96,9 +96,6 @@ struct JackRequest
     RequestType fType;
     int fSize;
 
-    JackRequest(): fType((RequestType)0), fSize(0)
-    {}
-
     JackRequest(RequestType type): fType(type), fSize(0)
     {}
 
@@ -166,11 +163,7 @@ struct JackClientCheckRequest : public JackRequest
     int fUUID;
     int fOpen;
 
-    JackClientCheckRequest() : fProtocol(0), fOptions(0), fUUID(0), fOpen(0)
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-    JackClientCheckRequest(const char* name, int protocol, int options, int uuid, int open = false)
+    JackClientCheckRequest(const char* name="", int protocol=0, int options=0, int uuid=0, int open = false)
         : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open)
     {
         memset(fName, 0, sizeof(fName));
@@ -251,11 +244,7 @@ struct JackClientOpenRequest : public JackRequest
     int fUUID;
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackClientOpenRequest() : fPID(0), fUUID(0)
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-    JackClientOpenRequest(const char* name, int pid, int uuid): JackRequest(JackRequest::kClientOpen)
+    JackClientOpenRequest(const char* name="", int pid=0, int uuid=0): JackRequest(JackRequest::kClientOpen)
     {
         memset(fName, 0, sizeof(fName));
         snprintf(fName, sizeof(fName), "%s", name);
@@ -330,9 +319,7 @@ struct JackClientCloseRequest : public JackRequest
 
     int fRefNum;
 
-    JackClientCloseRequest() : fRefNum(0)
-    {}
-    JackClientCloseRequest(int refnum): JackRequest(JackRequest::kClientClose), fRefNum(refnum)
+    JackClientCloseRequest(int refnum=0): JackRequest(JackRequest::kClientClose), fRefNum(refnum)
     {}
 
     int Read(detail::JackChannelTransactionInterface* trans)
@@ -360,9 +347,7 @@ struct JackActivateRequest : public JackRequest
     int fRefNum;
     int fIsRealTime;
 
-    JackActivateRequest() : fRefNum(0), fIsRealTime(0)
-    {}
-    JackActivateRequest(int refnum, int is_real_time)
+    JackActivateRequest(int refnum=0, int is_real_time=0)
         : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fIsRealTime(is_real_time)
     {}
 
@@ -392,9 +377,7 @@ struct JackDeactivateRequest : public JackRequest
 
     int fRefNum;
 
-    JackDeactivateRequest() : fRefNum(0)
-    {}
-    JackDeactivateRequest(int refnum): JackRequest(JackRequest::kDeactivateClient), fRefNum(refnum)
+    JackDeactivateRequest(int refnum=0): JackRequest(JackRequest::kDeactivateClient), fRefNum(refnum)
     {}
 
     int Read(detail::JackChannelTransactionInterface* trans)
@@ -425,12 +408,7 @@ struct JackPortRegisterRequest : public JackRequest
     unsigned int fFlags;
     unsigned int fBufferSize;
 
-    JackPortRegisterRequest() : fRefNum(0), fFlags(0), fBufferSize(0)
-    {
-        memset(fName, 0, sizeof(fName));
-        memset(fPortType, 0, sizeof(fPortType));
-    }
-    JackPortRegisterRequest(int refnum, const char* name, const char* port_type, unsigned int flags, unsigned int buffer_size)
+    JackPortRegisterRequest(int refnum=0, const char* name="", const char* port_type="", unsigned int flags=0, unsigned int buffer_size=0)
             : JackRequest(JackRequest::kRegisterPort), fRefNum(refnum), fFlags(flags), fBufferSize(buffer_size)
     {
         memset(fName, 0, sizeof(fName));
@@ -501,9 +479,7 @@ struct JackPortUnRegisterRequest : public JackRequest
     int fRefNum;
     jack_port_id_t fPortIndex;
 
-    JackPortUnRegisterRequest() : fRefNum(0), fPortIndex(0)
-    {}
-    JackPortUnRegisterRequest(int refnum, jack_port_id_t index)
+    JackPortUnRegisterRequest(int refnum=0, jack_port_id_t index=0)
         : JackRequest(JackRequest::kUnRegisterPort), fRefNum(refnum), fPortIndex(index)
     {}
 
@@ -537,12 +513,7 @@ struct JackPortConnectNameRequest : public JackRequest
     char fSrc[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
     char fDst[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
 
-    JackPortConnectNameRequest() : fRefNum(0)
-    {
-        memset(fSrc, 0, sizeof(fSrc));
-        memset(fDst, 0, sizeof(fDst));
-    }
-    JackPortConnectNameRequest(int refnum, const char* src_name, const char* dst_name)
+    JackPortConnectNameRequest(int refnum=0, const char* src_name="", const char* dst_name="")
         : JackRequest(JackRequest::kConnectNamePorts), fRefNum(refnum)
     {
         memset(fSrc, 0, sizeof(fSrc));
@@ -584,12 +555,7 @@ struct JackPortDisconnectNameRequest : public JackRequest
     char fSrc[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
     char fDst[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
 
-    JackPortDisconnectNameRequest() : fRefNum(0)
-    {
-        memset(fSrc, 0, sizeof(fSrc));
-        memset(fDst, 0, sizeof(fDst));
-    }
-    JackPortDisconnectNameRequest(int refnum, const char* src_name, const char* dst_name)
+    JackPortDisconnectNameRequest(int refnum=0, const char* src_name="", const char* dst_name="")
         : JackRequest(JackRequest::kDisconnectNamePorts), fRefNum(refnum)
     {
         memset(fSrc, 0, sizeof(fSrc));
@@ -631,9 +597,7 @@ struct JackPortConnectRequest : public JackRequest
     jack_port_id_t fSrc;
     jack_port_id_t fDst;
 
-    JackPortConnectRequest() : fRefNum(0), fSrc(0), fDst(0)
-    {}
-    JackPortConnectRequest(int refnum, jack_port_id_t src, jack_port_id_t dst)
+    JackPortConnectRequest(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
         : JackRequest(JackRequest::kConnectPorts), fRefNum(refnum), fSrc(src), fDst(dst)
     {}
 
@@ -669,9 +633,7 @@ struct JackPortDisconnectRequest : public JackRequest
     jack_port_id_t fSrc;
     jack_port_id_t fDst;
 
-    JackPortDisconnectRequest() : fRefNum(0), fSrc(0), fDst(0)
-    {}
-    JackPortDisconnectRequest(int refnum, jack_port_id_t src, jack_port_id_t dst)
+    JackPortDisconnectRequest(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
         : JackRequest(JackRequest::kDisconnectPorts), fRefNum(refnum), fSrc(src), fDst(dst)
     {}
 
@@ -707,11 +669,7 @@ struct JackPortRenameRequest : public JackRequest
     jack_port_id_t fPort;
     char fName[JACK_PORT_NAME_SIZE + 1];   // port short name
 
-    JackPortRenameRequest() : fRefNum(0), fPort(0)
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-    JackPortRenameRequest(int refnum, jack_port_id_t port, const char* name)
+    JackPortRenameRequest(int refnum=0, jack_port_id_t port=0, const char* name="")
         : JackRequest(JackRequest::kPortRename), fRefNum(refnum), fPort(port)
     {
         memset(fName, 0, sizeof(fName));
@@ -749,9 +707,7 @@ struct JackSetBufferSizeRequest : public JackRequest
 
     jack_nframes_t fBufferSize;
 
-    JackSetBufferSizeRequest() : fBufferSize(0)
-    {}
-    JackSetBufferSizeRequest(jack_nframes_t buffer_size)
+    JackSetBufferSizeRequest(jack_nframes_t buffer_size=0)
         : JackRequest(JackRequest::kSetBufferSize), fBufferSize(buffer_size)
     {}
 
@@ -779,9 +735,7 @@ struct JackSetFreeWheelRequest : public JackRequest
 
     int fOnOff;
 
-    JackSetFreeWheelRequest() : fOnOff(0)
-    {}
-    JackSetFreeWheelRequest(int onoff)
+    JackSetFreeWheelRequest(int onoff=0)
         : JackRequest(JackRequest::kSetFreeWheel), fOnOff(onoff)
     {}
 
@@ -836,9 +790,7 @@ struct JackReleaseTimebaseRequest : public JackRequest
 
     int fRefNum;
 
-    JackReleaseTimebaseRequest() : fRefNum(0)
-    {}
-    JackReleaseTimebaseRequest(int refnum)
+    JackReleaseTimebaseRequest(int refnum=0)
         : JackRequest(JackRequest::kReleaseTimebase), fRefNum(refnum)
     {}
 
@@ -868,9 +820,7 @@ struct JackSetTimebaseCallbackRequest : public JackRequest
     int fRefNum;
     int fConditionnal;
 
-    JackSetTimebaseCallbackRequest() : fRefNum(0), fConditionnal(0)
-    {}
-    JackSetTimebaseCallbackRequest(int refnum, int conditional)
+    JackSetTimebaseCallbackRequest(int refnum=0, int conditional=0)
         : JackRequest(JackRequest::kSetTimebaseCallback), fRefNum(refnum), fConditionnal(conditional)
     {}
 
@@ -901,9 +851,7 @@ struct JackGetInternalClientNameRequest : public JackRequest
     int fRefNum;
     int fIntRefNum;
 
-    JackGetInternalClientNameRequest() : fRefNum(0), fIntRefNum(0)
-    {}
-    JackGetInternalClientNameRequest(int refnum, int int_ref)
+    JackGetInternalClientNameRequest(int refnum=0, int int_ref=0)
             : JackRequest(JackRequest::kGetInternalClientName), fRefNum(refnum), fIntRefNum(int_ref)
     {}
 
@@ -971,11 +919,7 @@ struct JackInternalClientHandleRequest : public JackRequest
     int fRefNum;
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackInternalClientHandleRequest() : fRefNum(0)
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-    JackInternalClientHandleRequest(int refnum, const char* client_name)
+    JackInternalClientHandleRequest(int refnum=0, const char* client_name="")
             : JackRequest(JackRequest::kInternalClientHandle), fRefNum(refnum)
     {
         memset(fName, 0, sizeof(fName));
@@ -1052,13 +996,7 @@ struct JackInternalClientLoadRequest : public JackRequest
     int fOptions;
     int fUUID;
 
-    JackInternalClientLoadRequest() : fRefNum(0), fOptions(0), fUUID(0)
-    {
-        memset(fName, 0, sizeof(fName));
-        memset(fDllName, 0, sizeof(fDllName));
-        memset(fLoadInitName, 0, sizeof(fLoadInitName));
-    }
-    JackInternalClientLoadRequest(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int uuid )
+    JackInternalClientLoadRequest(int refnum=0, const char* client_name="", const char* so_name="", const char* objet_data="", int options=0, int uuid=0 )
             : JackRequest(JackRequest::kInternalClientLoad), fRefNum(refnum), fOptions(options), fUUID(uuid)
     {
         memset(fName, 0, sizeof(fName));
@@ -1139,9 +1077,7 @@ struct JackInternalClientUnloadRequest : public JackRequest
     int fRefNum;
     int fIntRefNum;
 
-    JackInternalClientUnloadRequest() : fRefNum(0), fIntRefNum(0)
-    {}
-    JackInternalClientUnloadRequest(int refnum, int int_ref)
+    JackInternalClientUnloadRequest(int refnum=0, int int_ref=0)
             : JackRequest(JackRequest::kInternalClientUnload), fRefNum(refnum), fIntRefNum(int_ref)
     {}
 
@@ -1205,9 +1141,7 @@ struct JackClientNotificationRequest : public JackRequest
     int fNotify;
     int fValue;
 
-    JackClientNotificationRequest() : fRefNum(0), fNotify(0), fValue(0)
-    {}
-    JackClientNotificationRequest(int refnum, int notify, int value)
+    JackClientNotificationRequest(int refnum=0, int notify=0, int value=0)
             : JackRequest(JackRequest::kNotification), fRefNum(refnum), fNotify(notify), fValue(value)
     {}
 
@@ -1358,9 +1292,7 @@ struct JackSessionNotifyRequest : public JackRequest
     jack_session_event_type_t fEventType;
     int fRefNum;
 
-    JackSessionNotifyRequest() : fEventType(JackSessionSave), fRefNum(0)
-    {}
-    JackSessionNotifyRequest(int refnum, const char* path, jack_session_event_type_t type, const char* dst)
+    JackSessionNotifyRequest(int refnum=0, const char* path="", jack_session_event_type_t type=JackSessionSave, const char* dst=NULL)
             : JackRequest(JackRequest::kSessionNotify), fEventType(type), fRefNum(refnum)
     {
         memset(fPath, 0, sizeof(fPath));
@@ -1400,10 +1332,7 @@ struct JackSessionReplyRequest : public JackRequest
 {
     int fRefNum;
 
-    JackSessionReplyRequest() : fRefNum(0)
-    {}
-
-    JackSessionReplyRequest(int refnum)
+    JackSessionReplyRequest(int refnum=0)
             : JackRequest(JackRequest::kSessionReply), fRefNum(refnum)
     {}
 
@@ -1491,12 +1420,7 @@ struct JackGetUUIDRequest : public JackRequest
 {
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackGetUUIDRequest()
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-
-    JackGetUUIDRequest(const char* client_name)
+    JackGetUUIDRequest(const char* client_name="")
             : JackRequest(JackRequest::kGetUUIDByClient)
     {
         memset(fName, 0, sizeof(fName));
@@ -1525,12 +1449,7 @@ struct JackGetClientNameRequest : public JackRequest
 {
     char fUUID[JACK_UUID_SIZE];
 
-    JackGetClientNameRequest()
-    {
-        memset(fUUID, 0, sizeof(fUUID));
-    }
-
-    JackGetClientNameRequest(const char* uuid)
+    JackGetClientNameRequest(const char* uuid="")
             : JackRequest(JackRequest::kGetClientByUUID)
     {
         memset(fUUID, 0, sizeof(fUUID));
@@ -1561,13 +1480,7 @@ struct JackReserveNameRequest : public JackRequest
     char fName[JACK_CLIENT_NAME_SIZE+1];
     char fUUID[JACK_UUID_SIZE];
 
-    JackReserveNameRequest() : fRefNum(0)
-    {
-        memset(fName, 0, sizeof(fName));
-        memset(fUUID, 0, sizeof(fUUID));
-    }
-
-    JackReserveNameRequest(int refnum, const char *name, const char* uuid)
+    JackReserveNameRequest(int refnum=0, const char *name="", const char* uuid="")
             : JackRequest(JackRequest::kReserveClientName), fRefNum(refnum)
     {
         memset(fName, 0, sizeof(fName));
@@ -1602,12 +1515,7 @@ struct JackClientHasSessionCallbackRequest : public JackRequest
 {
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackClientHasSessionCallbackRequest()
-    {
-        memset(fName, 0, sizeof(fName));
-    }
-
-    JackClientHasSessionCallbackRequest(const char *name)
+    JackClientHasSessionCallbackRequest(const char *name="")
             : JackRequest(JackRequest::kClientHasSessionCallback)
     {
         memset(fName, 0, sizeof(fName));

From 9e4f3a7bb61a5b4035ddaef600eb52f29d952c4c Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Tue, 6 Nov 2018 14:16:26 +0100
Subject: [PATCH 5/8] JackRequest: Add template for building requests

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackRequest.h | 62 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/common/JackRequest.h b/common/JackRequest.h
index 3ffba705..3a586331 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -122,6 +122,68 @@ struct JackRequest
 
 };
 
+
+PRE_PACKED_STRUCTURE
+template<class DATA>
+struct JackRequestMessage
+{
+protected:
+    const JackRequest::RequestType fType;
+    const int fSize;
+public:
+    DATA d;
+
+protected:
+    template<typename... Args>
+        JackRequestMessage(Args&... args) : fType(DATA::Type()),
+            fSize(sizeof(JackRequestMessage<DATA>) - sizeof(fType) - sizeof(fSize)),
+            d(args...)
+        {}
+
+        int ReadMessage(detail::JackChannelTransactionInterface* trans)
+        {
+            int size = 0;
+            CheckRes(trans->Read(&size, sizeof(fSize)));
+            if (size != fSize) {
+                jack_error("CheckSize error expected %d actual %d", fSize, size);
+                return -1;
+            }
+
+            CheckRes(trans->Read(&d, fSize));
+            return 0;
+        }
+
+        int WriteMessage(detail::JackChannelTransactionInterface* trans)
+        {
+            CheckRes(trans->Write(this, sizeof(JackRequestMessage<DATA>)));
+            return 0;
+        }
+} POST_PACKED_STRUCTURE;
+
+
+template<class DATA>
+struct JackRequestTemplate : public JackRequest, public JackRequestMessage<DATA>
+{
+    template<typename... Args>
+        JackRequestTemplate(Args&... args) : JackRequestMessage<DATA>(args...)
+        {}
+
+    int Read(detail::JackChannelTransactionInterface* trans)
+    {
+        return JackRequestMessage<DATA>::ReadMessage(trans);
+    }
+
+    int Write(detail::JackChannelTransactionInterface* trans)
+    {
+        return JackRequestMessage<DATA>::WriteMessage(trans);
+    }
+
+    JackRequest::RequestType getType()
+    {
+        return JackRequestMessage<DATA>::fType;
+    }
+};
+
 /*!
 \brief Result from the server.
 */

From e5ed385067eebde6f59934d2bd560bea84178b2a Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Tue, 6 Nov 2018 14:19:44 +0100
Subject: [PATCH 6/8] JackRequest: Try to write request in one shot

With this adaption the probability that a message will be written
completely is higher.
On high load there are 647x/sec EAGAIN failures without this patch
and 570x/sec failures with this patch.
(The "JackClientSocket::Write time out" log messages were counted when
simulating continuously Xruns.)

In case of EAGAIN failures the message will now completely ignored.
Therefore it the socket stream will only contain complete messages
and no partly written messages. Such partly written messages would be
interpreted wrongly by the reader and the reader would detect the start
of the next message in the middle of the message. This could result in
"Unknown request" error logs but could also end up with assertions due
to request attributes which are out of range.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackGenericClientChannel.cpp |   6 +-
 common/JackRequest.h                | 782 ++++++++--------------------
 common/JackRequestDecoder.cpp       |  64 +--
 common/JackRequestDecoder.h         |   4 +-
 posix/JackSocketServerChannel.cpp   |   2 +-
 5 files changed, 268 insertions(+), 590 deletions(-)

diff --git a/common/JackGenericClientChannel.cpp b/common/JackGenericClientChannel.cpp
index 047d7bfa..cce1a1d9 100644
--- a/common/JackGenericClientChannel.cpp
+++ b/common/JackGenericClientChannel.cpp
@@ -60,13 +60,13 @@ void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res,
     }
     
     if (req->Write(fRequest) < 0) {
-        jack_error("Could not write request type = %ld", req->fType);
+        jack_error("Could not write request type = %ld", req->getType());
         *result = -1;
         return;
     }
 
     if (res->Read(fRequest) < 0) {
-        jack_error("Could not read result type = %ld", req->fType);
+        jack_error("Could not read result type = %ld", req->getType());
         *result = -1;
         return;
     }
@@ -90,7 +90,7 @@ void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res
     }
     
     if (req->Write(fRequest) < 0) {
-        jack_error("Could not write request type = %ld", req->fType);
+        jack_error("Could not write request type = %ld", req->getType());
         *result = -1;
     } else {
         *result = 0;
diff --git a/common/JackRequest.h b/common/JackRequest.h
index 3a586331..21364db6 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -93,32 +93,16 @@ struct JackRequest
         kPropertyChangeNotify = 40
     };
 
-    RequestType fType;
-    int fSize;
-
-    JackRequest(RequestType type): fType(type), fSize(0)
-    {}
-
-    virtual ~JackRequest()
-    {}
-
     static int ReadType(detail::JackChannelTransactionInterface* trans, RequestType& type)
     {
         type = (RequestType)0;
-        CheckRes(trans->Read(&type, sizeof(fType)));
+        CheckRes(trans->Read(&type, sizeof(RequestType)));
         return 0;
     }
 
-    virtual int Write(detail::JackChannelTransactionInterface* trans) { return -1; }
-    
-    virtual int Write(detail::JackChannelTransactionInterface* trans, int size)
-    {
-        fSize = size;
-        CheckRes(trans->Write(&fType, sizeof(RequestType)));
-        return trans->Write(&fSize, sizeof(int));
-    }
-    
-    virtual int Size() { return 0; }
+    virtual int Read(detail::JackChannelTransactionInterface* trans) = 0;
+    virtual int Write(detail::JackChannelTransactionInterface* trans) = 0;
+    virtual RequestType getType() = 0;
 
 };
 
@@ -216,7 +200,8 @@ struct JackResult
 \brief CheckClient request.
 */
 
-struct JackClientCheckRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackClientCheckRequestData
 {
 
     char fName[JACK_CLIENT_NAME_SIZE+1];
@@ -225,36 +210,20 @@ struct JackClientCheckRequest : public JackRequest
     int fUUID;
     int fOpen;
 
-    JackClientCheckRequest(const char* name="", int protocol=0, int options=0, int uuid=0, int open = false)
-        : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open)
+    JackClientCheckRequestData(const char* name="", int protocol=0, int options=0, int uuid=0, int open = false)
+        : fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open)
     {
         memset(fName, 0, sizeof(fName));
         snprintf(fName, sizeof(fName), "%s", name);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        CheckRes(trans->Read(&fProtocol, sizeof(int)));
-        CheckRes(trans->Read(&fOptions, sizeof(int)));
-        CheckRes(trans->Read(&fUUID, sizeof(int)));
-        return trans->Read(&fOpen, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        CheckRes(trans->Write(&fProtocol, sizeof(int)));
-        CheckRes(trans->Write(&fOptions, sizeof(int)));
-        CheckRes(trans->Write(&fUUID, sizeof(int)));
-        return trans->Write(&fOpen, sizeof(int));
+        return JackRequest::RequestType::kClientCheck;
     }
-    
-    int Size() { return sizeof(fName) + 4 * sizeof(int); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackClientCheckRequestData> JackClientCheckRequest;
 
 /*!
 \brief CheckClient result.
@@ -299,14 +268,15 @@ struct JackClientCheckResult : public JackResult
 \brief NewClient request.
 */
 
-struct JackClientOpenRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackClientOpenRequestData
 {
 
     int fPID;
     int fUUID;
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackClientOpenRequest(const char* name="", int pid=0, int uuid=0): JackRequest(JackRequest::kClientOpen)
+    JackClientOpenRequestData(const char* name="", int pid=0, int uuid=0)
     {
         memset(fName, 0, sizeof(fName));
         snprintf(fName, sizeof(fName), "%s", name);
@@ -314,25 +284,13 @@ struct JackClientOpenRequest : public JackRequest
         fUUID = uuid;
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fPID, sizeof(int)));
-        CheckRes(trans->Read(&fUUID, sizeof(int)));
-        return trans->Read(&fName, sizeof(fName));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fPID, sizeof(int)));
-        CheckRes(trans->Write(&fUUID, sizeof(int)));
-        return trans->Write(&fName, sizeof(fName));
+        return JackRequest::RequestType::kClientOpen;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return 2 * sizeof(int) + sizeof(fName); }
-    
-};
+typedef JackRequestTemplate<JackClientOpenRequestData> JackClientOpenRequest;
 
 /*!
 \brief NewClient result.
@@ -376,92 +334,73 @@ struct JackClientOpenResult : public JackResult
 \brief CloseClient request.
 */
 
-struct JackClientCloseRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackClientCloseRequestData
 {
 
     int fRefNum;
 
-    JackClientCloseRequest(int refnum=0): JackRequest(JackRequest::kClientClose), fRefNum(refnum)
+    JackClientCloseRequestData(int refnum=0): fRefNum(refnum)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        return trans->Read(&fRefNum, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return trans->Write(&fRefNum, sizeof(int));
+        return JackRequest::RequestType::kClientClose;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int); }
-};
+typedef JackRequestTemplate<JackClientCloseRequestData> JackClientCloseRequest;
 
 /*!
 \brief Activate request.
 */
 
-struct JackActivateRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackActivateRequestData
 {
 
     int fRefNum;
     int fIsRealTime;
 
-    JackActivateRequest(int refnum=0, int is_real_time=0)
-        : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fIsRealTime(is_real_time)
+    JackActivateRequestData(int refnum=0, int is_real_time=0)
+        : fRefNum(refnum), fIsRealTime(is_real_time)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return trans->Read(&fIsRealTime, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return trans->Write(&fIsRealTime, sizeof(int));
+        return JackRequest::RequestType::kActivateClient;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return 2 * sizeof(int); }
-};
+typedef JackRequestTemplate<JackActivateRequestData> JackActivateRequest;
 
 /*!
 \brief Deactivate request.
 */
 
-struct JackDeactivateRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackDeactivateRequestData
 {
 
     int fRefNum;
 
-    JackDeactivateRequest(int refnum=0): JackRequest(JackRequest::kDeactivateClient), fRefNum(refnum)
+    JackDeactivateRequestData(int refnum=0) : fRefNum(refnum)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        return trans->Read(&fRefNum, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return trans->Write(&fRefNum, sizeof(int));
+        return JackRequest::RequestType::kDeactivateClient;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int); }
-};
+typedef JackRequestTemplate<JackDeactivateRequestData> JackDeactivateRequest;
 
 /*!
 \brief PortRegister request.
 */
 
-struct JackPortRegisterRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortRegisterRequestData
 {
 
     int fRefNum;
@@ -470,8 +409,8 @@ struct JackPortRegisterRequest : public JackRequest
     unsigned int fFlags;
     unsigned int fBufferSize;
 
-    JackPortRegisterRequest(int refnum=0, const char* name="", const char* port_type="", unsigned int flags=0, unsigned int buffer_size=0)
-            : JackRequest(JackRequest::kRegisterPort), fRefNum(refnum), fFlags(flags), fBufferSize(buffer_size)
+    JackPortRegisterRequestData(int refnum=0, const char* name="", const char* port_type="", unsigned int flags=0, unsigned int buffer_size=0)
+            : fRefNum(refnum), fFlags(flags), fBufferSize(buffer_size)
     {
         memset(fName, 0, sizeof(fName));
         memset(fPortType, 0, sizeof(fPortType));
@@ -479,31 +418,14 @@ struct JackPortRegisterRequest : public JackRequest
         strncpy(fPortType, port_type, sizeof(fPortType)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        CheckRes(trans->Read(&fPortType, sizeof(fPortType)));
-        CheckRes(trans->Read(&fFlags, sizeof(unsigned int)));
-        CheckRes(trans->Read(&fBufferSize, sizeof(unsigned int)));
-        return 0;
-    }
 
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        CheckRes(trans->Write(&fPortType, sizeof(fPortType)));
-        CheckRes(trans->Write(&fFlags, sizeof(unsigned int)));
-        CheckRes(trans->Write(&fBufferSize, sizeof(unsigned int)));
-        return 0;
+        return JackRequest::RequestType::kRegisterPort;
     }
-    
-    int Size() { return sizeof(int) + sizeof(fName) + sizeof(fPortType) + 2 * sizeof(unsigned int); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackPortRegisterRequestData> JackPortRegisterRequest;
 
 /*!
 \brief PortRegister result.
@@ -535,48 +457,39 @@ struct JackPortRegisterResult : public JackResult
 \brief PortUnregister request.
 */
 
-struct JackPortUnRegisterRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortUnRegisterRequestData
 {
 
     int fRefNum;
     jack_port_id_t fPortIndex;
 
-    JackPortUnRegisterRequest(int refnum=0, jack_port_id_t index=0)
-        : JackRequest(JackRequest::kUnRegisterPort), fRefNum(refnum), fPortIndex(index)
+    JackPortUnRegisterRequestData(int refnum=0, jack_port_id_t index=0)
+        : fRefNum(refnum), fPortIndex(index)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fPortIndex, sizeof(jack_port_id_t)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fPortIndex, sizeof(jack_port_id_t)));
-        return 0;
+        return JackRequest::RequestType::kUnRegisterPort;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(jack_port_id_t); }
-};
+typedef JackRequestTemplate<JackPortUnRegisterRequestData> JackPortUnRegisterRequest;
 
 /*!
 \brief PortConnectName request.
 */
 
-struct JackPortConnectNameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortConnectNameRequestData
 {
 
     int fRefNum;
     char fSrc[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
     char fDst[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
 
-    JackPortConnectNameRequest(int refnum=0, const char* src_name="", const char* dst_name="")
-        : JackRequest(JackRequest::kConnectNamePorts), fRefNum(refnum)
+    JackPortConnectNameRequestData(int refnum=0, const char* src_name="", const char* dst_name="")
+        : fRefNum(refnum)
     {
         memset(fSrc, 0, sizeof(fSrc));
         memset(fDst, 0, sizeof(fDst));
@@ -584,41 +497,28 @@ struct JackPortConnectNameRequest : public JackRequest
         strncpy(fDst, dst_name, sizeof(fDst)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fSrc, sizeof(fSrc)));
-        CheckRes(trans->Read(&fDst, sizeof(fDst)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fSrc, sizeof(fSrc)));
-        CheckRes(trans->Write(&fDst, sizeof(fDst)));
-        return 0;
+        return JackRequest::RequestType::kConnectNamePorts;
     }
-    
-    int Size() { return sizeof(int) + sizeof(fSrc) + sizeof(fDst); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackPortConnectNameRequestData> JackPortConnectNameRequest;
 
 /*!
 \brief PortDisconnectName request.
 */
 
-struct JackPortDisconnectNameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortDisconnectNameRequestData
 {
 
     int fRefNum;
     char fSrc[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
     char fDst[REAL_JACK_PORT_NAME_SIZE+1];    // port full name
 
-    JackPortDisconnectNameRequest(int refnum=0, const char* src_name="", const char* dst_name="")
-        : JackRequest(JackRequest::kDisconnectNamePorts), fRefNum(refnum)
+    JackPortDisconnectNameRequestData(int refnum=0, const char* src_name="", const char* dst_name="")
+        : fRefNum(refnum)
     {
         memset(fSrc, 0, sizeof(fSrc));
         memset(fDst, 0, sizeof(fDst));
@@ -626,313 +526,215 @@ struct JackPortDisconnectNameRequest : public JackRequest
         strncpy(fDst, dst_name, sizeof(fDst)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fSrc, sizeof(fSrc)));
-        CheckRes(trans->Read(&fDst, sizeof(fDst)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fSrc, sizeof(fSrc)));
-        CheckRes(trans->Write(&fDst, sizeof(fDst)));
-        return 0;
+        return JackRequest::RequestType::kDisconnectNamePorts;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(fSrc) + sizeof(fDst); }
-    
-};
+typedef JackRequestTemplate<JackPortDisconnectNameRequestData> JackPortDisconnectNameRequest;
 
 /*!
 \brief PortConnect request.
 */
 
-struct JackPortConnectRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortConnectRequestData
 {
 
     int fRefNum;
     jack_port_id_t fSrc;
     jack_port_id_t fDst;
 
-    JackPortConnectRequest(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
-        : JackRequest(JackRequest::kConnectPorts), fRefNum(refnum), fSrc(src), fDst(dst)
+    JackPortConnectRequestData(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
+        : fRefNum(refnum), fSrc(src), fDst(dst)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fSrc, sizeof(jack_port_id_t)));
-        CheckRes(trans->Read(&fDst, sizeof(jack_port_id_t)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fSrc, sizeof(jack_port_id_t)));
-        CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t)));
-        return 0;
+        return JackRequest::RequestType::kConnectPorts;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(jack_port_id_t); }
-};
+typedef JackRequestTemplate<JackPortConnectRequestData> JackPortConnectRequest;
 
 /*!
 \brief PortDisconnect request.
 */
 
-struct JackPortDisconnectRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortDisconnectRequestData
 {
 
     int fRefNum;
     jack_port_id_t fSrc;
     jack_port_id_t fDst;
 
-    JackPortDisconnectRequest(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
-        : JackRequest(JackRequest::kDisconnectPorts), fRefNum(refnum), fSrc(src), fDst(dst)
+    JackPortDisconnectRequestData(int refnum=0, jack_port_id_t src=0, jack_port_id_t dst=0)
+        : fRefNum(refnum), fSrc(src), fDst(dst)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fSrc, sizeof(jack_port_id_t)));
-        CheckRes(trans->Read(&fDst, sizeof(jack_port_id_t)));
-        return 0;
+        return JackRequest::RequestType::kDisconnectPorts;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fSrc, sizeof(jack_port_id_t)));
-        CheckRes(trans->Write(&fDst, sizeof(jack_port_id_t)));
-        return 0;
-    }
-
-    int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(jack_port_id_t); }
-};
+typedef JackRequestTemplate<JackPortDisconnectRequestData> JackPortDisconnectRequest;
 
 /*!
 \brief PortRename request.
 */
 
-struct JackPortRenameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPortRenameRequestData
 {
 
     int fRefNum;
     jack_port_id_t fPort;
     char fName[JACK_PORT_NAME_SIZE + 1];   // port short name
 
-    JackPortRenameRequest(int refnum=0, jack_port_id_t port=0, const char* name="")
-        : JackRequest(JackRequest::kPortRename), fRefNum(refnum), fPort(port)
+    JackPortRenameRequestData(int refnum=0, jack_port_id_t port=0, const char* name="")
+        : fRefNum(refnum), fPort(port)
     {
         memset(fName, 0, sizeof(fName));
         strncpy(fName, name, sizeof(fName)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fPort, sizeof(jack_port_id_t)));
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fPort, sizeof(jack_port_id_t)));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        return 0;
+        return JackRequest::RequestType::kPortRename;
     }
-    
-    int Size() { return sizeof(int) + sizeof(jack_port_id_t) + sizeof(fName); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackPortRenameRequestData> JackPortRenameRequest;
 
 /*!
 \brief SetBufferSize request.
 */
 
-struct JackSetBufferSizeRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackSetBufferSizeRequestData
 {
 
     jack_nframes_t fBufferSize;
 
-    JackSetBufferSizeRequest(jack_nframes_t buffer_size=0)
-        : JackRequest(JackRequest::kSetBufferSize), fBufferSize(buffer_size)
+    JackSetBufferSizeRequestData(jack_nframes_t buffer_size=0)
+        : fBufferSize(buffer_size)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        return trans->Read(&fBufferSize, sizeof(jack_nframes_t));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return trans->Write(&fBufferSize, sizeof(jack_nframes_t));
+        return JackRequest::RequestType::kSetBufferSize;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(jack_nframes_t); }
-};
+typedef JackRequestTemplate<JackSetBufferSizeRequestData> JackSetBufferSizeRequest;
 
 /*!
 \brief SetFreeWheel request.
 */
 
-struct JackSetFreeWheelRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackSetFreeWheelRequestData
 {
 
     int fOnOff;
 
-    JackSetFreeWheelRequest(int onoff=0)
-        : JackRequest(JackRequest::kSetFreeWheel), fOnOff(onoff)
+    JackSetFreeWheelRequestData(int onoff=0)
+        : fOnOff(onoff)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        return trans->Read(&fOnOff, sizeof(int));
+        return JackRequest::RequestType::kSetFreeWheel;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return trans->Write(&fOnOff, sizeof(int));
-    }
-    
-    int Size() { return sizeof(int); }
-
-};
+typedef JackRequestTemplate<JackSetFreeWheelRequestData> JackSetFreeWheelRequest;
 
 /*!
 \brief ComputeTotalLatencies request.
 */
 
-struct JackComputeTotalLatenciesRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackComputeTotalLatenciesRequestData
 {
-
-    JackComputeTotalLatenciesRequest()
-        : JackRequest(JackRequest::kComputeTotalLatencies)
-    {}
-
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return 0;
+        return JackRequest::RequestType::kComputeTotalLatencies;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return 0; }
-};
+typedef JackRequestTemplate<JackComputeTotalLatenciesRequestData> JackComputeTotalLatenciesRequest;
 
 /*!
 \brief ReleaseTimebase request.
 */
 
-struct JackReleaseTimebaseRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackReleaseTimebaseRequestData
 {
 
     int fRefNum;
 
-    JackReleaseTimebaseRequest(int refnum=0)
-        : JackRequest(JackRequest::kReleaseTimebase), fRefNum(refnum)
+    JackReleaseTimebaseRequestData(int refnum=0)
+        : fRefNum(refnum)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        return trans->Read(&fRefNum, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        return trans->Write(&fRefNum, sizeof(int));
+        return JackRequest::RequestType::kReleaseTimebase;
     }
-    
-    int Size() { return sizeof(int); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackReleaseTimebaseRequestData> JackReleaseTimebaseRequest;
 
 /*!
 \brief SetTimebaseCallback request.
 */
 
-struct JackSetTimebaseCallbackRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackSetTimebaseCallbackRequestData
 {
 
     int fRefNum;
     int fConditionnal;
 
-    JackSetTimebaseCallbackRequest(int refnum=0, int conditional=0)
-        : JackRequest(JackRequest::kSetTimebaseCallback), fRefNum(refnum), fConditionnal(conditional)
+    JackSetTimebaseCallbackRequestData(int refnum=0, int conditional=0)
+        : fRefNum(refnum), fConditionnal(conditional)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return trans->Read(&fConditionnal, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return trans->Write(&fConditionnal, sizeof(int));
+        return JackRequest::RequestType::kSetTimebaseCallback;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(int); }
-};
+typedef JackRequestTemplate<JackSetTimebaseCallbackRequestData> JackSetTimebaseCallbackRequest;
 
 /*!
 \brief GetInternalClientName request.
 */
 
-struct JackGetInternalClientNameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackGetInternalClientNameRequestData
 {
 
     int fRefNum;
     int fIntRefNum;
 
-    JackGetInternalClientNameRequest(int refnum=0, int int_ref=0)
-            : JackRequest(JackRequest::kGetInternalClientName), fRefNum(refnum), fIntRefNum(int_ref)
+    JackGetInternalClientNameRequestData(int refnum=0, int int_ref=0)
+            : fRefNum(refnum), fIntRefNum(int_ref)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return trans->Read(&fIntRefNum, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return trans->Write(&fIntRefNum, sizeof(int));
+        return JackRequest::RequestType::kGetInternalClientName;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(int); }
-};
+typedef JackRequestTemplate<JackGetInternalClientNameRequestData> JackGetInternalClientNameRequest;
 
 /*!
 \brief GetInternalClient result.
@@ -975,35 +777,27 @@ struct JackGetInternalClientNameResult : public JackResult
 \brief InternalClientHandle request.
 */
 
-struct JackInternalClientHandleRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackInternalClientHandleRequestData
 {
 
     int fRefNum;
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackInternalClientHandleRequest(int refnum=0, const char* client_name="")
-            : JackRequest(JackRequest::kInternalClientHandle), fRefNum(refnum)
+    JackInternalClientHandleRequestData(int refnum=0, const char* client_name="")
+            : fRefNum(refnum)
     {
         memset(fName, 0, sizeof(fName));
         snprintf(fName, sizeof(fName), "%s", client_name);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return trans->Read(&fName, sizeof(fName));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return trans->Write(&fName, sizeof(fName));
+        return JackRequest::RequestType::kInternalClientHandle;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(fName); }
-};
+typedef JackRequestTemplate<JackInternalClientHandleRequestData> JackInternalClientHandleRequest;
 
 /*!
 \brief InternalClientHandle result.
@@ -1044,7 +838,8 @@ struct JackInternalClientHandleResult : public JackResult
 \brief InternalClientLoad request.
 */
 
-struct JackInternalClientLoadRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackInternalClientLoadRequestData
 {
 
 #ifndef MAX_PATH
@@ -1058,8 +853,8 @@ struct JackInternalClientLoadRequest : public JackRequest
     int fOptions;
     int fUUID;
 
-    JackInternalClientLoadRequest(int refnum=0, const char* client_name="", const char* so_name="", const char* objet_data="", int options=0, int uuid=0 )
-            : JackRequest(JackRequest::kInternalClientLoad), fRefNum(refnum), fOptions(options), fUUID(uuid)
+    JackInternalClientLoadRequestData(int refnum=0, const char* client_name="", const char* so_name="", const char* objet_data="", int options=0, int uuid=0 )
+            : fRefNum(refnum), fOptions(options), fUUID(uuid)
     {
         memset(fName, 0, sizeof(fName));
         memset(fDllName, 0, sizeof(fDllName));
@@ -1069,30 +864,13 @@ struct JackInternalClientLoadRequest : public JackRequest
         snprintf(fLoadInitName, sizeof(fLoadInitName), "%s", objet_data);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        CheckRes(trans->Read(&fDllName, sizeof(fDllName)));
-        CheckRes(trans->Read(&fLoadInitName, sizeof(fLoadInitName)));
-        CheckRes(trans->Read(&fUUID, sizeof(int)));
-        return trans->Read(&fOptions, sizeof(int));
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        CheckRes(trans->Write(&fDllName, sizeof(fDllName)));
-        CheckRes(trans->Write(&fLoadInitName, sizeof(fLoadInitName)));
-        CheckRes(trans->Write(&fUUID, sizeof(int)));
-        return trans->Write(&fOptions, sizeof(int));
+        return JackRequest::RequestType::kInternalClientLoad;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int) + sizeof(fName) + sizeof(fDllName) + sizeof(fLoadInitName) + 2 * sizeof(int); }
-};
+typedef JackRequestTemplate<JackInternalClientLoadRequestData> JackInternalClientLoadRequest;
 
 /*!
 \brief InternalClientLoad result.
@@ -1133,32 +911,24 @@ struct JackInternalClientLoadResult : public JackResult
 \brief InternalClientUnload request.
 */
 
-struct JackInternalClientUnloadRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackInternalClientUnloadRequestData
 {
 
     int fRefNum;
     int fIntRefNum;
 
-    JackInternalClientUnloadRequest(int refnum=0, int int_ref=0)
-            : JackRequest(JackRequest::kInternalClientUnload), fRefNum(refnum), fIntRefNum(int_ref)
+    JackInternalClientUnloadRequestData(int refnum=0, int int_ref=0)
+            : fRefNum(refnum), fIntRefNum(int_ref)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return trans->Read(&fIntRefNum, sizeof(int));
+        return JackRequest::RequestType::kInternalClientUnload;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return trans->Write(&fIntRefNum, sizeof(int));
-    }
-    
-    int Size() { return sizeof(int) + sizeof(int); }
-};
+typedef JackRequestTemplate<JackInternalClientUnloadRequestData> JackInternalClientUnloadRequest;
 
 /*!
 \brief InternalClientLoad result.
@@ -1196,38 +966,26 @@ struct JackInternalClientUnloadResult : public JackResult
 \brief ClientNotification request.
 */
 
-struct JackClientNotificationRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackClientNotificationRequestData
 {
 
     int fRefNum;
     int fNotify;
     int fValue;
 
-    JackClientNotificationRequest(int refnum=0, int notify=0, int value=0)
-            : JackRequest(JackRequest::kNotification), fRefNum(refnum), fNotify(notify), fValue(value)
+    JackClientNotificationRequestData(int refnum=0, int notify=0, int value=0)
+            : fRefNum(refnum), fNotify(notify), fValue(value)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        CheckRes(trans->Read(&fNotify, sizeof(int)));
-        CheckRes(trans->Read(&fValue, sizeof(int)));
-        return 0;
-    }
 
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        CheckRes(trans->Write(&fNotify, sizeof(int)));
-        CheckRes(trans->Write(&fValue, sizeof(int)));
-        return 0;
+        return JackRequest::RequestType::kNotification;
     }
-    
-    int Size() { return 3 * sizeof(int); }
+} POST_PACKED_STRUCTURE;
 
-};
+typedef JackRequestTemplate<JackClientNotificationRequestData> JackClientNotificationRequest;
 
 struct JackSessionCommand
 {
@@ -1347,15 +1105,16 @@ struct JackSessionNotifyResult : public JackResult
 \brief SessionNotify request.
 */
 
-struct JackSessionNotifyRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackSessionNotifyRequestData
 {
     char fPath[JACK_MESSAGE_SIZE+1];
     char fDst[JACK_CLIENT_NAME_SIZE+1];
     jack_session_event_type_t fEventType;
     int fRefNum;
 
-    JackSessionNotifyRequest(int refnum=0, const char* path="", jack_session_event_type_t type=JackSessionSave, const char* dst=NULL)
-            : JackRequest(JackRequest::kSessionNotify), fEventType(type), fRefNum(refnum)
+    JackSessionNotifyRequestData(int refnum=0, const char* path="", jack_session_event_type_t type=JackSessionSave, const char* dst=NULL)
+            : fEventType(type), fRefNum(refnum)
     {
         memset(fPath, 0, sizeof(fPath));
         memset(fDst, 0, sizeof(fDst));
@@ -1367,54 +1126,30 @@ struct JackSessionNotifyRequest : public JackRequest
         }
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(fRefNum)));
-        CheckRes(trans->Read(&fPath, sizeof(fPath)));
-        CheckRes(trans->Read(&fDst, sizeof(fDst)));
-        CheckRes(trans->Read(&fEventType, sizeof(fEventType)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(fRefNum)));
-        CheckRes(trans->Write(&fPath, sizeof(fPath)));
-        CheckRes(trans->Write(&fDst, sizeof(fDst)));
-        CheckRes(trans->Write(&fEventType, sizeof(fEventType)));
-        return 0;
+        return JackRequest::RequestType::kSessionNotify;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fRefNum) + sizeof(fPath) + sizeof(fDst) + sizeof(fEventType); }
-};
+typedef JackRequestTemplate<JackSessionNotifyRequestData> JackSessionNotifyRequest;
 
-struct JackSessionReplyRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackSessionReplyRequestData
 {
     int fRefNum;
 
-    JackSessionReplyRequest(int refnum=0)
-            : JackRequest(JackRequest::kSessionReply), fRefNum(refnum)
+    JackSessionReplyRequestData(int refnum=0)
+            : fRefNum(refnum)
     {}
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fRefNum, sizeof(int)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fRefNum, sizeof(int)));
-        return 0;
+        return JackRequest::RequestType::kSessionReply;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(int); }
-    
-};
+typedef JackRequestTemplate<JackSessionReplyRequestData> JackSessionReplyRequest;
 
 struct JackClientNameResult : public JackResult
 {
@@ -1478,170 +1213,111 @@ struct JackUUIDResult : public JackResult
 
 };
 
-struct JackGetUUIDRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackGetUUIDRequestData
 {
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackGetUUIDRequest(const char* client_name="")
-            : JackRequest(JackRequest::kGetUUIDByClient)
+    JackGetUUIDRequestData(const char* client_name="")
     {
         memset(fName, 0, sizeof(fName));
         strncpy(fName, client_name, sizeof(fName)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        return 0;
+        return JackRequest::RequestType::kGetUUIDByClient;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fName); }
-    
-};
+typedef JackRequestTemplate<JackGetUUIDRequestData> JackGetUUIDRequest;
 
-struct JackGetClientNameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackGetClientNameRequestData
 {
     char fUUID[JACK_UUID_SIZE];
 
-    JackGetClientNameRequest(const char* uuid="")
-            : JackRequest(JackRequest::kGetClientByUUID)
+    JackGetClientNameRequestData(const char* uuid="")
     {
         memset(fUUID, 0, sizeof(fUUID));
         strncpy(fUUID, uuid, sizeof(fUUID)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {   
-        CheckSize();
-        CheckRes(trans->Read(&fUUID, sizeof(fUUID)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fUUID, sizeof(fUUID)));
-        return 0;
+        return JackRequest::RequestType::kGetClientByUUID;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fUUID); }
-    
-};
+typedef JackRequestTemplate<JackGetClientNameRequestData> JackGetClientNameRequest;
 
-struct JackReserveNameRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackReserveNameRequestData
 {
     int  fRefNum;
     char fName[JACK_CLIENT_NAME_SIZE+1];
     char fUUID[JACK_UUID_SIZE];
 
-    JackReserveNameRequest(int refnum=0, const char *name="", const char* uuid="")
-            : JackRequest(JackRequest::kReserveClientName), fRefNum(refnum)
+    JackReserveNameRequestData(int refnum=0, const char *name="", const char* uuid="")
+            : fRefNum(refnum)
     {
         memset(fName, 0, sizeof(fName));
         memset(fUUID, 0, sizeof(fUUID));
         strncpy(fName, name, sizeof(fName)-1);
         strncpy(fUUID, uuid, sizeof(fUUID)-1);
     }
+    
 
-    int Read(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckSize();
-        CheckRes(trans->Read(&fUUID, sizeof(fUUID)));
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        CheckRes(trans->Read(&fRefNum, sizeof(fRefNum)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fUUID, sizeof(fUUID)));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        CheckRes(trans->Write(&fRefNum, sizeof(fRefNum)));
-        return 0;
+        return JackRequest::RequestType::kReserveClientName;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fUUID) + sizeof(fName) + sizeof(fRefNum); }
-    
-};
+typedef JackRequestTemplate<JackReserveNameRequestData> JackReserveNameRequest;
 
-struct JackClientHasSessionCallbackRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackClientHasSessionCallbackRequestData
 {
     char fName[JACK_CLIENT_NAME_SIZE+1];
 
-    JackClientHasSessionCallbackRequest(const char *name="")
-            : JackRequest(JackRequest::kClientHasSessionCallback)
+    JackClientHasSessionCallbackRequestData(const char *name="")
     {
         memset(fName, 0, sizeof(fName));
         strncpy(fName, name, sizeof(fName)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fName, sizeof(fName)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fName, sizeof(fName)));
-        return 0;
+        return JackRequest::RequestType::kClientHasSessionCallback;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fName); }
-    
-};
+typedef JackRequestTemplate<JackClientHasSessionCallbackRequestData> JackClientHasSessionCallbackRequest;
 
 
-struct JackPropertyChangeNotifyRequest : public JackRequest
+PRE_PACKED_STRUCTURE
+struct JackPropertyChangeNotifyRequestData
 {
     jack_uuid_t fSubject;
     char fKey[JACK_UUID_STRING_SIZE];
     jack_property_change_t fChange;
 
-    JackPropertyChangeNotifyRequest() : fChange((jack_property_change_t)0)
-    {
-        jack_uuid_clear(&fSubject);
-        memset(fKey, 0, sizeof(fKey));
-    }
-    JackPropertyChangeNotifyRequest(jack_uuid_t subject, const char* key, jack_property_change_t change)
-        : JackRequest(JackRequest::kPropertyChangeNotify), fChange(change)
+    JackPropertyChangeNotifyRequestData(jack_uuid_t subject=0, const char* key="", jack_property_change_t change=(jack_property_change_t)0)
+        : fChange(change)
     {
         jack_uuid_copy(&fSubject, subject);
         memset(fKey, 0, sizeof(fKey));
         strncpy(fKey, key, sizeof(fKey)-1);
     }
 
-    int Read(detail::JackChannelTransactionInterface* trans)
+    static JackRequest::RequestType Type()
     {
-        CheckSize();
-        CheckRes(trans->Read(&fSubject, sizeof(fSubject)));
-        CheckRes(trans->Read(&fKey, sizeof(fKey)));
-        CheckRes(trans->Read(&fChange, sizeof(fChange)));
-        return 0;
-    }
-
-    int Write(detail::JackChannelTransactionInterface* trans)
-    {
-        CheckRes(JackRequest::Write(trans, Size()));
-        CheckRes(trans->Write(&fSubject, sizeof(fSubject)));
-        CheckRes(trans->Write(&fKey, sizeof(fKey)));
-        CheckRes(trans->Write(&fChange, sizeof(fChange)));
-        return 0;
+        return JackRequest::RequestType::kPropertyChangeNotify;
     }
+} POST_PACKED_STRUCTURE;
 
-    int Size() { return sizeof(fSubject) + sizeof(fKey) + sizeof(fChange); }
-};
+typedef JackRequestTemplate<JackPropertyChangeNotifyRequestData> JackPropertyChangeNotifyRequest;
 
 /*!
 \brief ClientNotification.
diff --git a/common/JackRequestDecoder.cpp b/common/JackRequestDecoder.cpp
index 3c18f964..9911d977 100644
--- a/common/JackRequestDecoder.cpp
+++ b/common/JackRequestDecoder.cpp
@@ -31,8 +31,8 @@ namespace Jack
 {
 
 #define CheckRead(req, socket)          { if (req.Read(socket) <  0) { jack_error("CheckRead error"); return -1; } }
-#define CheckWriteName(error, socket)   { if (res.Write(socket) < 0) { jack_error("%s write error name = %s", error, req.fName); } }
-#define CheckWriteRefNum(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error ref = %d", error, req.fRefNum); } }
+#define CheckWriteName(error, socket)   { if (res.Write(socket) < 0) { jack_error("%s write error name = %s", error, req.d.fName); } }
+#define CheckWriteRefNum(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error ref = %d", error, req.d.fRefNum); } }
 #define CheckWrite(error, socket)       { if (res.Write(socket) < 0) { jack_error("%s write error", error); } }
 
 JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler)
@@ -54,10 +54,10 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackClientCheckRequest req;
             JackClientCheckResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
+            res.fResult = fServer->GetEngine()->ClientCheck(req.d.fName, req.d.fUUID, res.fName, req.d.fProtocol, req.d.fOptions, &res.fStatus);
             CheckWriteName("JackRequest::ClientCheck", socket);
             // Atomic ClientCheck followed by ClientOpen on same socket
-            if (req.fOpen) {
+            if (req.d.fOpen) {
                 JackRequest::RequestType type;
                 JackRequest::ReadType(socket, type);
                 return HandleRequest(socket, type);
@@ -80,9 +80,9 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackClientCloseRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
+            res.fResult = fServer->GetEngine()->ClientExternalClose(req.d.fRefNum);
             CheckWriteRefNum("JackRequest::ClientClose", socket);
-            fHandler->ClientRemove(socket, req.fRefNum);
+            fHandler->ClientRemove(socket, req.d.fRefNum);
             // Will cause the wrapping thread to stop
             return -1;
         }
@@ -92,7 +92,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackResult res;
             jack_log("JackRequest::ActivateClient");
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
+            res.fResult = fServer->GetEngine()->ClientActivate(req.d.fRefNum, req.d.fIsRealTime);
             CheckWriteRefNum("JackRequest::ActivateClient", socket);
             break;
         }
@@ -102,7 +102,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackDeactivateRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
+            res.fResult = fServer->GetEngine()->ClientDeactivate(req.d.fRefNum);
             CheckWriteRefNum("JackRequest::DeactivateClient", socket);
             break;
         }
@@ -112,7 +112,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortRegisterRequest req;
             JackPortRegisterResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
+            res.fResult = fServer->GetEngine()->PortRegister(req.d.fRefNum, req.d.fName, req.d.fPortType, req.d.fFlags, req.d.fBufferSize, &res.fPortIndex);
             CheckWriteRefNum("JackRequest::RegisterPort", socket);
             break;
         }
@@ -122,7 +122,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortUnRegisterRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
+            res.fResult = fServer->GetEngine()->PortUnRegister(req.d.fRefNum, req.d.fPortIndex);
             CheckWriteRefNum("JackRequest::UnRegisterPort", socket);
             break;
         }
@@ -132,7 +132,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortConnectNameRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
+            res.fResult = fServer->GetEngine()->PortConnect(req.d.fRefNum, req.d.fSrc, req.d.fDst);
             CheckWriteRefNum("JackRequest::ConnectNamePorts", socket);
             break;
         }
@@ -142,7 +142,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortDisconnectNameRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
+            res.fResult = fServer->GetEngine()->PortDisconnect(req.d.fRefNum, req.d.fSrc, req.d.fDst);
             CheckWriteRefNum("JackRequest::DisconnectNamePorts", socket);
             break;
         }
@@ -152,7 +152,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortConnectRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
+            res.fResult = fServer->GetEngine()->PortConnect(req.d.fRefNum, req.d.fSrc, req.d.fDst);
             CheckWriteRefNum("JackRequest::ConnectPorts", socket);
             break;
         }
@@ -162,7 +162,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortDisconnectRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
+            res.fResult = fServer->GetEngine()->PortDisconnect(req.d.fRefNum, req.d.fSrc, req.d.fDst);
             CheckWriteRefNum("JackRequest::DisconnectPorts", socket);
             break;
         }
@@ -172,7 +172,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackPortRenameRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
+            res.fResult = fServer->GetEngine()->PortRename(req.d.fRefNum, req.d.fPort, req.d.fName);
             CheckWriteRefNum("JackRequest::PortRename", socket);
             break;
         }
@@ -182,7 +182,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackSetBufferSizeRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->SetBufferSize(req.fBufferSize);
+            res.fResult = fServer->SetBufferSize(req.d.fBufferSize);
             CheckWrite("JackRequest::SetBufferSize", socket);
             break;
         }
@@ -192,7 +192,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackSetFreeWheelRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->SetFreewheel(req.fOnOff);
+            res.fResult = fServer->SetFreewheel(req.d.fOnOff);
             CheckWrite("JackRequest::SetFreeWheel", socket);
             break;
         }
@@ -212,7 +212,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackReleaseTimebaseRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->ReleaseTimebase(req.fRefNum);
+            res.fResult = fServer->ReleaseTimebase(req.d.fRefNum);
             CheckWriteRefNum("JackRequest::ReleaseTimebase", socket);
             break;
         }
@@ -222,7 +222,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackSetTimebaseCallbackRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
+            res.fResult = fServer->SetTimebaseCallback(req.d.fRefNum, req.d.fConditionnal);
             CheckWriteRefNum("JackRequest::SetTimebaseCallback", socket);
             break;
         }
@@ -232,7 +232,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackGetInternalClientNameRequest req;
             JackGetInternalClientNameResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
+            res.fResult = fServer->GetEngine()->GetInternalClientName(req.d.fIntRefNum, res.fName);
             CheckWriteRefNum("JackRequest::GetInternalClientName", socket);
             break;
         }
@@ -242,7 +242,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackInternalClientHandleRequest req;
             JackInternalClientHandleResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
+            res.fResult = fServer->GetEngine()->InternalClientHandle(req.d.fName, &res.fStatus, &res.fIntRefNum);
             CheckWriteRefNum("JackRequest::InternalClientHandle", socket);
             break;
         }
@@ -252,7 +252,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackInternalClientLoadRequest req;
             JackInternalClientLoadResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
+            res.fResult = fServer->InternalClientLoad1(req.d.fName, req.d.fDllName, req.d.fLoadInitName, req.d.fOptions, &res.fIntRefNum, req.d.fUUID, &res.fStatus);
             CheckWriteName("JackRequest::InternalClientLoad", socket);
             break;
         }
@@ -262,7 +262,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackInternalClientUnloadRequest req;
             JackInternalClientUnloadResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
+            res.fResult = fServer->GetEngine()->InternalClientUnload(req.d.fIntRefNum, &res.fStatus);
             CheckWriteRefNum("JackRequest::InternalClientUnload", socket);
             break;
         }
@@ -271,11 +271,11 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             jack_log("JackRequest::Notification");
             JackClientNotificationRequest req;
             CheckRead(req, socket);
-            if (req.fNotify == kQUIT) {
+            if (req.d.fNotify == kQUIT) {
                 jack_log("JackRequest::Notification kQUIT");
                 throw JackQuitException();
             } else {
-                fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
+                fServer->Notify(req.d.fRefNum, req.d.fNotify, req.d.fValue);
             }
             break;
         }
@@ -284,7 +284,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             jack_log("JackRequest::SessionNotify");
             JackSessionNotifyRequest req;
             CheckRead(req, socket);
-            fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL);
+            fServer->GetEngine()->SessionNotify(req.d.fRefNum, req.d.fDst, req.d.fEventType, req.d.fPath, socket, NULL);
             break;
         }
 
@@ -293,7 +293,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackSessionReplyRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->SessionReply(req.fRefNum);
+            res.fResult = fServer->GetEngine()->SessionReply(req.d.fRefNum);
             CheckWrite("JackRequest::SessionReply", socket);
             break;
         }
@@ -303,7 +303,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackGetClientNameRequest req;
             JackClientNameResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName);
+            res.fResult = fServer->GetEngine()->GetClientNameForUUID(req.d.fUUID, res.fName);
             CheckWrite("JackRequest::GetClientByUUID", socket);
             break;
         }
@@ -313,7 +313,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackGetUUIDRequest req;
             JackUUIDResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID);
+            res.fResult = fServer->GetEngine()->GetUUIDForClientName(req.d.fName, res.fUUID);
             CheckWrite("JackRequest::GetUUIDByClient", socket);
             break;
         }
@@ -323,7 +323,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackReserveNameRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID);
+            res.fResult = fServer->GetEngine()->ReserveClientName(req.d.fName, req.d.fUUID);
             CheckWrite("JackRequest::ReserveClientName", socket);
             break;
         }
@@ -333,7 +333,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             JackClientHasSessionCallbackRequest req;
             JackResult res;
             CheckRead(req, socket);
-            res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.fName);
+            res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.d.fName);
             CheckWrite("JackRequest::ClientHasSessionCallback", socket);
             break;
         }
@@ -342,7 +342,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
             jack_log("JackRequest::PropertyChangeNotify");
             JackPropertyChangeNotifyRequest req;
             CheckRead(req, socket);
-            fServer->GetEngine()->PropertyChangeNotify(req.fSubject, req.fKey, req.fChange);
+            fServer->GetEngine()->PropertyChangeNotify(req.d.fSubject, req.d.fKey, req.d.fChange);
             break;
         }
 
diff --git a/common/JackRequestDecoder.h b/common/JackRequestDecoder.h
index f23caede..852ded0b 100644
--- a/common/JackRequestDecoder.h
+++ b/common/JackRequestDecoder.h
@@ -26,7 +26,9 @@ namespace Jack
 {
 
 class JackServer;
-struct JackClientOpenRequest;
+template<class DATA> struct JackRequestTemplate;
+struct JackClientOpenRequestData;
+typedef JackRequestTemplate<JackClientOpenRequestData> JackClientOpenRequest;
 struct JackClientOpenResult;
 
 struct JackClientHandlerInterface {
diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp
index 04cd2385..4357f00f 100644
--- a/posix/JackSocketServerChannel.cpp
+++ b/posix/JackSocketServerChannel.cpp
@@ -129,7 +129,7 @@ int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux)
 void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res)
 {
     int refnum = -1;
-    res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
+    res->fResult = fServer->GetEngine()->ClientExternalOpen(req->d.fName, req->d.fPID, req->d.fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
     if (res->fResult == 0) {
         JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
         assert(socket);

From 793465d5f388ee1b2b069cf0951721fd05f437e8 Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Wed, 24 Oct 2018 13:57:04 +0200
Subject: [PATCH 7/8] JackRequest: Add start marker and verify it on read

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackRequest.h | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/common/JackRequest.h b/common/JackRequest.h
index 21364db6..6287ce11 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -93,9 +93,27 @@ struct JackRequest
         kPropertyChangeNotify = 40
     };
 
+    static const int StartMarker = 'R' | ('e' << 8) | ('q' << 16) | ('S' << 24);
+
     static int ReadType(detail::JackChannelTransactionInterface* trans, RequestType& type)
     {
         type = (RequestType)0;
+
+        do {
+            PRE_PACKED_STRUCTURE
+            union {
+                int i;
+                uint8_t b[sizeof(i)];
+            } POST_PACKED_STRUCTURE start;
+
+            CheckRes(trans->Read(&start.i, sizeof(StartMarker)));
+            if (start.i != StartMarker) {
+                jack_error("Request start marker not found. Ignoring %02x %02x %02x %02x ",
+                           start.b[0], start.b[1], start.b[2], start.b[3]);
+                continue;
+            }
+        } while (false);
+
         CheckRes(trans->Read(&type, sizeof(RequestType)));
         return 0;
     }
@@ -112,6 +130,7 @@ template<class DATA>
 struct JackRequestMessage
 {
 protected:
+    const int fStart = JackRequest::StartMarker;
     const JackRequest::RequestType fType;
     const int fSize;
 public:
@@ -120,7 +139,7 @@ struct JackRequestMessage
 protected:
     template<typename... Args>
         JackRequestMessage(Args&... args) : fType(DATA::Type()),
-            fSize(sizeof(JackRequestMessage<DATA>) - sizeof(fType) - sizeof(fSize)),
+            fSize(sizeof(JackRequestMessage<DATA>) - sizeof(fStart) - sizeof(fType) - sizeof(fSize)),
             d(args...)
         {}
 

From a61fe232fead8c7657e1b6747cbc9dc653531f55 Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Wed, 24 Oct 2018 14:08:28 +0200
Subject: [PATCH 8/8] JackReuqest: Add End marker and verify them on read

Without this marker partly written messages cannot be detected before
processing them.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
---
 common/JackRequest.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/common/JackRequest.h b/common/JackRequest.h
index 6287ce11..17f1cce4 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -94,6 +94,7 @@ struct JackRequest
     };
 
     static const int StartMarker = 'R' | ('e' << 8) | ('q' << 16) | ('S' << 24);
+    static const int EndMarker   = 'R' | ('e' << 8) | ('q' << 16) | ('E' << 24);
 
     static int ReadType(detail::JackChannelTransactionInterface* trans, RequestType& type)
     {
@@ -135,8 +136,9 @@ struct JackRequestMessage
     const int fSize;
 public:
     DATA d;
-
 protected:
+    int fEnd = JackRequest::EndMarker;
+
     template<typename... Args>
         JackRequestMessage(Args&... args) : fType(DATA::Type()),
             fSize(sizeof(JackRequestMessage<DATA>) - sizeof(fStart) - sizeof(fType) - sizeof(fSize)),
@@ -152,7 +154,16 @@ struct JackRequestMessage
                 return -1;
             }
 
+            /* Size also contains fEnd */
             CheckRes(trans->Read(&d, fSize));
+            if (fEnd != JackRequest::EndMarker) {
+                jack_error("Request end marker not found (exp %08x act %08x). Request of type %d will be ignored!",
+                           JackRequest::EndMarker, fEnd, fType);
+
+                /* no need to sync here. Will be done by JackRequest::ReadType() */
+                return -1;
+            }
+
             return 0;
         }
 
openSUSE Build Service is sponsored by