You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@corinthia.apache.org by pm...@apache.org on 2015/07/29 15:38:21 UTC

incubator-corinthia git commit: Get weak references working

Repository: incubator-corinthia
Updated Branches:
  refs/heads/master 40310dcb8 -> dc46348ec


Get weak references working


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

Branch: refs/heads/master
Commit: dc46348ec65eb778e8ee3e73f7fd3d7756b3e98a
Parents: 40310dc
Author: Peter Kelly <pe...@uxproductivity.com>
Authored: Wed Jul 29 20:38:06 2015 +0700
Committer: Peter Kelly <pe...@uxproductivity.com>
Committed: Wed Jul 29 20:38:06 2015 +0700

----------------------------------------------------------------------
 ui/src/AShared.cpp | 56 +++++++++++++++++++++++++++++++++++++---------
 ui/src/AShared.h   | 59 ++++++++++++++++++++++++++++---------------------
 ui/src/uitest.cpp  | 55 ++++++++++++++++++++++++++++++++-------------
 3 files changed, 120 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/dc46348e/ui/src/AShared.cpp
----------------------------------------------------------------------
diff --git a/ui/src/AShared.cpp b/ui/src/AShared.cpp
index 1886916..d8fd5f4 100644
--- a/ui/src/AShared.cpp
+++ b/ui/src/AShared.cpp
@@ -25,24 +25,60 @@
 //                                                                                                //
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-void AShared::ref()
+AShared::AShared()
+    : _refCount(0)
 {
-    _refCount++;
-    printf("%p ref():   now _refCount = %d\n",this,_refCount);
 }
 
-void AShared::deref()
+AShared::~AShared()
 {
-    _refCount--;
-    printf("%p deref(): now _refCount = %d\n",this,_refCount);
-    if (_refCount == 0)
-        delete this;
+    AWeakRefData *ref = _weakRefs.first;
+    while (ref != NULL) {
+        AWeakRefData *next = ref->next;
+        ref->ptr = NULL;
+        ref->prev = NULL;
+        ref->next = NULL;
+        ref = next;
+    }
 }
 
-void AShared::addWeakRef(AWeakRefData *wref)
+int AShared::weakRefCount() const
 {
+    int count = 0;
+    for (AWeakRefData *d = _weakRefs.first; d != NULL; d = d->next)
+        count++;
+    return count;
 }
 
-void AShared::removeWeakRef(AWeakRefData *wref)
+void AShared::addWeakRef(AWeakRefData *ref)
 {
+    ref->ptr = this;
+
+    assert(!ref->prev && !ref->next);
+    if (_weakRefs.last) {
+        ref->prev = _weakRefs.last;
+        _weakRefs.last->next = ref;
+        _weakRefs.last = ref;
+    }
+    else {
+        _weakRefs.first = _weakRefs.last = ref;
+    }
+}
+
+void AShared::removeWeakRef(AWeakRefData *ref)
+{
+    ref->ptr = NULL;
+
+    assert(ref->prev || (_weakRefs.first == ref));
+    assert(ref->next || (_weakRefs.last == ref));
+    if (_weakRefs.first == ref)
+        _weakRefs.first = ref->next;
+    if (_weakRefs.last == ref)
+        _weakRefs.last = ref->prev;
+    if (ref->next)
+        ref->next->prev = ref->prev;
+    if (ref->prev)
+        ref->prev->next = ref->next;
+    ref->next = NULL;
+    ref->prev = NULL;
 }

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/dc46348e/ui/src/AShared.h
----------------------------------------------------------------------
diff --git a/ui/src/AShared.h b/ui/src/AShared.h
index c8de282..ece97d2 100644
--- a/ui/src/AShared.h
+++ b/ui/src/AShared.h
@@ -18,6 +18,9 @@
 #pragma once
 
 #include <stddef.h>
+#include <stdio.h>
+
+class AShared;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 //                                                                                                //
@@ -27,10 +30,18 @@
 
 struct AWeakRefData
 {
-    AWeakRefData() : ptr(NULL), prev(NULL), next(NULL) { }
-    void *ptr;
+    AWeakRefData(void *_back) : ptr(NULL), prev(NULL), next(NULL), back(_back) { }
+    AShared *ptr;
     AWeakRefData *prev;
     AWeakRefData *next;
+    void *back;
+};
+
+struct AWeakRefDataList
+{
+    AWeakRefDataList() : first(NULL), last(NULL) { }
+    AWeakRefData *first;
+    AWeakRefData *last;
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -42,21 +53,20 @@ struct AWeakRefData
 class AShared
 {
 public:
-    AShared() : _refCount(0) { }
-    virtual ~AShared() { }
+    AShared();
+    virtual ~AShared();
 
-    void ref();
-    void deref();
+    void ref() { _refCount++; }
+    void deref() { _refCount--; if (_refCount == 0) delete this; }
+    int refCount() const { return _refCount; }
 
-    void addWeakRef(AWeakRefData *wref);
-    void removeWeakRef(AWeakRefData *wref);
+    void addWeakRef(AWeakRefData *ref);
+    void removeWeakRef(AWeakRefData *ref);
+    int weakRefCount() const;
 
 private:
     int _refCount;
-    struct {
-        AWeakRefData *first;
-        AWeakRefData *last;
-    } _weakRefs;
+    AWeakRefDataList _weakRefs;
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -107,31 +117,30 @@ template<class T>
 class AWeakRef
 {
 public:
-    AWeakRef() : _ptr(NULL) { }
-    AWeakRef(T *ptr) : _ptr(NULL) { setPtr(ptr); }
-    AWeakRef(const AWeakRef<T> &other) : _ptr(NULL) { setPtr(other._ptr); }
+    AWeakRef() : _data(this) { }
+    AWeakRef(T *ptr) : _data(this) { setPtr(ptr); }
+    AWeakRef(const AWeakRef<T> &other) : _data(this) { setPtr(other._data.ptr); }
     ~AWeakRef() { setPtr(NULL); }
 
     AWeakRef &operator=(const AWeakRef<T> &other) {
-        setPtr(other._ptr);
+        setPtr(other._data.ptr);
         return *this;
     }
 
-    T &operator*() const { return *_ptr; }
-    T *operator->() const { return _ptr; }
-    T *ptr() const { return _ptr; }
-    bool isNull() const { return (_ptr == NULL); }
+    T &operator*() const { return *(static_cast<T*>(_data.ptr)); }
+    T *operator->() const { return static_cast<T*>(_data.ptr); }
+    T *ptr() const { return static_cast<T*>(_data.ptr); }
+    bool isNull() const { return (_data.ptr == NULL); }
 
-    void setPtr(T *newPtr) {
-        T *oldPtr = _ptr;
+    void setPtr(AShared *newPtr) {
+        AShared *oldPtr = _data.ptr;
         if (oldPtr != NULL)
             oldPtr->removeWeakRef(&_data);
         if (newPtr != NULL)
             newPtr->addWeakRef(&_data);
-        _ptr = newPtr;
+        _data.ptr = newPtr;
     }
 
- private:
-    T *_ptr;
+private:
     AWeakRefData _data;
 };

http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/dc46348e/ui/src/uitest.cpp
----------------------------------------------------------------------
diff --git a/ui/src/uitest.cpp b/ui/src/uitest.cpp
index ee9c09f..debd85e 100644
--- a/ui/src/uitest.cpp
+++ b/ui/src/uitest.cpp
@@ -19,11 +19,19 @@
 #include "AView.h"
 #include "AString.h"
 
+int fooInstances = 0;
+
 class Foo : public AShared
 {
 public:
-    Foo(int value) : x(value) { printf("%p Foo::Foo()\n",this); }
-    virtual ~Foo() { printf("%p Foo::~Foo()\n",this); }
+    Foo(int value) : x(value) {
+        printf("    %p Foo::Foo()\n",this);
+        fooInstances++;
+    }
+    virtual ~Foo() {
+        printf("    %p Foo::~Foo()\n",this);
+        fooInstances--;
+    }
     int x;
     void print() {
         printf("x = %d\n",x);
@@ -50,26 +58,43 @@ public:
 
 int main(int argc, const char **argv)
 {
-    printf("Hello World\n");
+    printf("step 0\n");
     Foo *f = new Foo(4);
-    printf("f = %p\n",f);
+    printf("    f = %p\n",f);
 
     StrongHolder *s1 = new StrongHolder();
-    /*
     StrongHolder *s2 = new StrongHolder();
-    StrongHolder *s3 = new StrongHolder();
+
     WeakHolder *w1 = new WeakHolder();
     WeakHolder *w2 = new WeakHolder();
-    WeakHolder *w3 = new WeakHolder();
-    */
-    printf("s1 = %p\n",s1);
 
-    printf("s1->ref.ptr() = %p\n",s1->ref.ptr());
-    printf("before\n");
-    s1->ref = f;
-    printf("after\n");
-    printf("s1->ref.ptr() = %p\n",s1->ref.ptr());
-    //    printf("s1->ref.ptr()->x = %d\n",s1->ref.ptr()->x);
+    printf("step 1\n");
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    s1->ref = f; // Should bring refCount to 1
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    printf("step 2\n");
+    s2->ref = f; // Should bring refCount to 2
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    printf("step 3\n");
+    w1->ref = f; // Should bring weakRefCount to 1
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    printf("step 4\n");
+    w2->ref = f; // Should bring weakRefCount to 2
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    printf("step 5\n");
+    delete s1; // Should bring refCount to 1
+    printf("    instances=%d, strong=%d, weak=%d, w1=%p, w2=%p\n",
+           fooInstances,f->refCount(),f->weakRefCount(),w1->ref.ptr(),w2->ref.ptr());
+    printf("step 6\n");
+    delete s2; // Should bring refCount to 0, deleting Foo, and clearing weak references
+    printf("    instances=%d w1=%p, w2=%p\n",
+           fooInstances,w1->ref.ptr(),w2->ref.ptr());
+    printf("done\n");
 
     return 0;
 }