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, \ 48 base::TimeDelta::FromMilliseconds(delay_ms)) 49 50 // Post a blocking task with the specified |priority|. Tasks that have not 51 // started executing at shutdown will never run. However, any task that has 52 // already begun executing when shutdown is invoked will be allowed to continue 53 // and will block shutdown until completion. 54 // Tasks posted with this method are not guaranteed to run sequentially. Use 55 // base::CreateSequencedTaskRunner instead if sequence is important. 56 // Sequenced runners at various priorities that always execute all pending tasks 57 // before shutdown are available via CefTaskRunnerManager and exposed by the CEF 58 // API. 59 #define CEF_POST_BLOCKING_TASK(priority, task) \ 60 base::ThreadPool::PostTask( \ 61 FROM_HERE, \ 62 {priority, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, \ 63 base::MayBlock()}, \ 64 task) 65 66 // Post a blocking task that affects UI or responsiveness of future user 67 // interactions. Do not use if an immediate response to a user interaction is 68 // expected. 69 #define CEF_POST_USER_VISIBLE_TASK(task) \ 70 CEF_POST_BLOCKING_TASK(base::TaskPriority::USER_VISIBLE, task) 71 72 // Post a blocking task where the user won't notice if it takes an arbitrarily 73 // long time to complete. 74 #define CEF_POST_BACKGROUND_TASK(task) \ 75 CEF_POST_BLOCKING_TASK(base::TaskPriority::BEST_EFFORT, task) 76 77 // Assert that blocking is allowed on the current thread. 78 #define CEF_REQUIRE_BLOCKING() \ 79 base::ScopedBlockingCall scoped_blocking_call( \ 80 FROM_HERE, base::BlockingType::WILL_BLOCK) 81 82 // Same as IMPLEMENT_REFCOUNTING() but using the specified Destructor. 83 #define IMPLEMENT_REFCOUNTING_EX(ClassName, Destructor) \ 84 public: \ 85 void AddRef() const OVERRIDE { ref_count_.AddRef(); } \ 86 bool Release() const OVERRIDE { \ 87 if (ref_count_.Release()) { \ 88 Destructor::Destruct(this); \ 89 return true; \ 90 } \ 91 return false; \ 92 } \ 93 bool HasOneRef() const OVERRIDE { return ref_count_.HasOneRef(); } \ 94 bool HasAtLeastOneRef() const OVERRIDE { \ 95 return ref_count_.HasAtLeastOneRef(); \ 96 } \ 97 \ 98 private: \ 99 CefRefCount ref_count_ 100 101 #define IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(ClassName) \ 102 IMPLEMENT_REFCOUNTING_EX(ClassName, content::BrowserThread::DeleteOnUIThread) 103 104 #define IMPLEMENT_REFCOUNTING_DELETE_ON_IOT(ClassName) \ 105 IMPLEMENT_REFCOUNTING_EX(ClassName, content::BrowserThread::DeleteOnIOThread) 106 107 #endif // CEF_LIBCEF_BROWSER_THREAD_UTIL_H_ 108