gfx/skia/trunk/include/core/SkWeakRefCnt.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef SkWeakRefCnt_DEFINED
michael@0 9 #define SkWeakRefCnt_DEFINED
michael@0 10
michael@0 11 #include "SkRefCnt.h"
michael@0 12 #include "SkThread.h"
michael@0 13
michael@0 14 /** \class SkWeakRefCnt
michael@0 15
michael@0 16 SkWeakRefCnt is the base class for objects that may be shared by multiple
michael@0 17 objects. When an existing strong owner wants to share a reference, it calls
michael@0 18 ref(). When a strong owner wants to release its reference, it calls
michael@0 19 unref(). When the shared object's strong reference count goes to zero as
michael@0 20 the result of an unref() call, its (virtual) weak_dispose method is called.
michael@0 21 It is an error for the destructor to be called explicitly (or via the
michael@0 22 object going out of scope on the stack or calling delete) if
michael@0 23 getRefCnt() > 1.
michael@0 24
michael@0 25 In addition to strong ownership, an owner may instead obtain a weak
michael@0 26 reference by calling weak_ref(). A call to weak_ref() must be balanced by a
michael@0 27 call to weak_unref(). To obtain a strong reference from a weak reference,
michael@0 28 call try_ref(). If try_ref() returns true, the owner's pointer is now also
michael@0 29 a strong reference on which unref() must be called. Note that this does not
michael@0 30 affect the original weak reference, weak_unref() must still be called. When
michael@0 31 the weak reference count goes to zero, the object is deleted. While the
michael@0 32 weak reference count is positive and the strong reference count is zero the
michael@0 33 object still exists, but will be in the disposed state. It is up to the
michael@0 34 object to define what this means.
michael@0 35
michael@0 36 Note that a strong reference implicitly implies a weak reference. As a
michael@0 37 result, it is allowable for the owner of a strong ref to call try_ref().
michael@0 38 This will have the same effect as calling ref(), but may be more expensive.
michael@0 39
michael@0 40 Example:
michael@0 41
michael@0 42 SkWeakRefCnt myRef = strongRef.weak_ref();
michael@0 43 ... // strongRef.unref() may or may not be called
michael@0 44 if (myRef.try_ref()) {
michael@0 45 ... // use myRef
michael@0 46 myRef.unref();
michael@0 47 } else {
michael@0 48 // myRef is in the disposed state
michael@0 49 }
michael@0 50 myRef.weak_unref();
michael@0 51 */
michael@0 52 class SK_API SkWeakRefCnt : public SkRefCnt {
michael@0 53 public:
michael@0 54 SK_DECLARE_INST_COUNT(SkWeakRefCnt)
michael@0 55
michael@0 56 /** Default construct, initializing the reference counts to 1.
michael@0 57 The strong references collectively hold one weak reference. When the
michael@0 58 strong reference count goes to zero, the collectively held weak
michael@0 59 reference is released.
michael@0 60 */
michael@0 61 SkWeakRefCnt() : SkRefCnt(), fWeakCnt(1) {}
michael@0 62
michael@0 63 /** Destruct, asserting that the weak reference count is 1.
michael@0 64 */
michael@0 65 virtual ~SkWeakRefCnt() {
michael@0 66 #ifdef SK_DEBUG
michael@0 67 SkASSERT(fWeakCnt == 1);
michael@0 68 fWeakCnt = 0;
michael@0 69 #endif
michael@0 70 }
michael@0 71
michael@0 72 /** Return the weak reference count.
michael@0 73 */
michael@0 74 int32_t getWeakCnt() const { return fWeakCnt; }
michael@0 75
michael@0 76 #ifdef SK_DEBUG
michael@0 77 void validate() const {
michael@0 78 this->INHERITED::validate();
michael@0 79 SkASSERT(fWeakCnt > 0);
michael@0 80 }
michael@0 81 #endif
michael@0 82
michael@0 83 /** Creates a strong reference from a weak reference, if possible. The
michael@0 84 caller must already be an owner. If try_ref() returns true the owner
michael@0 85 is in posession of an additional strong reference. Both the original
michael@0 86 reference and new reference must be properly unreferenced. If try_ref()
michael@0 87 returns false, no strong reference could be created and the owner's
michael@0 88 reference is in the same state as before the call.
michael@0 89 */
michael@0 90 bool SK_WARN_UNUSED_RESULT try_ref() const {
michael@0 91 if (sk_atomic_conditional_inc(&fRefCnt) != 0) {
michael@0 92 // Acquire barrier (L/SL), if not provided above.
michael@0 93 // Prevents subsequent code from happening before the increment.
michael@0 94 sk_membar_acquire__after_atomic_conditional_inc();
michael@0 95 return true;
michael@0 96 }
michael@0 97 return false;
michael@0 98 }
michael@0 99
michael@0 100 /** Increment the weak reference count. Must be balanced by a call to
michael@0 101 weak_unref().
michael@0 102 */
michael@0 103 void weak_ref() const {
michael@0 104 SkASSERT(fRefCnt > 0);
michael@0 105 SkASSERT(fWeakCnt > 0);
michael@0 106 sk_atomic_inc(&fWeakCnt); // No barrier required.
michael@0 107 }
michael@0 108
michael@0 109 /** Decrement the weak reference count. If the weak reference count is 1
michael@0 110 before the decrement, then call delete on the object. Note that if this
michael@0 111 is the case, then the object needs to have been allocated via new, and
michael@0 112 not on the stack.
michael@0 113 */
michael@0 114 void weak_unref() const {
michael@0 115 SkASSERT(fWeakCnt > 0);
michael@0 116 // Release barrier (SL/S), if not provided below.
michael@0 117 if (sk_atomic_dec(&fWeakCnt) == 1) {
michael@0 118 // Acquire barrier (L/SL), if not provided above.
michael@0 119 // Prevents code in destructor from happening before the decrement.
michael@0 120 sk_membar_acquire__after_atomic_dec();
michael@0 121 #ifdef SK_DEBUG
michael@0 122 // so our destructor won't complain
michael@0 123 fWeakCnt = 1;
michael@0 124 #endif
michael@0 125 this->INHERITED::internal_dispose();
michael@0 126 }
michael@0 127 }
michael@0 128
michael@0 129 /** Returns true if there are no strong references to the object. When this
michael@0 130 is the case all future calls to try_ref() will return false.
michael@0 131 */
michael@0 132 bool weak_expired() const {
michael@0 133 return fRefCnt == 0;
michael@0 134 }
michael@0 135
michael@0 136 protected:
michael@0 137 /** Called when the strong reference count goes to zero. This allows the
michael@0 138 object to free any resources it may be holding. Weak references may
michael@0 139 still exist and their level of allowed access to the object is defined
michael@0 140 by the object's class.
michael@0 141 */
michael@0 142 virtual void weak_dispose() const {
michael@0 143 }
michael@0 144
michael@0 145 private:
michael@0 146 /** Called when the strong reference count goes to zero. Calls weak_dispose
michael@0 147 on the object and releases the implicit weak reference held
michael@0 148 collectively by the strong references.
michael@0 149 */
michael@0 150 virtual void internal_dispose() const SK_OVERRIDE {
michael@0 151 weak_dispose();
michael@0 152 weak_unref();
michael@0 153 }
michael@0 154
michael@0 155 /* Invariant: fWeakCnt = #weak + (fRefCnt > 0 ? 1 : 0) */
michael@0 156 mutable int32_t fWeakCnt;
michael@0 157
michael@0 158 typedef SkRefCnt INHERITED;
michael@0 159 };
michael@0 160
michael@0 161 #endif

mercurial