1 // Copyright (c) 2012 Marshall A. Greenblatt. All rights reserved. 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google Inc. nor the name Chromium Embedded 14 // Framework nor the names of its contributors may be used to endorse 15 // or promote products derived from this software without specific prior 16 // written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 #ifndef CEF_INCLUDE_CEF_BASE_H_ 31 #define CEF_INCLUDE_CEF_BASE_H_ 32 #pragma once 33 34 #include "include/base/cef_atomic_ref_count.h" 35 #include "include/base/cef_build.h" 36 #include "include/base/cef_macros.h" 37 38 // Bring in common C++ type definitions used by CEF consumers. 39 #include "include/internal/cef_ptr.h" 40 #include "include/internal/cef_types_wrappers.h" 41 #if defined(OS_WIN) 42 #include "include/internal/cef_win.h" 43 #elif defined(OS_MAC) 44 #include "include/internal/cef_mac.h" 45 #elif defined(OS_LINUX) 46 #include "include/internal/cef_linux.h" 47 #endif 48 49 /// 50 // All ref-counted framework classes must extend this class. 51 /// 52 class CefBaseRefCounted { 53 public: 54 /// 55 // Called to increment the reference count for the object. Should be called 56 // for every new copy of a pointer to a given object. 57 /// 58 virtual void AddRef() const = 0; 59 60 /// 61 // Called to decrement the reference count for the object. Returns true if 62 // the reference count is 0, in which case the object should self-delete. 63 /// 64 virtual bool Release() const = 0; 65 66 /// 67 // Returns true if the reference count is 1. 68 /// 69 virtual bool HasOneRef() const = 0; 70 71 /// 72 // Returns true if the reference count is at least 1. 73 /// 74 virtual bool HasAtLeastOneRef() const = 0; 75 76 protected: ~CefBaseRefCounted()77 virtual ~CefBaseRefCounted() {} 78 }; 79 80 /// 81 // All scoped framework classes must extend this class. 82 /// 83 class CefBaseScoped { 84 public: ~CefBaseScoped()85 virtual ~CefBaseScoped() {} 86 }; 87 88 /// 89 // Class that implements atomic reference counting. 90 /// 91 class CefRefCount { 92 public: CefRefCount()93 CefRefCount() : ref_count_(0) {} 94 95 /// 96 // Increment the reference count. 97 /// AddRef()98 void AddRef() const { base::AtomicRefCountInc(&ref_count_); } 99 100 /// 101 // Decrement the reference count. Returns true if the reference count is 0. 102 /// Release()103 bool Release() const { return !base::AtomicRefCountDec(&ref_count_); } 104 105 /// 106 // Returns true if the reference count is 1. 107 /// HasOneRef()108 bool HasOneRef() const { return base::AtomicRefCountIsOne(&ref_count_); } 109 110 /// 111 // Returns true if the reference count is at least 1. 112 /// HasAtLeastOneRef()113 bool HasAtLeastOneRef() const { 114 return !base::AtomicRefCountIsZero(&ref_count_); 115 } 116 117 private: 118 mutable base::AtomicRefCount ref_count_; 119 DISALLOW_COPY_AND_ASSIGN(CefRefCount); 120 }; 121 122 /// 123 // Macro that provides a reference counting implementation for classes extending 124 // CefBase. 125 /// 126 #define IMPLEMENT_REFCOUNTING(ClassName) \ 127 public: \ 128 void AddRef() const OVERRIDE { ref_count_.AddRef(); } \ 129 bool Release() const OVERRIDE { \ 130 if (ref_count_.Release()) { \ 131 delete static_cast<const ClassName*>(this); \ 132 return true; \ 133 } \ 134 return false; \ 135 } \ 136 bool HasOneRef() const OVERRIDE { return ref_count_.HasOneRef(); } \ 137 bool HasAtLeastOneRef() const OVERRIDE { \ 138 return ref_count_.HasAtLeastOneRef(); \ 139 } \ 140 \ 141 private: \ 142 CefRefCount ref_count_ 143 144 /// 145 // Macro that provides a locking implementation. Use the Lock() and Unlock() 146 // methods to protect a section of code from simultaneous access by multiple 147 // threads. The AutoLock class is a helper that will hold the lock while in 148 // scope. 149 // 150 // THIS MACRO IS DEPRECATED. Use an explicit base::Lock member variable and 151 // base::AutoLock instead. For example: 152 // 153 // #include "include/base/cef_lock.h" 154 // 155 // // Class declaration. 156 // class MyClass : public CefBaseRefCounted { 157 // public: 158 // MyClass() : value_(0) {} 159 // // Method that may be called on multiple threads. 160 // void IncrementValue(); 161 // private: 162 // // Value that may be accessed on multiple theads. 163 // int value_; 164 // // Lock used to protect access to |value_|. 165 // base::Lock lock_; 166 // IMPLEMENT_REFCOUNTING(MyClass); 167 // }; 168 // 169 // // Class implementation. 170 // void MyClass::IncrementValue() { 171 // // Acquire the lock for the scope of this method. 172 // base::AutoLock lock_scope(lock_); 173 // // |value_| can now be modified safely. 174 // value_++; 175 // } 176 /// 177 #define IMPLEMENT_LOCKING(ClassName) \ 178 public: \ 179 class AutoLock { \ 180 public: \ 181 explicit AutoLock(ClassName* base) : base_(base) { base_->Lock(); } \ 182 ~AutoLock() { base_->Unlock(); } \ 183 \ 184 private: \ 185 ClassName* base_; \ 186 DISALLOW_COPY_AND_ASSIGN(AutoLock); \ 187 }; \ 188 void Lock() { lock_.Acquire(); } \ 189 void Unlock() { lock_.Release(); } \ 190 \ 191 private: \ 192 base::Lock lock_; 193 194 #endif // CEF_INCLUDE_CEF_BASE_H_ 195