From 947bc0f2d97e0d45eb3c198d2fdd10b534164567 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Mon, 16 Oct 2023 12:49:17 -0400
Subject: [PATCH] sync_module: reserve unpacker buffer

Change-Id: I80aebbc7cfe97b257571a13a07eff00dab0b2a2c
---
 src/jamidht/sync_module.cpp | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/src/jamidht/sync_module.cpp b/src/jamidht/sync_module.cpp
index c2ae87bdcd..aba4c3afc3 100644
--- a/src/jamidht/sync_module.cpp
+++ b/src/jamidht/sync_module.cpp
@@ -173,26 +173,40 @@ SyncModule::cacheSyncConnection(std::shared_ptr<dhtnet::ChannelSocket>&& socket,
         }
     });
 
-    socket->setOnRecv([acc = pimpl_->account_.lock(), device, peerId](const uint8_t* buf,
-                                                                      size_t len) {
+
+    struct DecodingContext
+    {
+        msgpack::unpacker pac {[](msgpack::type::object_type, std::size_t, void*) { return true; },
+                               nullptr,
+                               512};
+    };
+
+    socket->setOnRecv([acc = pimpl_->account_.lock(), device, peerId,
+                       ctx = std::make_shared<DecodingContext>()
+    ](const uint8_t* buf, size_t len) {
         if (!buf || !acc)
             return len;
 
+        ctx->pac.reserve_buffer(len);
+        std::copy_n(buf, len, ctx->pac.buffer());
+        ctx->pac.buffer_consumed(len);
+
+        msgpack::object_handle oh;
         SyncMsg msg;
+
         try {
-            msgpack::unpacked result;
-            msgpack::object_handle oh = msgpack::unpack(reinterpret_cast<const char*>(buf), len);
-            oh.get().convert(msg);
+            while (ctx->pac.next(oh)) {
+                oh.get().convert(msg);
+                if (auto manager = acc->accountManager())
+                    manager->onSyncData(std::move(msg.ds), false);
+
+                if (!msg.c.empty() || !msg.cr.empty() || !msg.p.empty() || !msg.ld.empty())
+                    acc->convModule()->onSyncData(msg, peerId, device.toString());
+            }
         } catch (const std::exception& e) {
             JAMI_WARNING("[convInfo] error on sync: {:s}", e.what());
-            return len;
         }
 
-        if (auto manager = acc->accountManager())
-            manager->onSyncData(std::move(msg.ds), false);
-
-        if (!msg.c.empty() || !msg.cr.empty() || !msg.p.empty() || !msg.ld.empty())
-            acc->convModule()->onSyncData(msg, peerId, device.toString());
         return len;
     });
 }
-- 
GitLab