1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_
6 #define PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_
8 #include "ppapi/cpp/logging.h"
9 #include "ppapi/cpp/module.h"
10 #include "ppapi/utility/threading/lock.h"
13 /// Defines the traits structures for thread-safety of a completion callback
14 /// factory. We provide thread-safe and non-thread-safe version. The thread-safe
15 /// version is always correct (if you follow the thread usage rules of the
16 /// callback factory), but if you know your object will only be used on one
17 /// thread, you can uses the non-thread-safe version.
19 /// The traits defines three nested classes to perform reference counting,
20 /// locks, and scoped locking.
24 /// The thread-safe version of thread traits. Using this class as the "traits"
25 /// template argument to a completion callback factory will make it "somewhat
26 /// thread-friendly." It will allow you to create completion callbacks from
27 /// background threads and post them to another thread to run.
29 /// Care still must be taken to ensure that the completion callbacks are
30 /// executed on the same thread that the factory is destroyed on to avoid a
31 /// race on destruction.
33 /// Implementation note: this uses a lock instead of atomic add instructions.
34 /// The number of platforms we need to support right now makes atomic
35 /// operations unwieldy for this case that we don't actually use that often.
36 /// As a further optimization, we can add support for this later.
37 class ThreadSafeThreadTraits
{
41 /// Default constructor. In debug mode, this checks that the object is being
42 /// created on the main thread.
43 RefCount() : ref_(0) {
46 /// AddRef() increments the reference counter.
48 /// @return An int32_t with the incremented reference counter.
54 /// Release() decrements the reference counter.
56 /// @return An int32_t with the decremeneted reference counter.
68 typedef pp::Lock Lock
;
69 typedef pp::AutoLock AutoLock
;
72 /// The non-thread-safe version of thread traits. Using this class as the
73 /// "traits" template argument to a completion callback factory will make it
74 /// not thread-safe but with potential extra performance.
75 class NonThreadSafeThreadTraits
{
77 /// A simple reference counter that is not thread-safe.
79 /// <strong>Note:</strong> in Debug mode, it checks that it is either called
80 /// on the main thread, or always called on another thread.
83 /// Default constructor. In debug mode, this checks that the object is being
84 /// created on the main thread.
85 RefCount() : ref_(0) {
87 is_main_thread_
= Module::Get()->core()->IsMainThread();
93 PP_DCHECK(is_main_thread_
== Module::Get()->core()->IsMainThread());
96 /// AddRef() increments the reference counter.
98 /// @return An int32_t with the incremented reference counter.
100 PP_DCHECK(is_main_thread_
== Module::Get()->core()->IsMainThread());
104 /// Release() decrements the reference counter.
106 /// @return An int32_t with the decremeneted reference counter.
108 PP_DCHECK(is_main_thread_
== Module::Get()->core()->IsMainThread());
115 bool is_main_thread_
;
119 /// A simple object that acts like a lock but does nothing.
121 /// <strong>Note:</strong> in Debug mode, it checks that it is either
122 /// called on the main thread, or always called on another thread. It also
123 /// asserts that the caller does not recursively lock.
128 is_main_thread_
= Module::Get()->core()->IsMainThread();
134 PP_DCHECK(is_main_thread_
== Module::Get()->core()->IsMainThread());
137 /// Acquires the fake "lock". This does nothing except perform checks in
141 PP_DCHECK(!lock_held_
);
146 /// Releases the fake "lock". This does nothing except perform checks in
150 PP_DCHECK(lock_held_
);
157 bool is_main_thread_
;
164 explicit AutoLock(Lock
& lock
) : lock_(lock
) {
178 #endif // PPAPI_UTILITY_THREAD_SAFE_THREAD_TRAITS_H_