ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shro...@apache.org
Subject [31/50] [abbrv] ignite git commit: IGNITE-2981: CPP: Added "EnableSharedFromThis" entity. This closes #636.
Date Tue, 01 Nov 2016 02:37:50 GMT
IGNITE-2981: CPP: Added "EnableSharedFromThis" entity. This closes #636.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bb5cd16a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bb5cd16a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bb5cd16a

Branch: refs/heads/ignite-2788
Commit: bb5cd16ac49f5804dc870a0aee1b8521e30070bb
Parents: fdb2f64
Author: Igor Sapego <isapego@gridgain.com>
Authored: Wed Apr 27 11:34:44 2016 +0300
Committer: shtykh_roman <rshtykh@yahoo.com>
Committed: Fri May 13 16:11:15 2016 +0900

----------------------------------------------------------------------
 .../common/include/ignite/common/concurrent.h   | 176 ++++++++++++++++---
 modules/platforms/cpp/common/src/concurrent.cpp |  13 +-
 .../cpp/core-test/src/concurrent_test.cpp       |  93 ++++++++++
 3 files changed, 253 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/bb5cd16a/modules/platforms/cpp/common/include/ignite/common/concurrent.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/concurrent.h b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
index a4cc3f7..1c84cf5 100644
--- a/modules/platforms/cpp/common/include/ignite/common/concurrent.h
+++ b/modules/platforms/cpp/common/include/ignite/common/concurrent.h
@@ -18,6 +18,8 @@
 #ifndef _IGNITE_COMMON_CONCURRENT
 #define _IGNITE_COMMON_CONCURRENT
 
+#include <cassert>
+
 #include "ignite/common/concurrent_os.h"
 
 namespace ignite
@@ -43,12 +45,13 @@ namespace ignite
             class IGNITE_IMPORT_EXPORT SharedPointerImpl
             {
             public:
+                typedef void(*DeleterType)(void*);
                 /**
                  * Constructor.
                  *
                  * @param ptr Raw pointer.
                  */
-                SharedPointerImpl(void* ptr);
+                SharedPointerImpl(void* ptr, DeleterType deleter);
 
                 /**
                  * Get raw pointer.
@@ -65,6 +68,13 @@ namespace ignite
                 const void* Pointer() const;
 
                 /**
+                 * Get raw pointer.
+                 *
+                 * @return Raw pointer.
+                 */
+                DeleterType Deleter();
+
+                /**
                  * Increment usage counter.
                  */
                 void Increment();
@@ -79,12 +89,29 @@ namespace ignite
                 /** Raw pointer. */
                 void* ptr;
 
+                /** Deleter. */
+                DeleterType deleter;
+
                 /** Reference count. */
                 int32_t refCnt;
 
                 IGNITE_NO_COPY_ASSIGNMENT(SharedPointerImpl)
             };
 
+            /* Forward declaration. */
+            template<typename T>
+            class IGNITE_IMPORT_EXPORT EnableSharedFromThis;
+
+            /* Forward declaration. */
+            template<typename T>
+            inline void ImplEnableShared(EnableSharedFromThis<T>* some, SharedPointerImpl*
impl);
+
+            // Do nothing if the instance is not derived from EnableSharedFromThis.
+            inline void ImplEnableShared(const volatile void*, const volatile void*)
+            {
+                // No-op.
+            }
+
             /**
              * Shared pointer.
              */
@@ -92,10 +119,12 @@ namespace ignite
             class IGNITE_IMPORT_EXPORT SharedPointer
             {
             public:
+                friend class EnableSharedFromThis<T>;
+
                 /**
                  * Constructor.
                  */
-                SharedPointer() : impl(NULL), deleter(NULL)
+                SharedPointer() : impl(0)
                 {
                     // No-op.
                 }
@@ -109,14 +138,11 @@ namespace ignite
                 {
                     if (ptr)
                     {
-                        impl = new SharedPointerImpl(ptr);
-                        deleter = SharedPointerDefaultDeleter;
+                        impl = new SharedPointerImpl(ptr, reinterpret_cast<SharedPointerImpl::DeleterType>(&SharedPointerDefaultDeleter<T>));
+                        ImplEnableShared(ptr, impl);
                     }
                     else
-                    {
-                        impl = NULL;
-                        deleter = NULL;
-                    }
+                        impl = 0;
                 }
 
                 /**
@@ -129,14 +155,11 @@ namespace ignite
                 {
                     if (ptr)
                     {
-                        this->impl = new SharedPointerImpl(ptr);
-                        this->deleter = deleter;
+                        impl = new SharedPointerImpl(ptr, reinterpret_cast<SharedPointerImpl::DeleterType>(deleter));
+                        ImplEnableShared(ptr, impl);
                     }
                     else
-                    {
-                        this->impl = NULL;
-                        this->deleter = NULL;
-                    }
+                        impl = 0;
                 }
 
                 /**
@@ -147,7 +170,6 @@ namespace ignite
                 SharedPointer(const SharedPointer& other)
                 {
                     impl = other.impl;
-                    deleter = other.deleter;
 
                     if (impl)
                         impl->Increment();
@@ -162,18 +184,9 @@ namespace ignite
                 {
                     if (this != &other)
                     {
-                        // 1. Create new instance.
                         SharedPointer tmp(other);
 
-                        // 2. Swap with temp.
-                        SharedPointerImpl* impl0 = impl;
-                        void(*deleter0)(T*) = deleter;
-
-                        impl = tmp.impl;
-                        deleter = tmp.deleter;
-
-                        tmp.impl = impl0;
-                        tmp.deleter = deleter0;
+                        std::swap(impl, tmp.impl);
                     }
 
                     return *this;
@@ -188,9 +201,11 @@ namespace ignite
                     {
                         T* ptr = Get();
 
-                        delete impl;
+                        void(*deleter)(T*) = reinterpret_cast<void(*)(T*)>(impl->Deleter());
 
                         deleter(ptr);
+
+                        delete impl;
                     }
                 }
 
@@ -226,10 +241,115 @@ namespace ignite
             private:
                 /** Implementation. */
                 SharedPointerImpl* impl;
+            };
+
+            /**
+             * The class provides functionality that allows objects of derived
+             * classes to create instances of shared_ptr pointing to themselves
+             * and sharing ownership with existing shared_ptr objects.
+             */
+            template<typename T>
+            class IGNITE_IMPORT_EXPORT EnableSharedFromThis
+            {
+            public:
+                /**
+                 * Default constructor.
+                 */
+                EnableSharedFromThis() : self(0)
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Copy constructor.
+                 */
+                EnableSharedFromThis(const EnableSharedFromThis&) : self(0)
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Assignment operator.
+                 */
+                EnableSharedFromThis& operator=(const EnableSharedFromThis&)
+                {
+                    return *this;
+                }
+
+                /**
+                 * Destructor.
+                 */
+                virtual ~EnableSharedFromThis()
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Create shared pointer for this instance.
+                 *
+                 * Can only be called on already shared object.
+                 * @return New shared pointer instance.
+                 */
+                SharedPointer<T> SharedFromThis()
+                {
+                    assert(self != 0);
+
+                    SharedPointer<T> ptr;
+
+                    ptr.impl = self;
+
+                    self->Increment();
+
+                    return ptr;
+                }
+
+            private:
+                template<typename T0>
+                friend void ImplEnableShared(EnableSharedFromThis<T0>*, SharedPointerImpl*);
+
+                /** Shared pointer base. */
+                SharedPointerImpl* self;
+            };
 
-                /** Delete function. */
-                void(*deleter)(T*);
+            // Implementation for instances derived from EnableSharedFromThis.
+            template<typename T>
+            inline void ImplEnableShared(EnableSharedFromThis<T>* some, SharedPointerImpl*
impl)
+            {
+                if (some)
+                    some->self = impl;
+            }
+
+            /**
+             * Lock guard.
+             */
+            template<typename T>
+            class LockGuard
+            {
+            public:
+                /**
+                 * Constructor.
+                 *
+                 * @param lock Lockable object.
+                 */
+                LockGuard(T& lock) :
+                    lock(lock)
+                {
+                    lock.Enter();
+                }
+
+                /**
+                 * Destructor.
+                 */
+                ~LockGuard()
+                {
+                    lock.Leave();
+                }
+
+            private:
+                T& lock;
             };
+
+            typedef LockGuard<CriticalSection> CsLockGuard;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb5cd16a/modules/platforms/cpp/common/src/concurrent.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/src/concurrent.cpp b/modules/platforms/cpp/common/src/concurrent.cpp
index 3f85b65..5b62387 100644
--- a/modules/platforms/cpp/common/src/concurrent.cpp
+++ b/modules/platforms/cpp/common/src/concurrent.cpp
@@ -70,7 +70,8 @@ namespace ignite
                 }
             }
 
-            SharedPointerImpl::SharedPointerImpl(void* ptr) : ptr(ptr), refCnt(1)
+            SharedPointerImpl::SharedPointerImpl(void* ptr, DeleterType deleter) :
+                ptr(ptr), deleter(deleter), refCnt(1)
             {
                 Memory::Fence();
             }
@@ -80,6 +81,16 @@ namespace ignite
                 return ptr;
             }
 
+            const void* SharedPointerImpl::Pointer() const
+            {
+                return ptr;
+            }
+
+            SharedPointerImpl::DeleterType SharedPointerImpl::Deleter()
+            {
+                return deleter;
+            }
+
             void SharedPointerImpl::Increment()
             {
                 Atomics::IncrementAndGet32(&refCnt);

http://git-wip-us.apache.org/repos/asf/ignite/blob/bb5cd16a/modules/platforms/cpp/core-test/src/concurrent_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/concurrent_test.cpp b/modules/platforms/cpp/core-test/src/concurrent_test.cpp
index 2d89b7a..173973d 100644
--- a/modules/platforms/cpp/core-test/src/concurrent_test.cpp
+++ b/modules/platforms/cpp/core-test/src/concurrent_test.cpp
@@ -183,4 +183,97 @@ BOOST_AUTO_TEST_CASE(TestSharedPointer)
     delete target;    
 }
 
+struct SharedPointerTargetFromThis : public EnableSharedFromThis<SharedPointerTargetFromThis>
+{
+    bool& deleted;
+
+    SharedPointerTargetFromThis(bool& deleted) : deleted(deleted)
+    {
+        deleted = false;
+    }
+};
+
+void DeleteSharedPointerTarget(SharedPointerTargetFromThis* ptr)
+{
+    ptr->deleted = true;
+    delete ptr;
+}
+
+BOOST_AUTO_TEST_CASE(TestEnableSharedFromThis)
+{
+    typedef SharedPointerTargetFromThis TestT;
+
+    bool deleted;
+
+    // 1. Test the simple scenario.
+    TestT* target = new TestT(deleted);
+    BOOST_CHECK(!deleted);
+
+    SharedPointer<TestT>* ptr1 = new SharedPointer<TestT>(target, DeleteSharedPointerTarget);
+    BOOST_CHECK(!deleted);
+
+    delete ptr1;
+    BOOST_CHECK(deleted);
+
+    // 2. Test copy ctor.
+    target = new TestT(deleted);
+    BOOST_CHECK(!deleted);
+
+    ptr1 = new SharedPointer<TestT>(target, DeleteSharedPointerTarget);
+    BOOST_CHECK(!deleted);
+
+    SharedPointer<TestT>* ptr2 = new SharedPointer<TestT>(*ptr1);
+    BOOST_CHECK(!deleted);
+
+    delete ptr1;
+    BOOST_CHECK(!deleted);
+
+    delete ptr2;
+    BOOST_CHECK(deleted);
+
+    // 3. Test assignment logic.
+    target = new TestT(deleted);
+    BOOST_CHECK(!deleted);
+
+    ptr1 = new SharedPointer<TestT>(target, DeleteSharedPointerTarget);
+    BOOST_CHECK(!deleted);
+
+    SharedPointer<TestT> ptr3 = *ptr1;
+    BOOST_CHECK(!deleted);
+
+    delete ptr1;
+    BOOST_CHECK(!deleted);
+
+    ptr3 = SharedPointer<TestT>();
+    BOOST_CHECK(deleted);
+
+    // 4. Test self-assignment.
+    target = new TestT(deleted);
+    BOOST_CHECK(!deleted);
+
+    ptr1 = new SharedPointer<TestT>(target, DeleteSharedPointerTarget);
+
+    *ptr1 = *ptr1;
+
+    delete ptr1;
+
+    BOOST_CHECK(deleted);
+
+    // 5. Test shared from this
+    target = new TestT(deleted);
+    BOOST_CHECK(!deleted);
+
+    ptr1 = new SharedPointer<TestT>(target, DeleteSharedPointerTarget);
+    BOOST_CHECK(!deleted);
+
+    ptr3 = target->SharedFromThis();
+    BOOST_CHECK(!deleted);
+
+    delete ptr1;
+    BOOST_CHECK(!deleted);
+
+    ptr3 = SharedPointer<TestT>();
+    BOOST_CHECK(deleted);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file


Mime
View raw message