1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights 2 // reserved. Use of this source code is governed by a BSD-style license that 3 // can be found in the LICENSE file. 4 5 #ifndef CEF_LIBCEF_BROWSER_THREAD_UTIL_H_ 6 #define CEF_LIBCEF_BROWSER_THREAD_UTIL_H_ 7 #pragma once 8 9 #include "base/location.h" 10 #include "base/logging.h" 11 #include "base/task/post_task.h" 12 #include "base/task/thread_pool.h" 13 #include "base/threading/scoped_blocking_call.h" 14 #include "base/threading/thread_restrictions.h" 15 #include "content/public/browser/browser_task_traits.h" 16 #include "content/public/browser/browser_thread.h" 17 18 #define CEF_UIT content::BrowserThread::UI 19 #define CEF_IOT content::BrowserThread::IO 20 21 #define CEF_CURRENTLY_ON(id) content::BrowserThread::CurrentlyOn(id) 22 #define CEF_CURRENTLY_ON_UIT() CEF_CURRENTLY_ON(CEF_UIT) 23 #define CEF_CURRENTLY_ON_IOT() CEF_CURRENTLY_ON(CEF_IOT) 24 25 #define CEF_REQUIRE(id) DCHECK(CEF_CURRENTLY_ON(id)) 26 #define CEF_REQUIRE_UIT() CEF_REQUIRE(CEF_UIT) 27 #define CEF_REQUIRE_IOT() CEF_REQUIRE(CEF_IOT) 28 29 #define CEF_REQUIRE_RETURN(id, var) \ 30 if (!CEF_CURRENTLY_ON(id)) { \ 31 NOTREACHED() << "called on invalid thread"; \ 32 return var; \ 33 } 34 #define CEF_REQUIRE_UIT_RETURN(var) CEF_REQUIRE_RETURN(CEF_UIT, var) 35 #define CEF_REQUIRE_IOT_RETURN(var) CEF_REQUIRE_RETURN(CEF_IOT, var) 36 37 #define CEF_REQUIRE_RETURN_VOID(id) \ 38 if (!CEF_CURRENTLY_ON(id)) { \ 39 NOTREACHED() << "called on invalid thread"; \ 40 return; \ 41 } 42 #define CEF_REQUIRE_UIT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_UIT) 43 #define CEF_REQUIRE_IOT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_IOT) 44 45 #define CEF_POST_TASK(id, task) base::PostTask(FROM_HERE, {id}, task) 46 #define CEF_POST_DELAYED_TASK(id, task, delay_ms) \ 47 base::PostDelayedTask(FROM_HERE, {id}, task, base::Milliseconds(delay_ms)) 48 49 // Post a blocking task with the specified |priority|. Tasks that have not 50 // started executing at shutdown will never run. However, any task that has 51 // already begun executing when shutdown is invoked will be allowed to continue 52 // and will block shutdown until completion. 53 // Tasks posted with this method are not guaranteed to run sequentially. Use 54 // base::CreateSequencedTaskRunner instead if sequence is important. 55 // Sequenced runners at various priorities that always execute all pending tasks 56 // before shutdown are available via CefTaskRunnerManager and exposed by the CEF 57 // API. 58 #define CEF_POST_BLOCKING_TASK(priority, task) \ 59 base::ThreadPool::PostTask( \ 60 FROM_HERE, \ 61 {priority, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, \ 62 base::MayBlock()}, \ 63 task) 64 65 // Post a blocking task that affects UI or responsiveness of future user 66 // interactions. Do not use if an immediate response to a user interaction is 67 // expected. 68 #define CEF_POST_USER_VISIBLE_TASK(task) \ 69 CEF_POST_BLOCKING_TASK(base::TaskPriority::USER_VISIBLE, task) 70 71 // Post a blocking task where the user won't notice if it takes an arbitrarily 72 // long time to complete. 73 #define CEF_POST_BACKGROUND_TASK(task) \ 74 CEF_POST_BLOCKING_TASK(base::TaskPriority::BEST_EFFORT, task) 75 76 // Assert that blocking is allowed on the current thread. 77 #define CEF_REQUIRE_BLOCKING() \ 78 base::ScopedBlockingCall scoped_blocking_call( \ 79 FROM_HERE, base::BlockingType::WILL_BLOCK) 80 81 // Same as IMPLEMENT_REFCOUNTING() but using the specified Destructor. 82 #define IMPLEMENT_REFCOUNTING_EX(ClassName, Destructor) \ 83 public: \ 84 void AddRef() const override { ref_count_.AddRef(); } \ 85 bool Release() const override { \ 86 if (ref_count_.Release()) { \ 87 Destructor::Destruct(this); \ 88 return true; \ 89 } \ 90 return false; \ 91 } \ 92 bool HasOneRef() const override { return ref_count_.HasOneRef(); } \ 93 bool HasAtLeastOneRef() const override { \ 94 return ref_count_.HasAtLeastOneRef(); \ 95 } \ 96 \ 97 private: \ 98 CefRefCount ref_count_ 99 100 #define IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(ClassName) \ 101 IMPLEMENT_REFCOUNTING_EX(ClassName, content::BrowserThread::DeleteOnUIThread) 102 103 #define IMPLEMENT_REFCOUNTING_DELETE_ON_IOT(ClassName) \ 104 IMPLEMENT_REFCOUNTING_EX(ClassName, content::BrowserThread::DeleteOnIOThread) 105 106 #endif // CEF_LIBCEF_BROWSER_THREAD_UTIL_H_ 107