From 1e82f0ebd6ae0de251ec6c3cac0544d96d973f1b Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 15 Aug 2009 22:10:07 -0700 Subject: A few more thread-safety fixes. --- src/upb_array.h | 2 +- src/upb_context.c | 26 +++++++++++++++++++------- src/upb_context.h | 29 +++++++++++++++-------------- src/upb_string.h | 2 +- 4 files changed, 36 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/upb_array.h b/src/upb_array.h index 65d44bb..370f6eb 100644 --- a/src/upb_array.h +++ b/src/upb_array.h @@ -55,7 +55,7 @@ INLINE void upb_array_uninit(struct upb_array *arr) if(arr->size) free(arr->elements._void); } -INLINE struct upb_array *upb_array_new() { +INLINE struct upb_array *upb_array_new(void) { struct upb_array *arr = malloc(sizeof(*arr)); upb_array_init(arr); return arr; diff --git a/src/upb_context.c b/src/upb_context.c index 0001a98..931a6fb 100644 --- a/src/upb_context.c +++ b/src/upb_context.c @@ -82,13 +82,24 @@ void upb_context_unref(struct upb_context *c) upb_rwlock_destroy(&c->lock); } -struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, - struct upb_string *symbol) +bool upb_context_lookup(struct upb_context *c, struct upb_string *symbol, + struct upb_symtab_entry *out_entry) { upb_rwlock_rdlock(&c->lock); struct upb_symtab_entry *e = upb_strtable_lookup(&c->symtab, symbol); + if(e) *out_entry = *e; + upb_rwlock_unlock(&c->lock); + return e != NULL; +} + +void upb_context_enumerate(struct upb_context *c, upb_context_enumerator_t cb, + void *udata) +{ + upb_rwlock_rdlock(&c->lock); + struct upb_symtab_entry *e = upb_strtable_begin(&c->symtab); + for(; e; e = upb_strtable_next(&c->symtab, &e->e)) + cb(udata, e); upb_rwlock_unlock(&c->lock); - return e; } /* Given a symbol and the base symbol inside which it is defined, find the @@ -139,13 +150,14 @@ union upb_symbol_ref resolve2(struct upb_strtable *t1, struct upb_strtable *t2, } -struct upb_symtab_entry *upb_context_resolve(struct upb_context *c, - struct upb_string *base, - struct upb_string *symbol) { +bool upb_context_resolve(struct upb_context *c, struct upb_string *base, + struct upb_string *symbol, + struct upb_symtab_entry *out_entry) { upb_rwlock_rdlock(&c->lock); struct upb_symtab_entry *e = resolve(&c->symtab, base, symbol); + if(e) *out_entry = *e; upb_rwlock_unlock(&c->lock); - return e; + return e != NULL; } /* Joins strings together, for example: diff --git a/src/upb_context.h b/src/upb_context.h index 504b1b6..8e46cae 100644 --- a/src/upb_context.h +++ b/src/upb_context.h @@ -53,7 +53,7 @@ struct upb_context { /* Initializes a upb_context. Contexts are not freed explicitly, but unref'd * when the caller is done with them. */ -struct upb_context *upb_context_new(); +struct upb_context *upb_context_new(void); INLINE void upb_context_ref(struct upb_context *c) { upb_atomic_ref(&c->refcount); } @@ -70,23 +70,24 @@ void upb_context_unref(struct upb_context *c); * root namespace). * * Returns NULL if the symbol has not been defined. */ -struct upb_symtab_entry *upb_context_resolve(struct upb_context *c, - struct upb_string *base, - struct upb_string *symbol); +bool upb_context_resolve(struct upb_context *c, struct upb_string *base, + struct upb_string *symbol, + struct upb_symtab_entry *out_entry); /* Find an entry in the symbol table with this exact name. Returns NULL if no * such symbol name exists. */ -struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, - struct upb_string *symbol); +bool upb_context_lookup(struct upb_context *c, struct upb_string *symbol, + struct upb_symtab_entry *out_entry); -INLINE struct upb_symtab_entry *upb_context_symbegin(struct upb_context *c) { - return (struct upb_symtab_entry*)upb_strtable_begin(&c->symtab); -} - -INLINE struct upb_symtab_entry *upb_context_symnext( - struct upb_context *c, struct upb_symtab_entry *cur) { - return (struct upb_symtab_entry*)upb_strtable_next(&c->symtab, &cur->e); -} +/* For enumerating over the entries in the symbol table. The enumerator + * callback will be called once for every symtab entry. + * + * The callback *must not* block or take any significant amount of time, since + * the upb_context's lock is held while it is being called! */ +typedef void (*upb_context_enumerator_t)( + void *udata, struct upb_symtab_entry *entry); +void upb_context_enumerate(struct upb_context *c, upb_context_enumerator_t, + void *udata); /* Adding symbols. ************************************************************/ diff --git a/src/upb_string.h b/src/upb_string.h index 7b63f1c..9740a0b 100644 --- a/src/upb_string.h +++ b/src/upb_string.h @@ -60,7 +60,7 @@ INLINE void upb_struninit(struct upb_string *str) if(str->byte_size) free(str->ptr); } -INLINE struct upb_string *upb_strnew() +INLINE struct upb_string *upb_strnew(void) { struct upb_string *str = (struct upb_string*)malloc(sizeof(*str)); upb_strinit(str); -- cgit v1.2.3