A few more thread-safety fixes.

pull/13171/head
Joshua Haberman 16 years ago
parent 7fa19a3f95
commit 1e82f0ebd6
  1. 2
      src/upb_array.h
  2. 26
      src/upb_context.c
  3. 29
      src/upb_context.h
  4. 2
      src/upb_string.h

@ -55,7 +55,7 @@ INLINE void upb_array_uninit(struct upb_array *arr)
if(arr->size) free(arr->elements._void); 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)); struct upb_array *arr = malloc(sizeof(*arr));
upb_array_init(arr); upb_array_init(arr);
return arr; return arr;

@ -82,13 +82,24 @@ void upb_context_unref(struct upb_context *c)
upb_rwlock_destroy(&c->lock); upb_rwlock_destroy(&c->lock);
} }
struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, bool upb_context_lookup(struct upb_context *c, struct upb_string *symbol,
struct upb_string *symbol) struct upb_symtab_entry *out_entry)
{ {
upb_rwlock_rdlock(&c->lock); upb_rwlock_rdlock(&c->lock);
struct upb_symtab_entry *e = upb_strtable_lookup(&c->symtab, symbol); 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); upb_rwlock_unlock(&c->lock);
return e;
} }
/* Given a symbol and the base symbol inside which it is defined, find the /* 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, bool upb_context_resolve(struct upb_context *c, struct upb_string *base,
struct upb_string *base, struct upb_string *symbol,
struct upb_string *symbol) { struct upb_symtab_entry *out_entry) {
upb_rwlock_rdlock(&c->lock); upb_rwlock_rdlock(&c->lock);
struct upb_symtab_entry *e = resolve(&c->symtab, base, symbol); struct upb_symtab_entry *e = resolve(&c->symtab, base, symbol);
if(e) *out_entry = *e;
upb_rwlock_unlock(&c->lock); upb_rwlock_unlock(&c->lock);
return e; return e != NULL;
} }
/* Joins strings together, for example: /* Joins strings together, for example:

@ -53,7 +53,7 @@ struct upb_context {
/* Initializes a upb_context. Contexts are not freed explicitly, but unref'd /* Initializes a upb_context. Contexts are not freed explicitly, but unref'd
* when the caller is done with them. */ * 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) { INLINE void upb_context_ref(struct upb_context *c) {
upb_atomic_ref(&c->refcount); upb_atomic_ref(&c->refcount);
} }
@ -70,23 +70,24 @@ void upb_context_unref(struct upb_context *c);
* root namespace). * root namespace).
* *
* Returns NULL if the symbol has not been defined. */ * Returns NULL if the symbol has not been defined. */
struct upb_symtab_entry *upb_context_resolve(struct upb_context *c, bool upb_context_resolve(struct upb_context *c, struct upb_string *base,
struct upb_string *base, struct upb_string *symbol,
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 /* Find an entry in the symbol table with this exact name. Returns NULL if no
* such symbol name exists. */ * such symbol name exists. */
struct upb_symtab_entry *upb_context_lookup(struct upb_context *c, bool upb_context_lookup(struct upb_context *c, struct upb_string *symbol,
struct upb_string *symbol); struct upb_symtab_entry *out_entry);
INLINE struct upb_symtab_entry *upb_context_symbegin(struct upb_context *c) { /* For enumerating over the entries in the symbol table. The enumerator
return (struct upb_symtab_entry*)upb_strtable_begin(&c->symtab); * callback will be called once for every symtab entry.
} *
* The callback *must not* block or take any significant amount of time, since
INLINE struct upb_symtab_entry *upb_context_symnext( * the upb_context's lock is held while it is being called! */
struct upb_context *c, struct upb_symtab_entry *cur) { typedef void (*upb_context_enumerator_t)(
return (struct upb_symtab_entry*)upb_strtable_next(&c->symtab, &cur->e); void *udata, struct upb_symtab_entry *entry);
} void upb_context_enumerate(struct upb_context *c, upb_context_enumerator_t,
void *udata);
/* Adding symbols. ************************************************************/ /* Adding symbols. ************************************************************/

@ -60,7 +60,7 @@ INLINE void upb_struninit(struct upb_string *str)
if(str->byte_size) free(str->ptr); 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)); struct upb_string *str = (struct upb_string*)malloc(sizeof(*str));
upb_strinit(str); upb_strinit(str);

Loading…
Cancel
Save