buflib: Allow handle to be freed entirely during the shrink callback.
Change-Id: I3a069dcb99bbd4022faf37596b03beb926d2ea82 Reviewed-on: http://gerrit.rockbox.org/480 Reviewed-by: Thomas Martitz <kugel@rockbox.org> Tested-by: Thomas Martitz <kugel@rockbox.org>
This commit is contained in:
parent
d938ae692c
commit
46ea8bfe7c
1 changed files with 10 additions and 4 deletions
|
@ -165,7 +165,7 @@ static union buflib_data* handle_to_block(struct buflib_context* ctx, int handle
|
||||||
union buflib_data* name_field =
|
union buflib_data* name_field =
|
||||||
(union buflib_data*)buflib_get_name(ctx, handle);
|
(union buflib_data*)buflib_get_name(ctx, handle);
|
||||||
|
|
||||||
return name_field - 3;
|
return name_field ? name_field - 3 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shrink the handle table, returning true if its size was reduced, false if
|
/* Shrink the handle table, returning true if its size was reduced, false if
|
||||||
|
@ -353,11 +353,15 @@ buflib_compact_and_shrink(struct buflib_context *ctx, unsigned shrink_hints)
|
||||||
ret = this[2].ops->shrink_callback(handle, shrink_hints,
|
ret = this[2].ops->shrink_callback(handle, shrink_hints,
|
||||||
data, (char*)(this+this->val)-data);
|
data, (char*)(this+this->val)-data);
|
||||||
result |= (ret == BUFLIB_CB_OK);
|
result |= (ret == BUFLIB_CB_OK);
|
||||||
/* this might have changed in the callback (if
|
/* 'this' might have changed in the callback (if it shrinked
|
||||||
* it shrinked from the top), get it again */
|
* from the top or even freed the handle), get it again */
|
||||||
this = handle_to_block(ctx, handle);
|
this = handle_to_block(ctx, handle);
|
||||||
|
/* The handle was possibly be freed in the callback,
|
||||||
|
* re-run the loop with the handle before */
|
||||||
|
if (!this)
|
||||||
|
this = before;
|
||||||
/* could also change with shrinking from back */
|
/* could also change with shrinking from back */
|
||||||
if (last)
|
else if (last)
|
||||||
ctx->alloc_end = this + this->val;
|
ctx->alloc_end = this + this->val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,6 +784,8 @@ buflib_shrink(struct buflib_context* ctx, int handle, void* new_start, size_t ne
|
||||||
const char* buflib_get_name(struct buflib_context *ctx, int handle)
|
const char* buflib_get_name(struct buflib_context *ctx, int handle)
|
||||||
{
|
{
|
||||||
union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
|
union buflib_data *data = ALIGN_DOWN(buflib_get_data(ctx, handle), sizeof (*data));
|
||||||
|
if (!data)
|
||||||
|
return NULL;
|
||||||
size_t len = data[-1].val;
|
size_t len = data[-1].val;
|
||||||
if (len <= 1)
|
if (len <= 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue