From 26900007b9eda47796bea7a34637dac04f8d3375 Mon Sep 17 00:00:00 2001 From: Guo Rui Date: Fri, 17 Jul 2009 00:14:50 +0800 Subject: [PATCH] Implement object broker mechanism. --- src/script.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/script.h | 32 +++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/script.c b/src/script.c index b123d06..ce035cb 100644 --- a/src/script.c +++ b/src/script.c @@ -324,3 +324,65 @@ trigger_sevent(struct script_event *ev, VA_DOTS) } \ } while (0) +/* Broker functions */ + +/* Broker hash */ +struct broker *b_hash[255]; + +#define DELETED ((struct broker*)1) +#define BHASH(o) (((int)(o) >> sizeof(struct broker *)) & 255) +struct broker **broker_from_obj(void *obj) +{ + struct broker **bucket = b_hash + BHASH(obj); + while (*bucket && (*bucket)->obj != obj) + { + bucket = &(*bucket)->b_next; + } + return bucket; +} + +struct broker * +get_obj_broker(void *obj) +{ + struct broker **bucket = broker_from_obj(obj); + if (!obj) + return NULL; + + /* Not found, allocate a new one */ + if (!*bucket) + { + struct broker *tmp = (struct broker *)malloc(sizeof(struct broker)); + if (!tmp) + return NULL; + + *bucket = tmp; + tmp->obj = obj; + tmp->ref = 0; + tmp->valid = 1; + tmp->b_next = NULL; + } + (*bucket)->ref++; + + return *bucket; +} + +void * get_broker_obj(struct broker *broker) +{ + if (broker->valid) + return broker->obj; + + if (--broker->ref == 0) + { + struct broker **b = broker_from_obj(broker->obj); + Free(b); + } + return NULL; +} + +void broker_inv_obj(void *obj) +{ + struct broker **b = broker_from_obj(obj); + if (*b) + (*b)->valid = 0; +} + diff --git a/src/script.h b/src/script.h index ed1261d..dda07ac 100644 --- a/src/script.h +++ b/src/script.h @@ -75,12 +75,32 @@ int trigger_sevent(struct script_event *ev, VA_DOTS); int register_listener(struct script_event *ev, struct listener *l); void unregister_listener(struct listener *l); -struct gevents { - struct script_event cmdexecuted; - struct script_event detached; - struct script_event onattach; - struct script_event forechanged; - struct script_event processcaption; +struct broker +{ + void *obj; + int ref; + int valid; + struct broker *b_next; +}; + +/* At most one broker object is created and reused for one object. + * A counter is maintained for broker references. A broker to valid object can + * be dereferenced as many times as you wish. But once the object is + * invalidated, each dereference action will decrease the counter by one, and + * return a NULL pointer. The binding should further invalidate the script + * variable that refers to the broker. This scheme will work for languages + * that always treat host objects as reference and never do value copy.*/ +struct broker *get_obj_broker(void *obj); +void * get_broker_obj(struct broker *broker); +void broker_inv_obj(void *obj); + +struct gevents +{ + struct script_event cmdexecuted; + struct script_event detached; + struct script_event onattach; + struct script_event forechanged; + struct script_event processcaption; }; extern struct gevents globalevents; #endif -- 2.11.4.GIT