aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lib/iomgr/error.c35
-rw-r--r--src/core/lib/slice/slice_buffer.c30
2 files changed, 47 insertions, 18 deletions
diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c
index 1dbb64e8f3..fbbca6b493 100644
--- a/src/core/lib/iomgr/error.c
+++ b/src/core/lib/iomgr/error.c
@@ -212,7 +212,11 @@ static uint8_t get_placement(grpc_error **err, size_t size) {
GPR_ASSERT(*err);
uint8_t slots = (uint8_t)(size / sizeof(intptr_t));
if ((*err)->arena_size + slots > (*err)->arena_capacity) {
- (*err)->arena_capacity = (uint8_t)(3 * (*err)->arena_capacity / 2);
+ (*err)->arena_capacity =
+ (uint8_t)GPR_MIN(UINT8_MAX - 1, (3 * (*err)->arena_capacity / 2));
+ if ((*err)->arena_size + slots > (*err)->arena_capacity) {
+ return UINT8_MAX;
+ }
*err = gpr_realloc(
*err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
}
@@ -223,10 +227,14 @@ static uint8_t get_placement(grpc_error **err, size_t size) {
static void internal_set_int(grpc_error **err, grpc_error_ints which,
intptr_t value) {
- // GPR_ASSERT((*err)->ints[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->ints[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
+ if (slot == UINT8_MAX) {
+ gpr_log(GPR_ERROR, "Error %p is full, dropping int {\"%s\":%" PRIiPTR "}",
+ *err, error_int_name(which), value);
+ return;
+ }
}
(*err)->ints[which] = slot;
(*err)->arena[slot] = value;
@@ -234,10 +242,16 @@ static void internal_set_int(grpc_error **err, grpc_error_ints which,
static void internal_set_str(grpc_error **err, grpc_error_strs which,
grpc_slice value) {
- // GPR_ASSERT((*err)->strs[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->strs[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
+ if (slot == UINT8_MAX) {
+ const char *str = grpc_slice_to_c_string(value);
+ gpr_log(GPR_ERROR, "Error %p is full, dropping string {\"%s\":\"%s\"}",
+ *err, error_str_name(which), str);
+ gpr_free((void *)str);
+ return;
+ }
} else {
unref_slice(*(grpc_slice *)((*err)->arena + slot));
}
@@ -245,12 +259,19 @@ static void internal_set_str(grpc_error **err, grpc_error_strs which,
memcpy((*err)->arena + slot, &value, sizeof(value));
}
+static char *fmt_time(gpr_timespec tm);
static void internal_set_time(grpc_error **err, grpc_error_times which,
gpr_timespec value) {
- // GPR_ASSERT((*err)->times[which] == UINT8_MAX); // TODO, enforce this
uint8_t slot = (*err)->times[which];
if (slot == UINT8_MAX) {
slot = get_placement(err, sizeof(value));
+ if (slot == UINT8_MAX) {
+ const char *time_str = fmt_time(value);
+ gpr_log(GPR_ERROR, "Error %p is full, dropping \"%s\":\"%s\"}", *err,
+ error_time_name(which), time_str);
+ gpr_free((void *)time_str);
+ return;
+ }
}
(*err)->times[which] = slot;
memcpy((*err)->arena + slot, &value, sizeof(value));
@@ -259,6 +280,12 @@ static void internal_set_time(grpc_error **err, grpc_error_times which,
static void internal_add_error(grpc_error **err, grpc_error *new) {
grpc_linked_error new_last = {new, UINT8_MAX};
uint8_t slot = get_placement(err, sizeof(grpc_linked_error));
+ if (slot == UINT8_MAX) {
+ gpr_log(GPR_ERROR, "Error %p is full, dropping error %p = %s", *err, new,
+ grpc_error_string(new));
+ GRPC_ERROR_UNREF(new);
+ return;
+ }
if ((*err)->first_err == UINT8_MAX) {
GPR_ASSERT((*err)->last_err == UINT8_MAX);
(*err)->last_err = slot;
diff --git a/src/core/lib/slice/slice_buffer.c b/src/core/lib/slice/slice_buffer.c
index 9176dc8a42..c96b9c3b28 100644
--- a/src/core/lib/slice/slice_buffer.c
+++ b/src/core/lib/slice/slice_buffer.c
@@ -46,27 +46,29 @@
#define GROW(x) (3 * (x) / 2)
static void maybe_embiggen(grpc_slice_buffer *sb) {
- if (sb->base_slices != sb->slices) {
- memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
- sb->slices = sb->base_slices;
- }
-
/* How far away from sb->base_slices is sb->slices pointer */
size_t slice_offset = (size_t)(sb->slices - sb->base_slices);
size_t slice_count = sb->count + slice_offset;
if (slice_count == sb->capacity) {
- sb->capacity = GROW(sb->capacity);
- GPR_ASSERT(sb->capacity > slice_count);
- if (sb->base_slices == sb->inlined) {
- sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
- memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
+ if (sb->base_slices != sb->slices) {
+ /* Make room by moving elements if there's still space unused */
+ memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice));
+ sb->slices = sb->base_slices;
} else {
- sb->base_slices =
- gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
- }
+ /* Allocate more memory if no more space is available */
+ sb->capacity = GROW(sb->capacity);
+ GPR_ASSERT(sb->capacity > slice_count);
+ if (sb->base_slices == sb->inlined) {
+ sb->base_slices = gpr_malloc(sb->capacity * sizeof(grpc_slice));
+ memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice));
+ } else {
+ sb->base_slices =
+ gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice));
+ }
- sb->slices = sb->base_slices + slice_offset;
+ sb->slices = sb->base_slices + slice_offset;
+ }
}
}