TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / android / opengl / shared / OpenglCodecCommon / SmartPtr.h
diff --git a/src/type3_AndroidCloud/anbox-master/android/opengl/shared/OpenglCodecCommon/SmartPtr.h b/src/type3_AndroidCloud/anbox-master/android/opengl/shared/OpenglCodecCommon/SmartPtr.h
new file mode 100644 (file)
index 0000000..4bdfbe4
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef __SMART_PTR_H
+#define __SMART_PTR_H
+
+#include <cutils/threads.h>
+#include <cutils/atomic.h>
+
+template <class T, bool threadSafe = false>
+class SmartPtr
+{
+public:
+    explicit SmartPtr(T* ptr = (T*)NULL) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_ptr = ptr;
+        if (ptr)
+           m_pRefCount = new int32_t(1);
+        else
+           m_pRefCount = NULL;
+    }
+
+    SmartPtr<T,threadSafe>(const SmartPtr<T,false>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+    }
+
+    SmartPtr<T,threadSafe>(SmartPtr<T,true>& rhs) {
+        if (threadSafe) {
+            m_lock = new mutex_t;
+            mutex_init(m_lock);
+        }
+        else m_lock = NULL;
+
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+    }
+
+    ~SmartPtr() {
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (m_lock)
+        {
+            mutex_unlock(m_lock);
+            mutex_destroy(m_lock);
+            delete m_lock;
+        }
+    }
+
+    T* Ptr() const {
+        return m_ptr;
+    }
+
+    const T* constPtr() const
+    {
+        return m_ptr;
+    }
+
+    T* operator->() const {
+        return m_ptr;
+    }
+
+    T& operator*() const {
+        return *m_ptr;
+    }
+
+    operator void*() const {
+        return (void *)m_ptr;
+    }
+
+    // This gives STL lists something to compare.
+    bool operator <(const SmartPtr<T>& t1) const {
+        return m_ptr < t1.m_ptr;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(const SmartPtr<T,false>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+    SmartPtr<T,threadSafe>& operator=(SmartPtr<T,true>& rhs)
+    {
+        if (m_ptr == rhs.m_ptr)
+            return *this;
+
+        if (m_lock) mutex_lock(m_lock);
+        release();
+        if (rhs.m_lock) mutex_lock(rhs.m_lock);
+        m_pRefCount = rhs.m_pRefCount;
+        m_ptr       = rhs.m_ptr;
+        use();
+        if (rhs.m_lock) mutex_unlock(rhs.m_lock);
+        if (m_lock) mutex_unlock(m_lock);
+
+        return *this;
+    }
+
+private:
+    int32_t  *m_pRefCount;
+    mutex_t  *m_lock;
+    T* m_ptr;
+
+    // Increment the reference count on this pointer by 1.
+    int use() {
+        if (!m_pRefCount) return 0;
+        return android_atomic_inc(m_pRefCount) + 1;
+    }
+
+    // Decrement the reference count on the pointer by 1.
+    // If the reference count goes to (or below) 0, the pointer is deleted.
+    int release() {
+        if (!m_pRefCount) return 0;
+
+        int iVal = android_atomic_dec(m_pRefCount);
+        if (iVal > 1)
+            return iVal - 1;
+
+        delete m_pRefCount;
+        m_pRefCount = NULL;
+
+        if (m_ptr) {
+            delete m_ptr;
+            m_ptr = NULL;
+        }
+        return 0;
+    }
+
+};
+
+#endif // of  __SMART_PTR_H