Commit a3d29f51446a7103a2101a21135c5f920aa73dc4
1 parent
4a16d48b
Fix unnecessary QoS packet creation
The extraneous creation would happen when multiple subscribes at different QoS levels happen.
Showing
3 changed files
with
10 additions
and
9 deletions
client.cpp
| ... | ... | @@ -251,14 +251,14 @@ void Client::writeMqttPacketAndBlameThisClient(PublishCopyFactory &copyFactory, |
| 251 | 251 | |
| 252 | 252 | MqttPacket *p = copyFactory.getOptimumPacket(max_qos, this->protocolVersion, topic_alias, skip_topic); |
| 253 | 253 | |
| 254 | - assert(p->getQos() <= max_qos); | |
| 254 | + assert(static_cast<bool>(p->getQos()) == static_cast<bool>(max_qos)); | |
| 255 | 255 | |
| 256 | 256 | if (p->getQos() > 0) |
| 257 | 257 | { |
| 258 | 258 | // This may change the packet ID and QoS of the incoming packet for each subscriber, but because we don't store that packet anywhere, |
| 259 | 259 | // that should be fine. |
| 260 | 260 | p->setPacketId(packet_id); |
| 261 | - p->setQos(max_qos); | |
| 261 | + p->setQos(copyFactory.getEffectiveQos(max_qos)); | |
| 262 | 262 | } |
| 263 | 263 | |
| 264 | 264 | writeMqttPacketAndBlameThisClient(*p); | ... | ... |
publishcopyfactory.cpp
| ... | ... | @@ -19,31 +19,32 @@ PublishCopyFactory::PublishCopyFactory(Publish *publish) : |
| 19 | 19 | |
| 20 | 20 | MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const ProtocolVersion protocolVersion, uint16_t topic_alias, bool skip_topic) |
| 21 | 21 | { |
| 22 | + const char actualQos = getEffectiveQos(max_qos); | |
| 23 | + | |
| 22 | 24 | if (packet) |
| 23 | 25 | { |
| 24 | 26 | if (protocolVersion >= ProtocolVersion::Mqtt5 && (packet->containsClientSpecificProperties() || topic_alias > 0)) |
| 25 | 27 | { |
| 26 | 28 | Publish newPublish(packet->getPublishData()); |
| 27 | - newPublish.qos = max_qos; | |
| 29 | + newPublish.qos = actualQos; | |
| 28 | 30 | newPublish.topicAlias = topic_alias; |
| 29 | 31 | newPublish.skipTopic = skip_topic; |
| 30 | 32 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, newPublish); |
| 31 | 33 | return this->oneShotPacket.get(); |
| 32 | 34 | } |
| 33 | 35 | |
| 34 | - if (packet->getProtocolVersion() == protocolVersion && orgQos == max_qos) | |
| 36 | + if (packet->getProtocolVersion() == protocolVersion && static_cast<bool>(orgQos) == static_cast<bool>(actualQos)) | |
| 35 | 37 | { |
| 36 | - assert(orgQos == packet->getQos()); | |
| 37 | 38 | return packet; |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | - const int cache_key = (static_cast<uint8_t>(protocolVersion) * 10) + max_qos; | |
| 41 | + const int cache_key = (static_cast<uint8_t>(protocolVersion) * 10) + actualQos; | |
| 41 | 42 | std::unique_ptr<MqttPacket> &cachedPack = constructedPacketCache[cache_key]; |
| 42 | 43 | |
| 43 | 44 | if (!cachedPack) |
| 44 | 45 | { |
| 45 | 46 | Publish newPublish(packet->getPublishData()); |
| 46 | - newPublish.qos = max_qos; | |
| 47 | + newPublish.qos = actualQos; | |
| 47 | 48 | cachedPack = std::make_unique<MqttPacket>(protocolVersion, newPublish); |
| 48 | 49 | } |
| 49 | 50 | |
| ... | ... | @@ -53,7 +54,7 @@ MqttPacket *PublishCopyFactory::getOptimumPacket(const char max_qos, const Proto |
| 53 | 54 | // Getting an instance of a Publish object happens at least on retained messages, will messages and SYS topics. It's low traffic, anyway. |
| 54 | 55 | assert(publish); |
| 55 | 56 | |
| 56 | - publish->qos = getEffectiveQos(max_qos); | |
| 57 | + publish->qos = actualQos; | |
| 57 | 58 | |
| 58 | 59 | this->oneShotPacket = std::make_unique<MqttPacket>(protocolVersion, *publish); |
| 59 | 60 | return this->oneShotPacket.get(); | ... | ... |
publishcopyfactory.h
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | * @brief The PublishCopyFactory class is for managing copies of an incoming publish, including sometimes not making copies at all. |
| 12 | 12 | * |
| 13 | 13 | * The idea is that certain incoming packets can just be written to the receiving client as-is, without constructing a new one. We do have to change the bytes |
| 14 | - * where the QoS is stored, so we keep track of the original. | |
| 14 | + * where the QoS is stored, so we keep track of the original QoS. | |
| 15 | 15 | * |
| 16 | 16 | * Ownership info: object of this type are never copied or transferred, so the internal pointers come from (near) the same scope these objects |
| 17 | 17 | * are created from. | ... | ... |