Browse Source

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.

When using POST_PACKED_STRUCTURE JackRequest structures would be
aligned to 64b on aarch64 due to packing is disabled on aarch64 in
systemdeps, this causes issues with decoding some JackRequests. To
overcome this issue by defining POST_PACKED_STRUCTURE_FORCED_AARCH64
which is not undefed for aarch64.

It is only used for JackRequest structures, since enabling for all uses
cases in Jack jackd startup failed with "Bus Error".

Change-Id: I9460840f11870bb699744da09a5dcacddb828d2c
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
pull/386/head
Timo Wischer Timo Wischer 7 years ago
parent
commit
9d094d9a35
5 changed files with 268 additions and 590 deletions
  1. +3
    -3
      common/JackGenericClientChannel.cpp
  2. +229
    -553
      common/JackRequest.h
  3. +32
    -32
      common/JackRequestDecoder.cpp
  4. +3
    -1
      common/JackRequestDecoder.h
  5. +1
    -1
      posix/JackSocketServerChannel.cpp

+ 3
- 3
common/JackGenericClientChannel.cpp View File

@@ -60,13 +60,13 @@ void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res,
} }
if (req->Write(fRequest) < 0) { 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; *result = -1;
return; return;
} }


if (res->Read(fRequest) < 0) { 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; *result = -1;
return; return;
} }
@@ -90,7 +90,7 @@ void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res
} }
if (req->Write(fRequest) < 0) { 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; *result = -1;
} else { } else {
*result = 0; *result = 0;


+ 229
- 553
common/JackRequest.h
File diff suppressed because it is too large
View File


+ 32
- 32
common/JackRequestDecoder.cpp View File

@@ -31,8 +31,8 @@ namespace Jack
{ {


#define CheckRead(req, socket) { if (req.Read(socket) < 0) { jack_error("CheckRead error"); return -1; } } #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); } } #define CheckWrite(error, socket) { if (res.Write(socket) < 0) { jack_error("%s write error", error); } }


JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler) JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler)
@@ -54,10 +54,10 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackClientCheckRequest req; JackClientCheckRequest req;
JackClientCheckResult res; JackClientCheckResult res;
CheckRead(req, socket); 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); CheckWriteName("JackRequest::ClientCheck", socket);
// Atomic ClientCheck followed by ClientOpen on same socket // Atomic ClientCheck followed by ClientOpen on same socket
if (req.fOpen) {
if (req.d.fOpen) {
JackRequest::RequestType type; JackRequest::RequestType type;
JackRequest::ReadType(socket, type); JackRequest::ReadType(socket, type);
return HandleRequest(socket, type); return HandleRequest(socket, type);
@@ -80,9 +80,9 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackClientCloseRequest req; JackClientCloseRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
res.fResult = fServer->GetEngine()->ClientExternalClose(req.d.fRefNum);
CheckWriteRefNum("JackRequest::ClientClose", socket); CheckWriteRefNum("JackRequest::ClientClose", socket);
fHandler->ClientRemove(socket, req.fRefNum);
fHandler->ClientRemove(socket, req.d.fRefNum);
// Will cause the wrapping thread to stop // Will cause the wrapping thread to stop
return -1; return -1;
} }
@@ -92,7 +92,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackResult res; JackResult res;
jack_log("JackRequest::ActivateClient"); jack_log("JackRequest::ActivateClient");
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::ActivateClient", socket);
break; break;
} }
@@ -102,7 +102,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackDeactivateRequest req; JackDeactivateRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
res.fResult = fServer->GetEngine()->ClientDeactivate(req.d.fRefNum);
CheckWriteRefNum("JackRequest::DeactivateClient", socket); CheckWriteRefNum("JackRequest::DeactivateClient", socket);
break; break;
} }
@@ -112,7 +112,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortRegisterRequest req; JackPortRegisterRequest req;
JackPortRegisterResult res; JackPortRegisterResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::RegisterPort", socket);
break; break;
} }
@@ -122,7 +122,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortUnRegisterRequest req; JackPortUnRegisterRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::UnRegisterPort", socket);
break; break;
} }
@@ -132,7 +132,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortConnectNameRequest req; JackPortConnectNameRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::ConnectNamePorts", socket);
break; break;
} }
@@ -142,7 +142,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortDisconnectNameRequest req; JackPortDisconnectNameRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::DisconnectNamePorts", socket);
break; break;
} }
@@ -152,7 +152,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortConnectRequest req; JackPortConnectRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::ConnectPorts", socket);
break; break;
} }
@@ -162,7 +162,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortDisconnectRequest req; JackPortDisconnectRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::DisconnectPorts", socket);
break; break;
} }
@@ -172,7 +172,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackPortRenameRequest req; JackPortRenameRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::PortRename", socket);
break; break;
} }
@@ -182,7 +182,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackSetBufferSizeRequest req; JackSetBufferSizeRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->SetBufferSize(req.fBufferSize);
res.fResult = fServer->SetBufferSize(req.d.fBufferSize);
CheckWrite("JackRequest::SetBufferSize", socket); CheckWrite("JackRequest::SetBufferSize", socket);
break; break;
} }
@@ -192,7 +192,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackSetFreeWheelRequest req; JackSetFreeWheelRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->SetFreewheel(req.fOnOff);
res.fResult = fServer->SetFreewheel(req.d.fOnOff);
CheckWrite("JackRequest::SetFreeWheel", socket); CheckWrite("JackRequest::SetFreeWheel", socket);
break; break;
} }
@@ -212,7 +212,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackReleaseTimebaseRequest req; JackReleaseTimebaseRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->ReleaseTimebase(req.fRefNum);
res.fResult = fServer->ReleaseTimebase(req.d.fRefNum);
CheckWriteRefNum("JackRequest::ReleaseTimebase", socket); CheckWriteRefNum("JackRequest::ReleaseTimebase", socket);
break; break;
} }
@@ -222,7 +222,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackSetTimebaseCallbackRequest req; JackSetTimebaseCallbackRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::SetTimebaseCallback", socket);
break; break;
} }
@@ -232,7 +232,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackGetInternalClientNameRequest req; JackGetInternalClientNameRequest req;
JackGetInternalClientNameResult res; JackGetInternalClientNameResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::GetInternalClientName", socket);
break; break;
} }
@@ -242,7 +242,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackInternalClientHandleRequest req; JackInternalClientHandleRequest req;
JackInternalClientHandleResult res; JackInternalClientHandleResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::InternalClientHandle", socket);
break; break;
} }
@@ -252,7 +252,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackInternalClientLoadRequest req; JackInternalClientLoadRequest req;
JackInternalClientLoadResult res; JackInternalClientLoadResult res;
CheckRead(req, socket); 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); CheckWriteName("JackRequest::InternalClientLoad", socket);
break; break;
} }
@@ -262,7 +262,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackInternalClientUnloadRequest req; JackInternalClientUnloadRequest req;
JackInternalClientUnloadResult res; JackInternalClientUnloadResult res;
CheckRead(req, socket); 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); CheckWriteRefNum("JackRequest::InternalClientUnload", socket);
break; break;
} }
@@ -271,11 +271,11 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
jack_log("JackRequest::Notification"); jack_log("JackRequest::Notification");
JackClientNotificationRequest req; JackClientNotificationRequest req;
CheckRead(req, socket); CheckRead(req, socket);
if (req.fNotify == kQUIT) {
if (req.d.fNotify == kQUIT) {
jack_log("JackRequest::Notification kQUIT"); jack_log("JackRequest::Notification kQUIT");
throw JackQuitException(); throw JackQuitException();
} else { } else {
fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
fServer->Notify(req.d.fRefNum, req.d.fNotify, req.d.fValue);
} }
break; break;
} }
@@ -284,7 +284,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
jack_log("JackRequest::SessionNotify"); jack_log("JackRequest::SessionNotify");
JackSessionNotifyRequest req; JackSessionNotifyRequest req;
CheckRead(req, socket); 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; break;
} }


@@ -293,7 +293,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackSessionReplyRequest req; JackSessionReplyRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->GetEngine()->SessionReply(req.fRefNum);
res.fResult = fServer->GetEngine()->SessionReply(req.d.fRefNum);
CheckWrite("JackRequest::SessionReply", socket); CheckWrite("JackRequest::SessionReply", socket);
break; break;
} }
@@ -303,7 +303,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackGetClientNameRequest req; JackGetClientNameRequest req;
JackClientNameResult res; JackClientNameResult res;
CheckRead(req, socket); 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); CheckWrite("JackRequest::GetClientByUUID", socket);
break; break;
} }
@@ -313,7 +313,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackGetUUIDRequest req; JackGetUUIDRequest req;
JackUUIDResult res; JackUUIDResult res;
CheckRead(req, socket); 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); CheckWrite("JackRequest::GetUUIDByClient", socket);
break; break;
} }
@@ -323,7 +323,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackReserveNameRequest req; JackReserveNameRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); 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); CheckWrite("JackRequest::ReserveClientName", socket);
break; break;
} }
@@ -333,7 +333,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
JackClientHasSessionCallbackRequest req; JackClientHasSessionCallbackRequest req;
JackResult res; JackResult res;
CheckRead(req, socket); CheckRead(req, socket);
res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.fName);
res.fResult = fServer->GetEngine()->ClientHasSessionCallback(req.d.fName);
CheckWrite("JackRequest::ClientHasSessionCallback", socket); CheckWrite("JackRequest::ClientHasSessionCallback", socket);
break; break;
} }
@@ -342,7 +342,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
jack_log("JackRequest::PropertyChangeNotify"); jack_log("JackRequest::PropertyChangeNotify");
JackPropertyChangeNotifyRequest req; JackPropertyChangeNotifyRequest req;
CheckRead(req, socket); 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; break;
} }




+ 3
- 1
common/JackRequestDecoder.h View File

@@ -26,7 +26,9 @@ namespace Jack
{ {


class JackServer; class JackServer;
struct JackClientOpenRequest;
template<class DATA> struct JackRequestTemplate;
struct JackClientOpenRequestData;
typedef JackRequestTemplate<JackClientOpenRequestData> JackClientOpenRequest;
struct JackClientOpenResult; struct JackClientOpenResult;


struct JackClientHandlerInterface { struct JackClientHandlerInterface {


+ 1
- 1
posix/JackSocketServerChannel.cpp View File

@@ -128,7 +128,7 @@ int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux)
void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res) void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res)
{ {
int refnum = -1; 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) { if (res->fResult == 0) {
JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux); JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
assert(socket); assert(socket);


Loading…
Cancel
Save