| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright (C) 2010 Google Inc. All rights reserved. |    2  * Copyright (C) 2010 Google Inc. All rights reserved. | 
|    3  * |    3  * | 
|    4  * Redistribution and use in source and binary forms, with or without |    4  * Redistribution and use in source and binary forms, with or without | 
|    5  * modification, are permitted provided that the following conditions are |    5  * modification, are permitted provided that the following conditions are | 
|    6  * met: |    6  * met: | 
|    7  * |    7  * | 
|    8  *     * Redistributions of source code must retain the above copyright |    8  *     * Redistributions of source code must retain the above copyright | 
|    9  * notice, this list of conditions and the following disclaimer. |    9  * notice, this list of conditions and the following disclaimer. | 
|   10  *     * Redistributions in binary form must reproduce the above |   10  *     * Redistributions in binary form must reproduce the above | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   32 #define WebPrivatePtr_h |   32 #define WebPrivatePtr_h | 
|   33  |   33  | 
|   34 #include "WebCommon.h" |   34 #include "WebCommon.h" | 
|   35  |   35  | 
|   36 #if INSIDE_BLINK |   36 #if INSIDE_BLINK | 
|   37 #include "platform/heap/Handle.h" |   37 #include "platform/heap/Handle.h" | 
|   38 #include "wtf/PassRefPtr.h" |   38 #include "wtf/PassRefPtr.h" | 
|   39 #include "wtf/TypeTraits.h" |   39 #include "wtf/TypeTraits.h" | 
|   40 #endif |   40 #endif | 
|   41  |   41  | 
 |   42 namespace WTF { | 
 |   43 template<class T> class ThreadSafeRefCounted; | 
 |   44 } | 
 |   45  | 
|   42 namespace blink { |   46 namespace blink { | 
|   43  |   47  | 
 |   48 // By default, the destruction of a WebPrivatePtr<> must happen on the same | 
 |   49 // thread that created it, but can optionally be allowed to happen on | 
 |   50 // another thread. | 
 |   51 enum WebPrivatePtrDestruction { | 
 |   52     WebPrivatePtrDestructionSameThread, | 
 |   53     WebPrivatePtrDestructionCrossThread, | 
 |   54 }; | 
 |   55  | 
|   44 #if INSIDE_BLINK |   56 #if INSIDE_BLINK | 
|   45 enum LifetimeManagementType { |   57 enum LifetimeManagementType { | 
|   46     RefCountedLifetime, |   58     RefCountedLifetime, | 
|   47     GarbageCollectedLifetime, |   59     GarbageCollectedLifetime, | 
|   48     RefCountedGarbageCollectedLifetime |   60     RefCountedGarbageCollectedLifetime | 
|   49 }; |   61 }; | 
|   50  |   62  | 
|   51 template<typename T> |   63 template<typename T> | 
|   52 class LifetimeOf { |   64 class LifetimeOf { | 
|   53     static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, GarbageC
     ollected>::value || IsGarbageCollectedMixin<T>::value; |   65     static const bool isGarbageCollected = WTF::IsSubclassOfTemplate<T, GarbageC
     ollected>::value || IsGarbageCollectedMixin<T>::value; | 
|   54     static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T
     , RefCountedGarbageCollected>::value; |   66     static const bool isRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T
     , RefCountedGarbageCollected>::value; | 
|   55 public: |   67 public: | 
|   56     static const LifetimeManagementType value = |   68     static const LifetimeManagementType value = | 
|   57         !isGarbageCollected ? RefCountedLifetime : |   69         !isGarbageCollected ? RefCountedLifetime : | 
|   58         isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : Garb
     ageCollectedLifetime; |   70         isRefCountedGarbageCollected ? RefCountedGarbageCollectedLifetime : Garb
     ageCollectedLifetime; | 
|   59 }; |   71 }; | 
|   60  |   72  | 
|   61 template<typename T, LifetimeManagementType lifetime> |   73 template<typename T, WebPrivatePtrDestruction crossThreadDestruction, LifetimeMa
     nagementType lifetime> | 
|   62 class PtrStorageImpl; |   74 class PtrStorageImpl; | 
|   63  |   75  | 
|   64 template<typename T> |   76 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 
|   65 class PtrStorageImpl<T, RefCountedLifetime> { |   77 class PtrStorageImpl<T, crossThreadDestruction, RefCountedLifetime> { | 
|   66 public: |   78 public: | 
|   67     typedef PassRefPtr<T> BlinkPtrType; |   79     typedef PassRefPtr<T> BlinkPtrType; | 
|   68  |   80  | 
|   69     void assign(const BlinkPtrType& val) |   81     void assign(const BlinkPtrType& val) | 
|   70     { |   82     { | 
 |   83         static_assert(crossThreadDestruction == WebPrivatePtrDestructionSameThre
     ad || WTF::IsSubclassOfTemplate<T, WTF::ThreadSafeRefCounted>::value, "Cross thr
     ead destructible class must derive from ThreadSafeRefCounted<>"); | 
|   71         release(); |   84         release(); | 
|   72         m_ptr = val.leakRef(); |   85         m_ptr = val.leakRef(); | 
|   73     } |   86     } | 
|   74  |   87  | 
|   75     void assign(const PtrStorageImpl& other) |   88     void assign(const PtrStorageImpl& other) | 
|   76     { |   89     { | 
|   77         release(); |   90         release(); | 
|   78         T* val = other.get(); |   91         T* val = other.get(); | 
|   79         WTF::refIfNotNull(val); |   92         WTF::refIfNotNull(val); | 
|   80         m_ptr = val; |   93         m_ptr = val; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   92     void release() |  105     void release() | 
|   93     { |  106     { | 
|   94         WTF::derefIfNotNull(m_ptr); |  107         WTF::derefIfNotNull(m_ptr); | 
|   95         m_ptr = 0; |  108         m_ptr = 0; | 
|   96     } |  109     } | 
|   97  |  110  | 
|   98 private: |  111 private: | 
|   99     T* m_ptr; |  112     T* m_ptr; | 
|  100 }; |  113 }; | 
|  101  |  114  | 
|  102 template<typename T> |  115 template <typename T, WebPrivatePtrDestruction> | 
|  103 class PtrStorageImpl<T, GarbageCollectedLifetime> { |  116 struct WebPrivatePtrPersistentStorageType { | 
 |  117 public: | 
 |  118     using Type = Persistent<T>; | 
 |  119 }; | 
 |  120  | 
 |  121 template <typename T> | 
 |  122 struct WebPrivatePtrPersistentStorageType<T, WebPrivatePtrDestructionCrossThread
     > { | 
 |  123 public: | 
 |  124     using Type = CrossThreadPersistent<T>; | 
 |  125 }; | 
 |  126  | 
 |  127 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 
 |  128 class PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime> { | 
|  104 public: |  129 public: | 
|  105     void assign(const RawPtr<T>& val) |  130     void assign(const RawPtr<T>& val) | 
|  106     { |  131     { | 
|  107         if (!val) { |  132         if (!val) { | 
|  108             release(); |  133             release(); | 
|  109             return; |  134             return; | 
|  110         } |  135         } | 
|  111  |  136  | 
|  112         if (!m_handle) |  137         if (!m_handle) | 
|  113             m_handle = new Persistent<T>(); |  138             m_handle = new (typename WebPrivatePtrPersistentStorageType<T, cross
     ThreadDestruction>::Type)(); | 
|  114  |  139  | 
|  115         (*m_handle) = val; |  140         (*m_handle) = val; | 
|  116     } |  141     } | 
|  117  |  142  | 
|  118     void assign(T* ptr) { assign(RawPtr<T>(ptr)); } |  143     void assign(T* ptr) { assign(RawPtr<T>(ptr)); } | 
|  119     template<typename U> void assign(const RawPtr<U>& val) { assign(RawPtr<T>(va
     l)); } |  144     template<typename U> void assign(const RawPtr<U>& val) { assign(RawPtr<T>(va
     l)); } | 
|  120  |  145  | 
|  121     void assign(const PtrStorageImpl& other) { assign(other.get()); } |  146     void assign(const PtrStorageImpl& other) { assign(other.get()); } | 
|  122  |  147  | 
|  123     void moveFrom(PtrStorageImpl& other) |  148     void moveFrom(PtrStorageImpl& other) | 
|  124     { |  149     { | 
|  125         release(); |  150         release(); | 
|  126         m_handle = other.m_handle; |  151         m_handle = other.m_handle; | 
|  127         other.m_handle = 0; |  152         other.m_handle = 0; | 
|  128     } |  153     } | 
|  129  |  154  | 
|  130     T* get() const { return m_handle ? m_handle->get() : 0; } |  155     T* get() const { return m_handle ? m_handle->get() : 0; } | 
|  131  |  156  | 
|  132     void release() |  157     void release() | 
|  133     { |  158     { | 
|  134         delete m_handle; |  159         delete m_handle; | 
|  135         m_handle = 0; |  160         m_handle = 0; | 
|  136     } |  161     } | 
|  137  |  162  | 
|  138 private: |  163 private: | 
|  139     Persistent<T>* m_handle; |  164     typename WebPrivatePtrPersistentStorageType<T, crossThreadDestruction>::Type
     * m_handle; | 
|  140 }; |  165 }; | 
|  141  |  166  | 
|  142 template<typename T> |  167 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 
|  143 class PtrStorageImpl<T, RefCountedGarbageCollectedLifetime> : public PtrStorageI
     mpl<T, GarbageCollectedLifetime> { |  168 class PtrStorageImpl<T, crossThreadDestruction, RefCountedGarbageCollectedLifeti
     me> : public PtrStorageImpl<T, crossThreadDestruction, GarbageCollectedLifetime>
      { | 
|  144 public: |  169 public: | 
|  145     void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, Garbag
     eCollectedLifetime>::assign(val.get()); } |  170     void assign(const PassRefPtrWillBeRawPtr<T>& val) { PtrStorageImpl<T, crossT
     hreadDestruction, GarbageCollectedLifetime>::assign(val.get()); } | 
|  146  |  171  | 
|  147     void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, GarbageCollecte
     dLifetime>::assign(other.get()); } |  172     void assign(const PtrStorageImpl& other) { PtrStorageImpl<T, crossThreadDest
     ruction, GarbageCollectedLifetime>::assign(other.get()); } | 
|  148 }; |  173 }; | 
|  149  |  174  | 
|  150 template<typename T> |  175 template<typename T, WebPrivatePtrDestruction crossThreadDestruction> | 
|  151 class PtrStorage : public PtrStorageImpl<T, LifetimeOf<T>::value> { |  176 class PtrStorage : public PtrStorageImpl<T, crossThreadDestruction, LifetimeOf<T
     >::value> { | 
|  152 public: |  177 public: | 
|  153     static PtrStorage& fromSlot(void** slot) |  178     static PtrStorage& fromSlot(void** slot) | 
|  154     { |  179     { | 
|  155         static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t
     he size of a pointer"); |  180         static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t
     he size of a pointer"); | 
|  156         return *reinterpret_cast<PtrStorage*>(slot); |  181         return *reinterpret_cast<PtrStorage*>(slot); | 
|  157     } |  182     } | 
|  158  |  183  | 
|  159     static const PtrStorage& fromSlot(void* const* slot) |  184     static const PtrStorage& fromSlot(void* const* slot) | 
|  160     { |  185     { | 
|  161         static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t
     he size of a pointer"); |  186         static_assert(sizeof(PtrStorage) == sizeof(void*), "PtrStorage must be t
     he size of a pointer"); | 
|  162         return *reinterpret_cast<const PtrStorage*>(slot); |  187         return *reinterpret_cast<const PtrStorage*>(slot); | 
|  163     } |  188     } | 
|  164  |  189  | 
|  165 private: |  190 private: | 
|  166     // Prevent construction via normal means. |  191     // Prevent construction via normal means. | 
|  167     PtrStorage(); |  192     PtrStorage(); | 
|  168     PtrStorage(const PtrStorage&); |  193     PtrStorage(const PtrStorage&); | 
|  169 }; |  194 }; | 
|  170 #endif |  195 #endif | 
|  171  |  196  | 
|  172  |  | 
|  173 // This class is an implementation detail of the Blink API. It exists to help |  197 // This class is an implementation detail of the Blink API. It exists to help | 
|  174 // simplify the implementation of Blink interfaces that merely wrap a reference |  198 // simplify the implementation of Blink interfaces that merely wrap a reference | 
|  175 // counted WebCore class. |  199 // counted WebCore class. | 
|  176 // |  200 // | 
|  177 // A typical implementation of a class which uses WebPrivatePtr might look like |  201 // A typical implementation of a class which uses WebPrivatePtr might look like | 
|  178 // this: |  202 // this: | 
|  179 //    class WebFoo { |  203 //    class WebFoo { | 
|  180 //    public: |  204 //    public: | 
|  181 //        BLINK_EXPORT ~WebFoo(); |  205 //        BLINK_EXPORT ~WebFoo(); | 
|  182 //        WebFoo() { } |  206 //        WebFoo() { } | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|  199 //    #endif |  223 //    #endif | 
|  200 // |  224 // | 
|  201 //    private: |  225 //    private: | 
|  202 //        WebPrivatePtr<Foo> m_private; |  226 //        WebPrivatePtr<Foo> m_private; | 
|  203 //    }; |  227 //    }; | 
|  204 // |  228 // | 
|  205 //    // WebFoo.cpp |  229 //    // WebFoo.cpp | 
|  206 //    WebFoo::~WebFoo() { m_private.reset(); } |  230 //    WebFoo::~WebFoo() { m_private.reset(); } | 
|  207 //    void WebFoo::assign(const WebFoo& other) { ... } |  231 //    void WebFoo::assign(const WebFoo& other) { ... } | 
|  208 // |  232 // | 
|  209 template <typename T> |  233 template <typename T, WebPrivatePtrDestruction crossThreadDestruction = WebPriva
     tePtrDestructionSameThread> | 
|  210 class WebPrivatePtr { |  234 class WebPrivatePtr { | 
|  211 public: |  235 public: | 
|  212     WebPrivatePtr() : m_storage(0) { } |  236     WebPrivatePtr() : m_storage(0) { } | 
|  213     ~WebPrivatePtr() |  237     ~WebPrivatePtr() | 
|  214     { |  238     { | 
|  215         // We don't destruct the object pointed by m_ptr here because we don't |  239         // We don't destruct the object pointed by m_ptr here because we don't | 
|  216         // want to expose destructors of core classes to embedders. We should |  240         // want to expose destructors of core classes to embedders. We should | 
|  217         // call reset() manually in destructors of classes with WebPrivatePtr |  241         // call reset() manually in destructors of classes with WebPrivatePtr | 
|  218         // members. |  242         // members. | 
|  219         BLINK_ASSERT(!m_storage); |  243         BLINK_ASSERT(!m_storage); | 
|  220     } |  244     } | 
|  221  |  245  | 
|  222     bool isNull() const { return !m_storage; } |  246     bool isNull() const { return !m_storage; } | 
|  223  |  247  | 
|  224 #if INSIDE_BLINK |  248 #if INSIDE_BLINK | 
|  225     template<typename U> |  249     template<typename U> | 
|  226     WebPrivatePtr(const U& ptr) |  250     WebPrivatePtr(const U& ptr) | 
|  227         : m_storage(0) |  251         : m_storage(0) | 
|  228     { |  252     { | 
|  229         storage().assign(ptr); |  253         storage().assign(ptr); | 
|  230     } |  254     } | 
|  231  |  255  | 
|  232     void reset() { storage().release(); } |  256     void reset() { storage().release(); } | 
|  233  |  257  | 
|  234     WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other) |  258     WebPrivatePtr& operator=(const WebPrivatePtr& other) | 
|  235     { |  259     { | 
|  236         storage().assign(other.storage()); |  260         storage().assign(other.storage()); | 
|  237         return *this; |  261         return *this; | 
|  238     } |  262     } | 
|  239  |  263  | 
|  240     void moveFrom(WebPrivatePtr<T>& other) |  264     void moveFrom(WebPrivatePtr& other) | 
|  241     { |  265     { | 
|  242         storage().moveFrom(other.storage()); |  266         storage().moveFrom(other.storage()); | 
|  243         return; |  267         return; | 
|  244     } |  268     } | 
|  245  |  269  | 
|  246     template<typename U> |  270     template<typename U> | 
|  247     WebPrivatePtr<T>& operator=(const U& ptr) |  271     WebPrivatePtr& operator=(const U& ptr) | 
|  248     { |  272     { | 
|  249         storage().assign(ptr); |  273         storage().assign(ptr); | 
|  250         return *this; |  274         return *this; | 
|  251     } |  275     } | 
|  252  |  276  | 
|  253     T* get() const { return storage().get(); } |  277     T* get() const { return storage().get(); } | 
|  254  |  278  | 
|  255     T& operator*() const |  279     T& operator*() const | 
|  256     { |  280     { | 
|  257         ASSERT(m_storage); |  281         ASSERT(m_storage); | 
|  258         return *get(); |  282         return *get(); | 
|  259     } |  283     } | 
|  260  |  284  | 
|  261     T* operator->() const |  285     T* operator->() const | 
|  262     { |  286     { | 
|  263         ASSERT(m_storage); |  287         ASSERT(m_storage); | 
|  264         return get(); |  288         return get(); | 
|  265     } |  289     } | 
|  266 #endif |  290 #endif | 
|  267  |  291  | 
|  268 private: |  292 private: | 
|  269 #if INSIDE_BLINK |  293 #if INSIDE_BLINK | 
|  270     PtrStorage<T>& storage() { return PtrStorage<T>::fromSlot(&m_storage); } |  294     PtrStorage<T, crossThreadDestruction>& storage() { return PtrStorage<T, cros
     sThreadDestruction>::fromSlot(&m_storage); } | 
|  271     const PtrStorage<T>& storage() const { return PtrStorage<T>::fromSlot(&m_sto
     rage); } |  295     const PtrStorage<T, crossThreadDestruction>& storage() const { return PtrSto
     rage<T, crossThreadDestruction>::fromSlot(&m_storage); } | 
|  272 #endif |  296 #endif | 
|  273  |  297  | 
|  274 #if !INSIDE_BLINK |  298 #if !INSIDE_BLINK | 
|  275     // Disable the assignment operator; we define it above for when |  299     // Disable the assignment operator; we define it above for when | 
|  276     // INSIDE_BLINK is set, but we need to make sure that it is not |  300     // INSIDE_BLINK is set, but we need to make sure that it is not | 
|  277     // used outside there; the compiler-provided version won't handle reference |  301     // used outside there; the compiler-provided version won't handle reference | 
|  278     // counting properly. |  302     // counting properly. | 
|  279     WebPrivatePtr<T>& operator=(const WebPrivatePtr<T>& other); |  303     WebPrivatePtr& operator=(const WebPrivatePtr& other); | 
|  280 #endif |  304 #endif | 
|  281     // Disable the copy constructor; classes that contain a WebPrivatePtr |  305     // Disable the copy constructor; classes that contain a WebPrivatePtr | 
|  282     // should implement their copy constructor using assign(). |  306     // should implement their copy constructor using assign(). | 
|  283     WebPrivatePtr(const WebPrivatePtr<T>&); |  307     WebPrivatePtr(const WebPrivatePtr&); | 
|  284  |  308  | 
|  285     void* m_storage; |  309     void* m_storage; | 
|  286 }; |  310 }; | 
|  287  |  311  | 
|  288 } // namespace blink |  312 } // namespace blink | 
|  289  |  313  | 
|  290 #endif |  314 #endif | 
| OLD | NEW |