You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2014/09/15 21:19:24 UTC
svn commit: r1625120 - in /qpid/proton/trunk/proton-c:
include/proton/cproton.i include/proton/object.h src/messenger/messenger.c
src/object/object.c src/tests/object.c
Author: rhs
Date: Mon Sep 15 19:19:24 2014
New Revision: 1625120
URL: http://svn.apache.org/r1625120
Log:
revised class system to be more extensible
Modified:
qpid/proton/trunk/proton-c/include/proton/cproton.i
qpid/proton/trunk/proton-c/include/proton/object.h
qpid/proton/trunk/proton-c/src/messenger/messenger.c
qpid/proton/trunk/proton-c/src/object/object.c
qpid/proton/trunk/proton-c/src/tests/object.c
Modified: qpid/proton/trunk/proton-c/include/proton/cproton.i
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/cproton.i?rev=1625120&r1=1625119&r2=1625120&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/cproton.i (original)
+++ qpid/proton/trunk/proton-c/include/proton/cproton.i Mon Sep 15 19:19:24 2014
@@ -53,6 +53,8 @@ typedef long long int int64_t;
%include "proton/types.h"
%ignore pn_string_vformat;
%ignore pn_string_vaddf;
+%immutable PN_OBJECT;
+%immutable PN_VOID;
%include "proton/object.h"
%ignore pn_error_format;
Modified: qpid/proton/trunk/proton-c/include/proton/object.h
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/object.h?rev=1625120&r1=1625119&r2=1625120&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/object.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/object.h Mon Sep 15 19:19:24 2014
@@ -35,31 +35,82 @@ extern "C" {
typedef uintptr_t pn_handle_t;
typedef intptr_t pn_shandle_t;
+typedef struct pn_class_t pn_class_t;
+typedef struct pn_string_t pn_string_t;
typedef struct pn_list_t pn_list_t;
typedef struct pn_map_t pn_map_t;
typedef struct pn_hash_t pn_hash_t;
-typedef struct pn_string_t pn_string_t;
typedef void *(*pn_iterator_next_t)(void *state);
typedef struct pn_iterator_t pn_iterator_t;
-typedef struct {
+struct pn_class_t {
const char *name;
+ void *(*newinst)(const pn_class_t *, size_t);
void (*initialize)(void *);
+ void (*incref)(void *);
+ void (*decref)(void *);
+ int (*refcount)(void *);
void (*finalize)(void *);
+ void (*free)(void *);
+ const pn_class_t *(*reify)(void *);
uintptr_t (*hashcode)(void *);
intptr_t (*compare)(void *, void *);
int (*inspect)(void *, pn_string_t *);
-} pn_class_t;
+};
+
+extern const pn_class_t *PN_OBJECT;
+extern const pn_class_t *PN_VOID;
#define PN_CLASS(PREFIX) { \
#PREFIX, \
+ pn_object_new, \
+ PREFIX ## _initialize, \
+ pn_object_incref, \
+ pn_object_decref, \
+ pn_object_refcount, \
+ PREFIX ## _finalize, \
+ pn_object_free, \
+ pn_object_reify, \
+ PREFIX ## _hashcode, \
+ PREFIX ## _compare, \
+ PREFIX ## _inspect \
+}
+
+#define PN_METACLASS(PREFIX) { \
+ #PREFIX, \
+ PREFIX ## _new, \
PREFIX ## _initialize, \
+ PREFIX ## _incref, \
+ PREFIX ## _decref, \
+ PREFIX ## _refcount, \
PREFIX ## _finalize, \
+ PREFIX ## _free, \
+ PREFIX ## _reify, \
PREFIX ## _hashcode, \
PREFIX ## _compare, \
PREFIX ## _inspect \
}
+PN_EXTERN void *pn_class_new(const pn_class_t *clazz, size_t size);
+PN_EXTERN void *pn_class_incref(const pn_class_t *clazz, void *object);
+PN_EXTERN void pn_class_decref(const pn_class_t *clazz, void *object);
+PN_EXTERN void pn_class_free(const pn_class_t *clazz, void *object);
+PN_EXTERN int pn_class_refcount(const pn_class_t *clazz, void *object);
+PN_EXTERN const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object);
+PN_EXTERN uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object);
+PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
+PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
+
+PN_EXTERN void *pn_object_new(const pn_class_t *clazz, size_t size);
+PN_EXTERN const pn_class_t *pn_object_reify(void *object);
+PN_EXTERN void pn_object_incref(void *object);
+PN_EXTERN int pn_object_refcount(void *object);
+PN_EXTERN void pn_object_decref(void *object);
+PN_EXTERN void pn_object_free(void *object);
+PN_EXTERN uintptr_t pn_object_hashcode(void *object);
+PN_EXTERN intptr_t pn_object_compare(void *a, void *b);
+PN_EXTERN int pn_object_inspect(void *object, pn_string_t *dst);
+
PN_EXTERN void *pn_new(size_t size, const pn_class_t* clazz);
PN_EXTERN void *pn_new2(size_t size, const pn_class_t* clazz, void *from);
PN_EXTERN void pn_initialize(void *object, const pn_class_t *clazz);
Modified: qpid/proton/trunk/proton-c/src/messenger/messenger.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/messenger/messenger.c?rev=1625120&r1=1625119&r2=1625120&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/messenger/messenger.c (original)
+++ qpid/proton/trunk/proton-c/src/messenger/messenger.c Mon Sep 15 19:19:24 2014
@@ -375,7 +375,7 @@ static pn_listener_ctx_t *pn_listener_ct
return NULL;
}
- pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) pn_new(sizeof(pn_listener_ctx_t), NULL);
+ pn_listener_ctx_t *ctx = (pn_listener_ctx_t *) pn_new(sizeof(pn_listener_ctx_t), PN_OBJECT);
ctx->messenger = messenger;
ctx->domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
if (messenger->certificate) {
Modified: qpid/proton/trunk/proton-c/src/object/object.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/object/object.c?rev=1625120&r1=1625119&r2=1625120&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Mon Sep 15 19:19:24 2014
@@ -28,6 +28,103 @@
#include <assert.h>
#include <ctype.h>
+#define pn_object_initialize NULL
+#define pn_object_finalize NULL
+
+const pn_class_t PNI_OBJECT = PN_CLASS(pn_object);
+const pn_class_t *PN_OBJECT = &PNI_OBJECT;
+
+#define pn_void_initialize NULL
+static void *pn_void_new(const pn_class_t *clazz, size_t size) { return malloc(size); }
+static void pn_void_incref(void *object) {}
+static void pn_void_decref(void *object) {}
+static int pn_void_refcount(void *object) { return -1; }
+#define pn_void_finalize NULL
+static void pn_void_free(void *object) { free(object); }
+static const pn_class_t *pn_void_reify(void *object) { return PN_VOID; }
+static uintptr_t pn_void_hashcode(void *object) { return (uintptr_t) object; }
+static intptr_t pn_void_compare(void *a, void *b) { return (intptr_t) b - (intptr_t) a; }
+static int pn_void_inspect(void *object, pn_string_t *dst) { return pn_string_addf(dst, "%p", object); }
+
+const pn_class_t PNI_VOID = PN_METACLASS(pn_void);
+const pn_class_t *PN_VOID = &PNI_VOID;
+
+void *pn_class_new(const pn_class_t *clazz, size_t size)
+{
+ assert(clazz);
+ return clazz->newinst(clazz, size);
+}
+
+void *pn_class_incref(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+ clazz = clazz->reify(object);
+ clazz->incref(object);
+ return object;
+}
+
+int pn_class_refcount(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+ clazz = clazz->reify(object);
+ return clazz->refcount(object);
+}
+
+void pn_class_decref(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+ clazz = clazz->reify(object);
+ clazz->decref(object);
+}
+
+void pn_class_free(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+ clazz = clazz->reify(object);
+ clazz->free(object);
+}
+
+const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+ return clazz->reify(object);
+}
+
+uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object)
+{
+ assert(clazz);
+
+ if (!object) return 0;
+
+ clazz = clazz->reify(object);
+
+ if (clazz->hashcode) {
+ return clazz->hashcode(object);
+ } else {
+ return (uintptr_t) object;
+ }
+}
+
+intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b)
+{
+ assert(clazz);
+
+ if (a == b) return 0;
+
+ clazz = clazz->reify(a);
+
+ if (a && b && clazz->compare) {
+ return clazz->compare(a, b);
+ } else {
+ return (intptr_t) b - (intptr_t) a;
+ }
+}
+
+bool pn_class_equals(const pn_class_t *clazz, void *a, void *b)
+{
+ return pn_class_compare(clazz, a, b) == 0;
+}
+
typedef struct {
const pn_class_t *clazz;
int refcount;
@@ -36,8 +133,58 @@ typedef struct {
#define pni_head(PTR) \
(((pni_head_t *) (PTR)) - 1)
+void *pn_object_new(const pn_class_t *clazz, size_t size)
+{
+ return pn_new(size, clazz);
+}
+
+const pn_class_t *pn_object_reify(void *object)
+{
+ if (object) {
+ return pni_head(object)->clazz;
+ } else {
+ return PN_OBJECT;
+ }
+}
+
+void pn_object_incref(void *object)
+{
+ pn_incref(object);
+}
+
+int pn_object_refcount(void *object)
+{
+ return pn_refcount(object);
+}
+
+void pn_object_decref(void *object)
+{
+ pn_decref(object);
+}
+
+void pn_object_free(void *object)
+{
+ pn_free(object);
+}
+
+uintptr_t pn_object_hashcode(void *object)
+{
+ return (uintptr_t) object;
+}
+
+intptr_t pn_object_compare(void *a, void *b)
+{
+ return (intptr_t) b - (intptr_t) a;
+}
+
+int pn_object_inspect(void *object, pn_string_t *dst)
+{
+ return pn_inspect(object, dst);
+}
+
void *pn_new(size_t size, const pn_class_t *clazz)
{
+ assert(clazz);
return pn_new2(size, clazz, NULL);
}
@@ -136,20 +283,7 @@ uintptr_t pn_hashcode(void *object)
intptr_t pn_compare(void *a, void *b)
{
- if (a == b) return 0;
- if (a && b) {
- pni_head_t *ha = pni_head(a);
- pni_head_t *hb = pni_head(b);
-
- if (ha->clazz && hb->clazz && ha->clazz == hb->clazz) {
- const pn_class_t *clazz = ha->clazz;
- if (clazz->compare) {
- return clazz->compare(a, b);
- }
- }
- }
-
- return (intptr_t) b - (intptr_t) a;
+ return pn_class_compare(PN_OBJECT, a, b);
}
bool pn_equals(void *a, void *b)
Modified: qpid/proton/trunk/proton-c/src/tests/object.c
URL: http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/tests/object.c?rev=1625120&r1=1625119&r2=1625120&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Mon Sep 15 19:19:24 2014
@@ -95,9 +95,46 @@ static intptr_t delta(void *a, void *b)
static pn_class_t null_class = {0};
-static pn_class_t noop_class = {NULL, noop, noop, zero, delta};
+#define noop_initialize noop
+#define noop_finalize noop
+#define noop_hashcode zero
+#define noop_compare delta
+#define noop_inspect NULL
-static void test_new(size_t size, pn_class_t *clazz)
+static const pn_class_t noop_class = PN_CLASS(noop);
+
+static void test_class(const pn_class_t *clazz, size_t size)
+{
+ void *a = pn_class_new(clazz, size);
+ void *b = pn_class_new(clazz, size);
+
+ assert(!pn_class_equals(clazz, a, b));
+ assert(pn_class_equals(clazz, a, a));
+ assert(pn_class_equals(clazz, b, b));
+ assert(!pn_class_equals(clazz, a, NULL));
+ assert(!pn_class_equals(clazz, NULL, a));
+
+ int rca = pn_class_refcount(clazz, a);
+ int rcb = pn_class_refcount(clazz, b);
+
+ assert(rca == -1 || rca == 1);
+ assert(rcb == -1 || rcb == 1);
+
+ pn_class_incref(clazz, a);
+
+ rca = pn_class_refcount(clazz, a);
+ assert(rca == -1 || rca == 2);
+
+ pn_class_decref(clazz, a);
+
+ rca = pn_class_refcount(clazz, a);
+ assert(rca == -1 || rca == 1);
+
+ pn_class_free(clazz, a);
+ pn_class_free(clazz, b);
+}
+
+static void test_new(size_t size, const pn_class_t *clazz)
{
void *obj = pn_new(size, clazz);
assert(obj);
@@ -117,9 +154,15 @@ static void finalizer(void *object)
(**called)++;
}
+#define finalizer_initialize NULL
+#define finalizer_finalize finalizer
+#define finalizer_hashcode NULL
+#define finalizer_compare NULL
+#define finalizer_inspect NULL
+
static void test_finalize(void)
{
- static pn_class_t clazz = {NULL, NULL, finalizer};
+ static pn_class_t clazz = PN_CLASS(finalizer);
int **obj = (int **) pn_new(sizeof(int **), &clazz);
assert(obj);
@@ -139,9 +182,15 @@ static void test_free(void)
static uintptr_t hashcode(void *obj) { return (uintptr_t) obj; }
+#define hashcode_initialize NULL
+#define hashcode_finalize NULL
+#define hashcode_compare NULL
+#define hashcode_hashcode hashcode
+#define hashcode_inspect NULL
+
static void test_hashcode(void)
{
- static pn_class_t clazz = {NULL, NULL, NULL, hashcode};
+ static pn_class_t clazz = PN_CLASS(hashcode);
void *obj = pn_new(0, &clazz);
assert(obj);
assert(pn_hashcode(obj) == (uintptr_t) obj);
@@ -149,9 +198,15 @@ static void test_hashcode(void)
pn_free(obj);
}
+#define compare_initialize NULL
+#define compare_finalize NULL
+#define compare_compare delta
+#define compare_hashcode NULL
+#define compare_inspect NULL
+
static void test_compare(void)
{
- static pn_class_t clazz = {NULL, NULL, NULL, NULL, delta};
+ static pn_class_t clazz = PN_CLASS(compare);
void *a = pn_new(0, &clazz);
assert(a);
@@ -181,7 +236,7 @@ static void test_compare(void)
static void test_refcounting(int refs)
{
- void *obj = pn_new(0, NULL);
+ void *obj = pn_new(0, PN_OBJECT);
assert(pn_refcount(obj) == 1);
@@ -224,10 +279,10 @@ static void test_list(size_t capacity)
static void test_list_refcount(size_t capacity)
{
- void *one = pn_new(0, NULL);
- void *two = pn_new(0, NULL);
- void *three = pn_new(0, NULL);
- void *four = pn_new(0, NULL);
+ void *one = pn_new(0, PN_OBJECT);
+ void *two = pn_new(0, PN_OBJECT);
+ void *three = pn_new(0, PN_OBJECT);
+ void *four = pn_new(0, PN_OBJECT);
pn_list_t *list = pn_list(0, PN_REFCOUNT);
assert(!pn_list_add(list, one));
@@ -395,9 +450,9 @@ static void test_build_map_odd(void)
static void test_map(void)
{
- void *one = pn_new(0, NULL);
- void *two = pn_new(0, NULL);
- void *three = pn_new(0, NULL);
+ void *one = pn_new(0, PN_OBJECT);
+ void *two = pn_new(0, PN_OBJECT);
+ void *three = pn_new(0, PN_OBJECT);
pn_map_t *map = pn_map(4, 0.75, PN_REFCOUNT);
assert(pn_map_size(map) == 0);
@@ -458,9 +513,9 @@ static void test_map(void)
static void test_hash(void)
{
- void *one = pn_new(0, NULL);
- void *two = pn_new(0, NULL);
- void *three = pn_new(0, NULL);
+ void *one = pn_new(0, PN_OBJECT);
+ void *two = pn_new(0, PN_OBJECT);
+ void *three = pn_new(0, PN_OBJECT);
pn_hash_t *hash = pn_hash(4, 0.75, PN_REFCOUNT);
pn_hash_put(hash, 0, NULL);
@@ -639,8 +694,8 @@ static void test_map_iteration(int n)
{
pn_list_t *pairs = pn_list(2*n, PN_REFCOUNT);
for (int i = 0; i < n; i++) {
- void *key = pn_new(0, NULL);
- void *value = pn_new(0, NULL);
+ void *key = pn_new(0, PN_OBJECT);
+ void *value = pn_new(0, PN_OBJECT);
pn_list_add(pairs, key);
pn_list_add(pairs, value);
pn_decref(key);
@@ -746,9 +801,9 @@ void test_list_compare(void)
assert(pn_equals(a, b));
- void *one = pn_new(0, NULL);
- void *two = pn_new(0, NULL);
- void *three = pn_new(0, NULL);
+ void *one = pn_new(0, PN_OBJECT);
+ void *two = pn_new(0, PN_OBJECT);
+ void *three = pn_new(0, PN_OBJECT);
pn_list_add(a, one);
assert(!pn_equals(a, b));
@@ -811,7 +866,13 @@ void test_iterator(void)
int main(int argc, char **argv)
{
for (size_t i = 0; i < 128; i++) {
- test_new(i, NULL);
+ test_class(PN_OBJECT, i);
+ test_class(PN_VOID, i);
+ test_class(&noop_class, i);
+ }
+
+ for (size_t i = 0; i < 128; i++) {
+ test_new(i, PN_OBJECT);
test_new(i, &null_class);
test_new(i, &noop_class);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org