summaryrefslogtreecommitdiffstats
path: root/common/resourceaccess.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-02 17:22:24 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-02 17:22:24 +0200
commitf46e1f6775b5e052ebe12f9db2eb211d1622274b (patch)
tree4a2fcd6ef65756e04f8ece8cd92e8f29f9707b9a /common/resourceaccess.cpp
parent93f224b1f6ca0a69a5c4610466baa43b43d042e3 (diff)
downloadsink-f46e1f6775b5e052ebe12f9db2eb211d1622274b.tar.gz
sink-f46e1f6775b5e052ebe12f9db2eb211d1622274b.zip
ResourceAccess: copy the buffer before capturing it in the lambda.
It's lifetime is limited to the end of the function, so we have to copy it before. I switched to QByteArray because it simplifies the code and shouldn't really cost anything, additionally the implicit sharing makes copies cheap. This patch incurs the cost of always copying the buffer instead of writing straight to the socket, but we probably anyways want to keep a copy around, and if it would indeed be a performance issues (I doubt it), we could still optimize that copy away.
Diffstat (limited to 'common/resourceaccess.cpp')
-rw-r--r--common/resourceaccess.cpp27
1 files changed, 10 insertions, 17 deletions
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index 22d7d97..7320e50 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -41,23 +41,14 @@ class QueuedCommand
41public: 41public:
42 QueuedCommand(int commandId, const std::function<void(int, const QString &)> &callback) 42 QueuedCommand(int commandId, const std::function<void(int, const QString &)> &callback)
43 : commandId(commandId), 43 : commandId(commandId),
44 bufferSize(0),
45 buffer(0),
46 callback(callback) 44 callback(callback)
47 {} 45 {}
48 46
49 QueuedCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb, const std::function<void(int, const QString &)> &callback) 47 QueuedCommand(int commandId, const QByteArray &b, const std::function<void(int, const QString &)> &callback)
50 : commandId(commandId), 48 : commandId(commandId),
51 bufferSize(fbb.GetSize()), 49 buffer(b),
52 buffer(new char[bufferSize]),
53 callback(callback) 50 callback(callback)
54 { 51 {
55 memcpy(buffer, fbb.GetBufferPointer(), bufferSize);
56 }
57
58 ~QueuedCommand()
59 {
60 delete[] buffer;
61 } 52 }
62 53
63private: 54private:
@@ -66,8 +57,7 @@ private:
66 57
67public: 58public:
68 const int commandId; 59 const int commandId;
69 const uint bufferSize; 60 QByteArray buffer;
70 char *buffer;
71 std::function<void(int, const QString &)> callback; 61 std::function<void(int, const QString &)> callback;
72}; 62};
73 63
@@ -159,7 +149,9 @@ Async::Job<void> ResourceAccess::sendCommand(int commandId)
159 149
160Async::Job<void> ResourceAccess::sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb) 150Async::Job<void> ResourceAccess::sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb)
161{ 151{
162 return Async::start<void>([commandId, &fbb, this](Async::Future<void> &f) { 152 //The flatbuffer is transient, but we want to store it until the job is executed
153 QByteArray buffer(reinterpret_cast<const char*>(fbb.GetBufferPointer()), fbb.GetSize());
154 return Async::start<void>([commandId, buffer, this](Async::Future<void> &f) {
163 auto callback = [&f](int error, const QString &errorMessage) { 155 auto callback = [&f](int error, const QString &errorMessage) {
164 if (error) { 156 if (error) {
165 f.setError(error, errorMessage); 157 f.setError(error, errorMessage);
@@ -169,12 +161,13 @@ Async::Job<void> ResourceAccess::sendCommand(int commandId, flatbuffers::FlatBu
169 }; 161 };
170 162
171 if (isReady()) { 163 if (isReady()) {
164 //TODO: We probably always want to queue the command, so we can resend it in case something goes wrong
172 d->messageId++; 165 d->messageId++;
173 log(QString("Sending command %1 with messageId %2").arg(commandId).arg(d->messageId)); 166 log(QString("Sending command %1 with messageId %2").arg(commandId).arg(d->messageId));
174 registerCallback(d->messageId, callback); 167 registerCallback(d->messageId, callback);
175 Commands::write(d->socket, d->messageId, commandId, fbb); 168 Commands::write(d->socket, d->messageId, commandId, buffer.constData(), buffer.size());
176 } else { 169 } else {
177 d->commandQueue << new QueuedCommand(commandId, fbb, callback); 170 d->commandQueue << new QueuedCommand(commandId, buffer, callback);
178 } 171 }
179 }); 172 });
180} 173}
@@ -237,7 +230,7 @@ void ResourceAccess::connected()
237 if (command->callback) { 230 if (command->callback) {
238 registerCallback(d->messageId, command->callback); 231 registerCallback(d->messageId, command->callback);
239 } 232 }
240 Commands::write(d->socket, d->messageId, command->commandId, command->buffer, command->bufferSize); 233 Commands::write(d->socket, d->messageId, command->commandId, command->buffer.constData(), command->buffer.size());
241 delete command; 234 delete command;
242 } 235 }
243 d->commandQueue.clear(); 236 d->commandQueue.clear();