diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index fb8cad6483c01b932df8a01595c8ea3db3dc9297..6175ef252dcd979cad3206ec1653fff985d9eadb 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -174,9 +174,7 @@ SIPCall::~SIPCall()
     std::lock_guard<std::recursive_mutex> lk {callMutex_};
     {
         std::lock_guard<std::mutex> lk(transportMtx_);
-        if (tmpMediaTransport_)
-            dht::ThreadPool::io().run([ice = std::make_shared<decltype(tmpMediaTransport_)>(
-                                           std::move(tmpMediaTransport_))] {});
+        resetTransport(std::move(tmpMediaTransport_));
     }
     setTransport({});
     setInviteSession(); // prevents callback usage
@@ -1450,11 +1448,13 @@ SIPCall::removeCall()
         sdp_->setActiveRemoteSdpSession(nullptr);
     }
     Call::removeCall();
-    if (mediaTransport_)
-        dht::ThreadPool::io().run([ice = std::move(mediaTransport_)] {});
-    if (tmpMediaTransport_)
-        dht::ThreadPool::io().run([ice = std::make_shared<decltype(tmpMediaTransport_)>(
-                                       std::move(tmpMediaTransport_))] {});
+
+    {
+        std::lock_guard<std::mutex> lk(transportMtx_);
+        resetTransport(std::move(mediaTransport_));
+        resetTransport(std::move(tmpMediaTransport_));
+    }
+
     setInviteSession();
     setTransport({});
 }
@@ -2350,12 +2350,9 @@ SIPCall::onIceNegoSucceed()
     // Nego succeed: move to the new media transport
     stopAllMedia();
     {
-        std::lock_guard<std::mutex> lk(transportMtx_);
+        std::unique_lock<std::mutex> lk(transportMtx_);
         if (tmpMediaTransport_) {
-            // Destroy the ICE media transport on another thread. This can take
-            // quite some time.
-            if (mediaTransport_)
-                dht::ThreadPool::io().run([ice = std::move(mediaTransport_)] {});
+            resetTransport(std::move(mediaTransport_));
             mediaTransport_ = std::move(tmpMediaTransport_);
         }
     }
@@ -2892,21 +2889,36 @@ SIPCall::initIceMediaTransport(bool master, std::optional<IceTransportOptions> o
     // Each RTP stream requires a pair of ICE components (RTP + RTCP).
     iceOptions.compCountPerStream = ICE_COMP_COUNT_PER_STREAM;
     auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
-    std::lock_guard<std::mutex> lk(transportMtx_);
+
     auto transport = iceTransportFactory.createUTransport(getCallId().c_str(), iceOptions);
+
     // Destroy old ice on a separate io pool
-    if (tmpMediaTransport_)
-        dht::ThreadPool::io().run([ice = std::make_shared<decltype(tmpMediaTransport_)>(
-                                       std::move(tmpMediaTransport_))] {});
-    tmpMediaTransport_ = std::move(transport);
+    {
+        std::lock_guard<std::mutex> lk(transportMtx_);
+        resetTransport(std::move(tmpMediaTransport_));
+        tmpMediaTransport_ = std::move(transport);
+    }
+
     if (tmpMediaTransport_) {
-        JAMI_DBG("[call:%s] Successfully created media ICE transport", getCallId().c_str());
+        JAMI_DBG("[call:%s] Successfully created media ICE transport [ice:%p]", getCallId().c_str(), tmpMediaTransport_.get());
     } else {
         JAMI_ERR("[call:%s] Failed to create media ICE transport", getCallId().c_str());
     }
+
     return static_cast<bool>(tmpMediaTransport_);
 }
 
+void
+SIPCall::resetTransport(std::shared_ptr<IceTransport>&& transport)
+{
+    // Move the transport to another thread and destroy it there if possible
+    if (transport) {
+        dht::ThreadPool::io().run([transport = std::move(transport)]() mutable {
+            transport.reset();
+        });
+    }
+}
+
 void
 SIPCall::merge(Call& call)
 {
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index c5b0954d7c3c5058e2f63035087a356ce2aca659..80b60d91e3d45e3ff4e0fc1e781a1fe7deeebad6 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -124,6 +124,8 @@ public:
 private:
     void merge(Call& call) override; // not public - only called by Call
 
+    void resetTransport(std::shared_ptr<IceTransport>&& transport);
+
 public:
     void answer() override;
     void answer(const std::vector<DRing::MediaMap>& mediaList) override;