summaryrefslogtreecommitdiff
path: root/upb/handlers.c
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
committerJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
commit2d10fa33071d52d7a35ce3b13bc459cd16a0aa33 (patch)
treebf47d38e2e1cc8ddb4711b23b26e7fd10742e07d /upb/handlers.c
parent7d565f1e7a0f107506d3cf31ef2e33e22a504d2b (diff)
Sync from internal Google development.
Diffstat (limited to 'upb/handlers.c')
-rw-r--r--upb/handlers.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/upb/handlers.c b/upb/handlers.c
index be035ba..024cd0c 100644
--- a/upb/handlers.c
+++ b/upb/handlers.c
@@ -21,12 +21,17 @@ char _upb_noclosure;
static void freehandlers(upb_refcounted *r) {
upb_handlers *h = (upb_handlers*)r;
- for (int i = 0; i < h->msg->selector_count; i++) {
- upb_handlerfree *cleanup = h->table[i].attr.cleanup;
- if (cleanup) {
- cleanup(h->table[i].attr.handler_data_);
- }
+
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &h->cleanup_);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ void *val = (void*)upb_inttable_iter_key(&i);
+ upb_value func_val = upb_inttable_iter_value(&i);
+ upb_handlerfree *func = upb_value_getfptr(func_val);
+ func(val);
}
+
+ upb_inttable_uninit(&h->cleanup_);
upb_msgdef_unref(h->msg, h);
free(h->sub);
free(h);
@@ -49,7 +54,7 @@ static const struct upb_refcounted_vtbl vtbl = {visithandlers, freehandlers};
typedef struct {
upb_inttable tab; // maps upb_msgdef* -> upb_handlers*.
upb_handlers_callback *callback;
- void *closure;
+ const void *closure;
} dfs_state;
// TODO(haberman): discard upb_handlers* objects that do not actually have any
@@ -283,6 +288,7 @@ upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
h->sub = calloc(md->submsg_field_count, sizeof(*h->sub));
if (!h->sub) goto oom;
if (!upb_refcounted_init(UPB_UPCAST(h), &vtbl, owner)) goto oom;
+ if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
// calloc() above initialized all handlers to NULL.
return h;
@@ -295,7 +301,7 @@ oom:
const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
const void *owner,
upb_handlers_callback *callback,
- void *closure) {
+ const void *closure) {
dfs_state state;
state.callback = callback;
state.closure = closure;
@@ -396,6 +402,15 @@ const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
+ if (upb_inttable_lookupptr(&h->cleanup_, p, NULL)) {
+ return false;
+ }
+ bool ok = upb_inttable_insertptr(&h->cleanup_, p, upb_value_fptr(func));
+ UPB_ASSERT_VAR(ok, ok);
+ return true;
+}
+
/* "Static" methods ***********************************************************/
@@ -584,10 +599,8 @@ void upb_handlerattr_uninit(upb_handlerattr *attr) {
UPB_UNUSED(attr);
}
-bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, void *hd,
- upb_handlerfree *cleanup) {
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd) {
attr->handler_data_ = hd;
- attr->cleanup = cleanup;
return true;
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback