mirror of
https://github.com/darlinghq/darlingserver.git
synced 2024-11-23 04:19:44 +00:00
Add reply-push synchronization
This is used to avoid the server reading incorrect/corrupted reply contents for pushed replies. This was happening because clients were sending the push-reply call with the pointer to the message contents, but they were immediately returning after sending it. This led to a race condition in which the server would sometimes read the data after the client had already overwritten/discarded said data.
This commit is contained in:
parent
700d89812c
commit
4f001e2a34
15
src/call.cpp
15
src/call.cpp
@ -133,6 +133,14 @@ std::shared_ptr<DarlingServer::Call> DarlingServer::Call::callFromMessage(Messag
|
|||||||
auto pushReplyCall = reinterpret_cast<const dserver_rpc_call_push_reply_t*>(requestMessage.data().data());
|
auto pushReplyCall = reinterpret_cast<const dserver_rpc_call_push_reply_t*>(requestMessage.data().data());
|
||||||
Message replyToSave(pushReplyCall->reply_size, 0);
|
Message replyToSave(pushReplyCall->reply_size, 0);
|
||||||
|
|
||||||
|
// extract the reply-push synchronization pipe
|
||||||
|
auto pipeDesc = requestMessage.extractDescriptorAtIndex(requestMessage.descriptors().size() - 1);
|
||||||
|
char tmp = 1;
|
||||||
|
|
||||||
|
if (pipeDesc < 0) {
|
||||||
|
throw std::runtime_error("Failed to extract reply-push synchronization pipe");
|
||||||
|
}
|
||||||
|
|
||||||
if (!process->readMemory(pushReplyCall->reply, replyToSave.data().data(), pushReplyCall->reply_size)) {
|
if (!process->readMemory(pushReplyCall->reply, replyToSave.data().data(), pushReplyCall->reply_size)) {
|
||||||
throw std::runtime_error("Failed to read client-pushed reply body");
|
throw std::runtime_error("Failed to read client-pushed reply body");
|
||||||
}
|
}
|
||||||
@ -160,7 +168,12 @@ std::shared_ptr<DarlingServer::Call> DarlingServer::Call::callFromMessage(Messag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callLog.debug() << *thread << ": Saved client-pushed reply" << callLog.endLog;
|
callLog.debug() << *thread << ": Saved client-pushed reply (" << ((thread->_pendingSavedReply) ? "pending" : "normal") << ")" << callLog.endLog;
|
||||||
|
|
||||||
|
// write a byte to the pipe so the caller can continue
|
||||||
|
write(pipeDesc, &tmp, sizeof(tmp));
|
||||||
|
// and close it
|
||||||
|
close(pipeDesc);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user