diff options
author | 2017-09-21 18:56:08 -0700 | |
---|---|---|
committer | 2017-10-02 16:29:41 -0700 | |
commit | 83062842c3601faeddcae8f901c515e3c78f3661 (patch) | |
tree | 58536b25350a5f2b3123161ab4ca9b8ce01a43a5 /src/core/ext/census/resource.c | |
parent | 1c9b584a153ff592c92b6cf6baa620d8602a37cd (diff) |
Changes for C to C++. Adding extern C to header files for compatibility.
Also converting to .cc
Diffstat (limited to 'src/core/ext/census/resource.c')
-rw-r--r-- | src/core/ext/census/resource.c | 303 |
1 files changed, 0 insertions, 303 deletions
diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c deleted file mode 100644 index 44a887231c..0000000000 --- a/src/core/ext/census/resource.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/ext/census/resource.h" -#include "third_party/nanopb/pb_decode.h" - -#include <grpc/census.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> - -#include <stdbool.h> -#include <string.h> - -// Protect local resource data structures. -static gpr_mu resource_lock; - -// Deleteing and creating resources are relatively rare events, and should not -// be done in the critical path of performance sensitive code. We record -// current resource id's used in a simple array, and just search it each time -// we need to assign a new id, or look up a resource. -static resource **resources = NULL; - -// Number of entries in *resources -static size_t n_resources = 0; - -// Number of defined resources -static size_t n_defined_resources = 0; - -void initialize_resources(void) { - gpr_mu_init(&resource_lock); - gpr_mu_lock(&resource_lock); - GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0); - gpr_mu_unlock(&resource_lock); -} - -// Delete a resource given it's ID. The ID must be a valid resource ID. Must be -// called with resource_lock held. -static void delete_resource_locked(size_t rid) { - GPR_ASSERT(resources[rid] != NULL); - gpr_free(resources[rid]->name); - gpr_free(resources[rid]->description); - gpr_free(resources[rid]->numerators); - gpr_free(resources[rid]->denominators); - gpr_free(resources[rid]); - resources[rid] = NULL; - n_defined_resources--; -} - -void shutdown_resources(void) { - gpr_mu_lock(&resource_lock); - for (size_t i = 0; i < n_resources; i++) { - if (resources[i] != NULL) { - delete_resource_locked(i); - } - } - GPR_ASSERT(n_defined_resources == 0); - gpr_free(resources); - resources = NULL; - n_resources = 0; - gpr_mu_unlock(&resource_lock); -} - -// Check the contents of string fields in a resource proto. -static bool validate_string(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - resource *vresource = (resource *)*arg; - switch (field->tag) { - case google_census_Resource_name_tag: - // Name must have at least one character - if (stream->bytes_left == 0) { - gpr_log(GPR_INFO, "Zero-length Resource name."); - return false; - } - vresource->name = (char *)gpr_malloc(stream->bytes_left + 1); - vresource->name[stream->bytes_left] = '\0'; - if (!pb_read(stream, (uint8_t *)vresource->name, stream->bytes_left)) { - return false; - } - // Can't have same name as an existing resource. - for (size_t i = 0; i < n_resources; i++) { - resource *compare = resources[i]; - if (compare == vresource || compare == NULL) continue; - if (strcmp(compare->name, vresource->name) == 0) { - gpr_log(GPR_INFO, "Duplicate Resource name %s.", vresource->name); - return false; - } - } - break; - case google_census_Resource_description_tag: - if (stream->bytes_left == 0) { - return true; - } - vresource->description = (char *)gpr_malloc(stream->bytes_left + 1); - vresource->description[stream->bytes_left] = '\0'; - if (!pb_read(stream, (uint8_t *)vresource->description, - stream->bytes_left)) { - return false; - } - break; - default: - // No other string fields in Resource. Print warning and skip. - gpr_log(GPR_INFO, "Unknown string field type in Resource protobuf."); - if (!pb_read(stream, NULL, stream->bytes_left)) { - return false; - } - break; - } - return true; -} - -// Decode numerators/denominators in a stream. The `count` and `bup` -// (BasicUnit pointer) are pointers to the approriate fields in a resource -// struct. -static bool validate_units_helper(pb_istream_t *stream, int *count, - google_census_Resource_BasicUnit **bup) { - while (stream->bytes_left) { - (*count)++; - // Have to allocate a new array of values. Normal case is 0 or 1, so - // this should normally not be an issue. - google_census_Resource_BasicUnit *new_bup = - (google_census_Resource_BasicUnit *)gpr_malloc( - (size_t)*count * sizeof(google_census_Resource_BasicUnit)); - if (*count != 1) { - memcpy(new_bup, *bup, - (size_t)(*count - 1) * sizeof(google_census_Resource_BasicUnit)); - gpr_free(*bup); - } - *bup = new_bup; - uint64_t value; - if (!pb_decode_varint(stream, &value)) { - return false; - } - *(*bup + *count - 1) = (google_census_Resource_BasicUnit)value; - } - return true; -} - -// Validate units field of a Resource proto. -static bool validate_units(pb_istream_t *stream, const pb_field_t *field, - void **arg) { - resource *vresource = (resource *)(*arg); - switch (field->tag) { - case google_census_Resource_MeasurementUnit_numerator_tag: - return validate_units_helper(stream, &vresource->n_numerators, - &vresource->numerators); - break; - case google_census_Resource_MeasurementUnit_denominator_tag: - return validate_units_helper(stream, &vresource->n_denominators, - &vresource->denominators); - break; - default: - gpr_log(GPR_ERROR, "Unknown field type."); - return false; - break; - } - return true; -} - -// Validate the contents of a Resource proto. `id` is the intended resource id. -static bool validate_resource_pb(const uint8_t *resource_pb, - size_t resource_pb_size, size_t id) { - GPR_ASSERT(id < n_resources); - if (resource_pb == NULL) { - return false; - } - google_census_Resource vresource; - vresource.name.funcs.decode = &validate_string; - vresource.name.arg = resources[id]; - vresource.description.funcs.decode = &validate_string; - vresource.description.arg = resources[id]; - vresource.unit.numerator.funcs.decode = &validate_units; - vresource.unit.numerator.arg = resources[id]; - vresource.unit.denominator.funcs.decode = &validate_units; - vresource.unit.denominator.arg = resources[id]; - - pb_istream_t stream = - pb_istream_from_buffer((uint8_t *)resource_pb, resource_pb_size); - if (!pb_decode(&stream, google_census_Resource_fields, &vresource)) { - return false; - } - // A Resource must have a name, a unit, with at least one numerator. - return (resources[id]->name != NULL && vresource.has_unit && - resources[id]->n_numerators > 0); -} - -// Allocate a blank resource, and return associated ID. Must be called with -// resource_lock held. -size_t allocate_resource(void) { - // use next_id to optimize expected placement of next new resource. - static size_t next_id = 0; - size_t id = n_resources; // resource ID - initialize to invalid value. - // Expand resources if needed. - if (n_resources == n_defined_resources) { - size_t new_n_resources = n_resources ? n_resources * 2 : 2; - resource **new_resources = - (resource **)gpr_malloc(new_n_resources * sizeof(resource *)); - if (n_resources != 0) { - memcpy(new_resources, resources, n_resources * sizeof(resource *)); - } - memset(new_resources + n_resources, 0, - (new_n_resources - n_resources) * sizeof(resource *)); - gpr_free(resources); - resources = new_resources; - n_resources = new_n_resources; - id = n_defined_resources; - } else { - GPR_ASSERT(n_defined_resources < n_resources); - // Find a free id. - for (size_t base = 0; base < n_resources; base++) { - id = (next_id + base) % n_resources; - if (resources[id] == NULL) break; - } - } - GPR_ASSERT(id < n_resources && resources[id] == NULL); - resources[id] = (resource *)gpr_malloc(sizeof(resource)); - memset(resources[id], 0, sizeof(resource)); - n_defined_resources++; - next_id = (id + 1) % n_resources; - return id; -} - -int32_t census_define_resource(const uint8_t *resource_pb, - size_t resource_pb_size) { - if (resource_pb == NULL) { - return -1; - } - gpr_mu_lock(&resource_lock); - size_t id = allocate_resource(); - // Validate pb, extract name. - if (!validate_resource_pb(resource_pb, resource_pb_size, id)) { - delete_resource_locked(id); - gpr_mu_unlock(&resource_lock); - return -1; - } - gpr_mu_unlock(&resource_lock); - return (int32_t)id; -} - -void census_delete_resource(int32_t rid) { - gpr_mu_lock(&resource_lock); - if (rid >= 0 && (size_t)rid < n_resources && resources[rid] != NULL) { - delete_resource_locked((size_t)rid); - } - gpr_mu_unlock(&resource_lock); -} - -int32_t census_resource_id(const char *name) { - gpr_mu_lock(&resource_lock); - for (int32_t id = 0; (size_t)id < n_resources; id++) { - if (resources[id] != NULL && strcmp(resources[id]->name, name) == 0) { - gpr_mu_unlock(&resource_lock); - return id; - } - } - gpr_mu_unlock(&resource_lock); - return -1; -} - -int32_t define_resource(const resource *base) { - GPR_ASSERT(base != NULL && base->name != NULL && base->n_numerators > 0 && - base->numerators != NULL); - gpr_mu_lock(&resource_lock); - size_t id = allocate_resource(); - size_t len = strlen(base->name) + 1; - resources[id]->name = (char *)gpr_malloc(len); - memcpy(resources[id]->name, base->name, len); - if (base->description) { - len = strlen(base->description) + 1; - resources[id]->description = (char *)gpr_malloc(len); - memcpy(resources[id]->description, base->description, len); - } - resources[id]->prefix = base->prefix; - resources[id]->n_numerators = base->n_numerators; - len = (size_t)base->n_numerators * sizeof(*base->numerators); - resources[id]->numerators = - (google_census_Resource_BasicUnit *)gpr_malloc(len); - memcpy(resources[id]->numerators, base->numerators, len); - resources[id]->n_denominators = base->n_denominators; - if (base->n_denominators != 0) { - len = (size_t)base->n_denominators * sizeof(*base->denominators); - resources[id]->denominators = - (google_census_Resource_BasicUnit *)gpr_malloc(len); - memcpy(resources[id]->denominators, base->denominators, len); - } - gpr_mu_unlock(&resource_lock); - return (int32_t)id; -} |