diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-04-02 17:22:24 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-04-02 17:22:24 +0200 |
commit | f46e1f6775b5e052ebe12f9db2eb211d1622274b (patch) | |
tree | 4a2fcd6ef65756e04f8ece8cd92e8f29f9707b9a /common/resourceaccess.cpp | |
parent | 93f224b1f6ca0a69a5c4610466baa43b43d042e3 (diff) | |
download | sink-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.cpp | 27 |
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 | |||
41 | public: | 41 | public: |
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 | ||
63 | private: | 54 | private: |
@@ -66,8 +57,7 @@ private: | |||
66 | 57 | ||
67 | public: | 58 | public: |
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 | ||
160 | Async::Job<void> ResourceAccess::sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb) | 150 | Async::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(); |