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;
}