[TTVD] Fix deadlock when deleting self-manage resources 31/314931/3
authorJakub Gajownik <j.gajownik2@samsung.com>
Mon, 22 Jul 2024 14:32:45 +0000 (16:32 +0200)
committerBot Blink <blinkbot@samsung.com>
Tue, 23 Jul 2024 09:12:25 +0000 (09:12 +0000)
It was possible that self-managed resources (holding their
resource manager) could deadlock when releasing during
handling conflict. It's because of locking mutex by
RM client while waiting for resource to be released
and decoder thread trying to unregister resource manager.
Since handling resource might be dispatched to decoder
thread, it cannot be finished, as this thread might be
waiting for mutex to be released.

Similar issue was fixed before by dispatching resource
manager deletition to thread pool for decoder thread. After
such change decoder thread no longer depends on access to
resource manager mutex, it might finish its work and then
handle request dispatched from RM client.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-539
Change-Id: I9b4e97f060b292b1db86deb0693f5f727b1fa660
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
tizen_src/chromium_impl/base/tizen/resource_manager.cc
tizen_src/chromium_impl/base/tizen/resource_manager.h

index 36953b71eeddc4fc42ee810feab5aa3a7448023d..cbad248c3218ba650e31637d5c428965daf882a2 100644 (file)
@@ -62,6 +62,19 @@ rm_cb_result RMResourceReleaseCallback(int handle,
 }
 }  // namespace
 
+AllocatedResource::Token::~Token() {
+  release_cb_.RunAndReset();
+  // For resources that self-manage their managers, we're sure at this point
+  // it holds no more resources. To avoid deadlock with recursive mutex
+  // locking, we can post destruction to some other thread using thread pool.
+  if (owner_) {
+    base::ThreadPool::PostTask(
+          FROM_HERE, {base::TaskPriority::BEST_EFFORT},
+          base::BindOnce([](std::unique_ptr<ResourceManager>) {},
+                         std::move(owner_)));
+  }
+}
+
 void ResourceManagerEntry::Register(int handle, ResourceManager* instance) {
   AutoLock auto_lock(lock_);
   managers_.emplace(handle, instance);
@@ -202,15 +215,6 @@ void ResourceManager::ReleaseDevice(int device_id) {
   if (maybe_token.has_value()) {
     AutoLock auto_lock(lock_);
     ReleaseResourceLocked(maybe_token->Leak());
-    // For resources that self-manage their managers, we're sure at this point
-    // it holds no more resources. To avoid deadlock with recursive mutex
-    // locking, we can post destruction to some other thread using thread pool.
-    if (maybe_token->owner_) {
-      base::ThreadPool::PostTask(
-          FROM_HERE, {base::TaskPriority::BEST_EFFORT},
-          base::BindOnce([](std::unique_ptr<ResourceManager>) {},
-                         std::move(maybe_token->owner_)));
-    }
   }
 }
 
index 524ca39ba864cc1dd4f65ac702fae6e0effee76a..5060674fe59ed67071e4cf5373458bc87e6d3664 100644 (file)
@@ -34,7 +34,7 @@ struct AllocatedResource {
   class Token {
    public:
     Token() = default;
-    ~Token() = default;
+    ~Token();
 
     Token(const Token&) = delete;
     Token& operator=(const Token&) = delete;