summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/upb_context.c44
-rw-r--r--src/upb_context.h2
-rw-r--r--tests/tests.c6
-rw-r--r--tools/upbc.c13
4 files changed, 42 insertions, 23 deletions
diff --git a/src/upb_context.c b/src/upb_context.c
index fbe3f34..0001a98 100644
--- a/src/upb_context.c
+++ b/src/upb_context.c
@@ -23,8 +23,9 @@ bool addfd(struct upb_strtable *addto, struct upb_strtable *existingdefs,
google_protobuf_FileDescriptorProto *fd, bool sort,
struct upb_context *context);
-bool upb_context_init(struct upb_context *c)
+struct upb_context *upb_context_new()
{
+ struct upb_context *c = malloc(sizeof(*c));
upb_atomic_refcount_init(&c->refcount, 1);
upb_rwlock_init(&c->lock);
upb_strtable_init(&c->symtab, 16, sizeof(struct upb_symtab_entry));
@@ -34,7 +35,7 @@ bool upb_context_init(struct upb_context *c)
upb_file_descriptor_set->file->elements[0]; /* We know there is only 1. */
if(!addfd(&c->psymtab, &c->symtab, fd, false, c)) {
assert(false);
- return false; /* Indicates that upb is buggy or corrupt. */
+ return NULL; /* Indicates that upb is buggy or corrupt. */
}
struct upb_string name = UPB_STRLIT("google.protobuf.FileDescriptorSet");
struct upb_symtab_entry *e = upb_strtable_lookup(&c->psymtab, &name);
@@ -43,7 +44,7 @@ bool upb_context_init(struct upb_context *c)
c->fds_size = 16;
c->fds_len = 0;
c->fds = malloc(sizeof(*c->fds));
- return true;
+ return c;
}
static void free_symtab(struct upb_strtable *t)
@@ -68,6 +69,7 @@ static void free_context(struct upb_context *c)
upb_msg_free((struct upb_msg*)c->fds[i]);
free_symtab(&c->psymtab);
free(c->fds);
+ free(c);
}
void upb_context_unref(struct upb_context *c)
@@ -83,7 +85,10 @@ void upb_context_unref(struct upb_context *c)
struct upb_symtab_entry *upb_context_lookup(struct upb_context *c,
struct upb_string *symbol)
{
- return upb_strtable_lookup(&c->symtab, symbol);
+ upb_rwlock_rdlock(&c->lock);
+ struct upb_symtab_entry *e = upb_strtable_lookup(&c->symtab, symbol);
+ upb_rwlock_unlock(&c->lock);
+ return e;
}
/* Given a symbol and the base symbol inside which it is defined, find the
@@ -137,7 +142,10 @@ 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) {
- return resolve(&c->symtab, base, symbol);
+ upb_rwlock_rdlock(&c->lock);
+ struct upb_symtab_entry *e = resolve(&c->symtab, base, symbol);
+ upb_rwlock_unlock(&c->lock);
+ return e;
}
/* Joins strings together, for example:
@@ -280,17 +288,25 @@ bool upb_context_addfds(struct upb_context *c,
* the descriptor is valid. */
struct upb_strtable tmp;
upb_strtable_init(&tmp, 0, sizeof(struct upb_symtab_entry));
+ upb_rwlock_rdlock(&c->lock);
for(uint32_t i = 0; i < fds->file->len; i++) {
if(!addfd(&tmp, &c->symtab, fds->file->elements[i], true, c)) {
printf("Not added successfully!\n");
free_symtab(&tmp);
+ upb_rwlock_unlock(&c->lock);
return false;
}
}
+ upb_rwlock_unlock(&c->lock);
+
/* Everything was successfully added, copy from the tmp symtable. */
struct upb_symtab_entry *e;
- for(e = upb_strtable_begin(&tmp); e; e = upb_strtable_next(&tmp, &e->e))
- upb_strtable_insert(&c->symtab, &e->e);
+ {
+ upb_rwlock_wrlock(&c->lock);
+ for(e = upb_strtable_begin(&tmp); e; e = upb_strtable_next(&tmp, &e->e))
+ upb_strtable_insert(&c->symtab, &e->e);
+ upb_rwlock_unlock(&c->lock);
+ }
upb_strtable_free(&tmp);
}
return true;
@@ -302,11 +318,15 @@ bool upb_context_parsefds(struct upb_context *c, struct upb_string *fds_str) {
if(!fds) return false;
if(!upb_context_addfds(c, fds)) return false;
- /* We own fds now, need to keep a ref so we can free it later. */
- if(c->fds_size == c->fds_len) {
- c->fds_size *= 2;
- c->fds = realloc(c->fds, c->fds_size);
+ {
+ /* We own fds now, need to keep a ref so we can free it later. */
+ upb_rwlock_wrlock(&c->lock);
+ if(c->fds_size == c->fds_len) {
+ c->fds_size *= 2;
+ c->fds = realloc(c->fds, c->fds_size);
+ }
+ c->fds[c->fds_len++] = fds;
+ upb_rwlock_unlock(&c->lock);
}
- c->fds[c->fds_len++] = fds;
return true;
}
diff --git a/src/upb_context.h b/src/upb_context.h
index a04a875..504b1b6 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. */
-bool upb_context_init(struct upb_context *c);
+struct upb_context *upb_context_new();
INLINE void upb_context_ref(struct upb_context *c) {
upb_atomic_ref(&c->refcount);
}
diff --git a/tests/tests.c b/tests/tests.c
index 5df933c..e625f8a 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -222,9 +222,9 @@ static void test_get_f_uint32_t()
}
static void test_upb_context() {
- struct upb_context c;
- ASSERT(upb_context_init(&c));
- upb_context_unref(&c);
+ struct upb_context *c = upb_context_new();
+ ASSERT(c);
+ upb_context_unref(c);
}
int main()
diff --git a/tools/upbc.c b/tools/upbc.c
index b3036a0..2185ee3 100644
--- a/tools/upbc.c
+++ b/tools/upbc.c
@@ -646,13 +646,12 @@ int main(int argc, char *argv[])
error("Couldn't read input file.");
/* Parse input file. */
- struct upb_context c;
- upb_context_init(&c);
- struct upb_msg *fds_msg = upb_msg_parsenew(c.fds_msg, descriptor);
+ struct upb_context *c = upb_context_new();
+ struct upb_msg *fds_msg = upb_msg_parsenew(c->fds_msg, descriptor);
google_protobuf_FileDescriptorSet *fds = (void*)fds_msg;
if(!fds)
error("Failed to parse input file descriptor.");
- if(!upb_context_addfds(&c, fds))
+ if(!upb_context_addfds(c, fds))
error("Failed to resolve symbols in descriptor.\n");
/* We need to sort the fields of all the descriptors. They will already be
@@ -676,17 +675,17 @@ int main(int argc, char *argv[])
if(!h_file) error("Failed to open .h output file");
int symcount;
- struct upb_symtab_entry **entries = strtable_to_array(&c.symtab, &symcount);
+ struct upb_symtab_entry **entries = strtable_to_array(&c->symtab, &symcount);
write_h(entries, symcount, h_filename, cident, h_file);
free(entries);
if(cident) {
FILE *c_file = fopen(c_filename, "w");
if(!c_file) error("Failed to open .h output file");
- write_message_c(fds, c.fds_msg, cident, h_filename, argc, argv, input_file, c_file);
+ write_message_c(fds, c->fds_msg, cident, h_filename, argc, argv, input_file, c_file);
fclose(c_file);
}
upb_msg_free(fds_msg);
- upb_context_unref(&c);
+ upb_context_unref(c);
upb_strfree(descriptor);
fclose(h_file);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback