From f9a34f99c8ca709fa505b4614550068dbd8df6da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 25 Jun 2021 17:40:49 -0400
Subject: [PATCH] data_transfer: channel can live longer than IncomingFile

Change-Id: Ifbc66d0197949f82826bd743b3a015ae5b540e6f
---
 src/data_transfer.cpp | 35 ++++++++++++++++++++---------------
 src/data_transfer.h   |  6 +++++-
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/data_transfer.cpp b/src/data_transfer.cpp
index 7ec830ad09..b6a7d4135e 100644
--- a/src/data_transfer.cpp
+++ b/src/data_transfer.cpp
@@ -832,32 +832,37 @@ IncomingFile::cancel()
 void
 IncomingFile::process()
 {
-    channel_->setOnRecv([this](const uint8_t* buf, size_t len) {
-        if (stream_.is_open())
-            stream_ << std::string_view((const char*) buf, len);
-        info_.bytesProgress = stream_.tellp();
+    channel_->setOnRecv([w=weak()](const uint8_t* buf, size_t len) {
+        if (auto shared = w.lock()) {
+            if (shared->stream_.is_open())
+                shared->stream_ << std::string_view((const char*) buf, len);
+            shared->info_.bytesProgress = shared->stream_.tellp();
+        }
         return len;
     });
-    channel_->onShutdown([this] {
-        auto correct = sha3Sum_.empty();
+    channel_->onShutdown([w=weak()] {
+        auto shared = w.lock();
+        if (!shared)
+            return;
+        auto correct = shared->sha3Sum_.empty();
         if (!correct) {
-            if (stream_ && stream_.is_open())
-                stream_.close();
+            if (shared->stream_ && shared->stream_.is_open())
+                shared->stream_.close();
             // Verify shaSum
-            auto sha3Sum = fileutils::sha3File(info_.path);
-            if (sha3Sum_ == sha3Sum) {
-                JAMI_INFO() << "New file received: " << info_.path;
+            auto sha3Sum = fileutils::sha3File(shared->info_.path);
+            if (shared->sha3Sum_ == sha3Sum) {
+                JAMI_INFO() << "New file received: " << shared->info_.path;
                 correct = true;
             } else {
-                JAMI_WARN() << "Remove file, invalid sha3sum detected for " << info_.path;
-                fileutils::remove(info_.path, true);
+                JAMI_WARN() << "Remove file, invalid sha3sum detected for " << shared->info_.path;
+                fileutils::remove(shared->info_.path, true);
             }
         }
-        if (isUserCancelled_)
+        if (shared->isUserCancelled_)
             return;
         auto code = correct ? DRing::DataTransferEventCode::finished
                             : DRing::DataTransferEventCode::closed_by_host;
-        emit(code);
+        shared->emit(code);
     });
 }
 
diff --git a/src/data_transfer.h b/src/data_transfer.h
index 9b7aae9054..92f4eb72b4 100644
--- a/src/data_transfer.h
+++ b/src/data_transfer.h
@@ -79,7 +79,7 @@ protected:
     std::function<void(uint32_t)> finishedCb_ {};
 };
 
-class IncomingFile : public FileInfo
+class IncomingFile : public FileInfo, public std::enable_shared_from_this<IncomingFile>
 {
 public:
     IncomingFile(const std::shared_ptr<ChannelSocket>& channel,
@@ -92,6 +92,10 @@ public:
     void cancel() override;
 
 private:
+    std::weak_ptr<IncomingFile> weak()
+    {
+        return std::static_pointer_cast<IncomingFile>(shared_from_this());
+    }
     std::ofstream stream_;
     std::string sha3Sum_ {};
 };
-- 
GitLab