1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

dsh: remove foreign support

We're going to refactor dsh to not have foreign support, let's remove it in
one step.
This commit is contained in:
Andy Green 2021-09-17 13:31:50 +01:00
parent 1e56dc9642
commit c38567960a
2 changed files with 2 additions and 202 deletions

View file

@ -120,123 +120,16 @@ search_best_free(struct lws_dll2 *d, void *user)
return 0;
}
static int
try_foreign(struct lws_dll2 *d, void *user)
{
struct lws_dsh_search *s = (struct lws_dsh_search *)user;
lws_dsh_t *dsh1 = lws_container_of(d, lws_dsh_t, list);
if (dsh1 == s->already_checked)
return 0;
if (dsh1->being_destroyed)
return 0;
if (dsh1->count_kinds < s->kind + 1)
return 0;
lwsl_debug("%s: actual try_foreign: dsh %p (free list size %d)\n",
__func__, dsh1, dsh1->oha[0].owner.count);
s->this_dsh = dsh1;
if (lws_dll2_foreach_safe(&dsh1->oha[0].owner, s, search_best_free))
return 1;
return 0;
}
static int
free_foreign(struct lws_dll2 *d, void *user)
{
lws_dsh_obj_t *obj = lws_container_of(d, lws_dsh_obj_t, list);
lws_dsh_t *dsh = (lws_dsh_t *)user;
void *p = (void *)&obj[1];
if (obj->dsh != dsh)
lws_dsh_free(&p);
return 0;
}
static int
evict2(struct lws_dll2 *d, void *user)
{
lws_dsh_obj_t *obj = lws_container_of(d, lws_dsh_obj_t, list);
lws_dsh_t *dsh = (lws_dsh_t *)user;
void *p;
if (obj->dsh != dsh)
return 0;
/*
* If we are here, it means obj is a live object that is allocated on
* the dsh being destroyed, from a different dsh. We need to migrate
* the object to a dsh that isn't being destroyed.
*/
lwsl_debug("%s: migrating object size %zu\n", __func__, obj->size);
if (_lws_dsh_alloc_tail(dsh, 0, (void *)&obj[1], obj->size, NULL, 0, &obj->list)) {
lwsl_notice("%s: failed to migrate object\n", __func__);
/*
* only thing we can do is drop the logical object
*/
p = (uint8_t *)&obj[1];
lws_dsh_free(&p);
}
return 0;
}
static int
evict1(struct lws_dll2 *d, void *user)
{
lws_dsh_t *dsh1 = lws_container_of(d, lws_dsh_t, list);
lws_dsh_t *dsh = (lws_dsh_t *)user;
int n;
if (dsh1->being_destroyed)
return 0;
/*
* For every dsh that's not being destroyed, send every object to
* evict2 for checking.
*/
lwsl_debug("%s: checking dsh %p\n", __func__, dsh1);
for (n = 1; n < dsh1->count_kinds; n++) {
lws_dll2_describe(&dsh1->oha[n].owner, "check dsh1");
lws_dll2_foreach_safe(&dsh1->oha[n].owner, dsh, evict2);
}
return 0;
}
void
lws_dsh_destroy(lws_dsh_t **pdsh)
{
lws_dsh_t *dsh = *pdsh;
int n;
if (!dsh)
return;
dsh->being_destroyed = 1;
/* we need to explicitly free any of our allocations in foreign dsh */
for (n = 1; n < dsh->count_kinds; n++)
lws_dll2_foreach_safe(&dsh->oha[n].owner, dsh, free_foreign);
/*
* We need to have anybody else with allocations in us evict them
* and make a copy in a buffer that isn't being destroyed
*/
if (dsh->list.owner)
lws_dll2_foreach_safe(dsh->list.owner, dsh, evict1);
lws_dll2_remove(&dsh->list);
/* everything else is in one heap allocation */
@ -278,19 +171,9 @@ _lws_dsh_alloc_tail(lws_dsh_t *dsh, int kind, const void *src1, size_t size1,
lws_dll2_foreach_safe(&dsh->oha[0].owner, &s, search_best_free);
if (!s.best) {
/*
* Let's see if any other buffer has room
*/
s.already_checked = dsh;
lwsl_notice("%s: no buffer has space\n", __func__);
if (dsh && dsh->list.owner)
lws_dll2_foreach_safe(dsh->list.owner, &s, try_foreign);
if (!s.best) {
lwsl_notice("%s: no buffer has space\n", __func__);
return 1;
}
return 1;
}
/* anything coming out of here must be aligned */

View file

@ -91,85 +91,6 @@ bail:
return 1;
}
int
test2(void)
{
struct lws_dsh *dsh, *dsh2;
lws_dll2_owner_t owner;
uint8_t blob[4096];
memset(blob, 0, sizeof(blob));
/*
* test 2: multiple dsh, overflow allocation and dynamic destroy
*/
lws_dll2_owner_clear(&owner);
dsh = lws_dsh_create(&owner, 4096, 2);
if (!dsh) {
lwsl_err("%s: Failed to create dsh1\n", __func__);
return 1;
}
dsh2 = lws_dsh_create(&owner, 4096, 2);
if (!dsh2) {
lwsl_err("%s: Failed to create dsh2\n", __func__);
goto bail;
}
if (lws_dsh_alloc_tail(dsh, 0, blob, 4000, NULL, 0)) {
lwsl_err("%s: Failed to alloc 1\n", __func__);
goto bail2;
}
if (lws_dsh_alloc_tail(dsh2, 0, "hello", 5, NULL, 0)) {
lwsl_err("%s: Failed to alloc 2\n", __func__);
goto bail2;
}
/*
* We create this logically on dsh. But there's no room for the body.
* It should figure out it can use space on dsh2.
*/
if (lws_dsh_alloc_tail(dsh, 0, blob, 2000, NULL, 0)) {
lwsl_err("%s: Failed to alloc 3\n", __func__);
goto bail2;
}
if (lws_dsh_alloc_tail(dsh2, 0, "hello again", 11, NULL, 0)) {
lwsl_err("%s: Failed to alloc 4\n", __func__);
goto bail2;
}
/*
* When we destroy dsh2 it will try to migrate out the 2000 allocation
* from there but find there is no space in dsh1. It should handle it
* by logicalling dropping the object.
*/
lws_dsh_destroy(&dsh2);
lws_dsh_destroy(&dsh);
return 0;
bail2:
lws_dsh_destroy(&dsh2);
bail:
lws_dsh_destroy(&dsh);
return 1;
}
int
test3(void)
{
@ -431,10 +352,6 @@ int main(int argc, const char **argv)
lwsl_user("%s: test1: %d\n", __func__, n);
ret |= n;
n = test2();
lwsl_user("%s: test2: %d\n", __func__, n);
ret |= n;
n = test3();
lwsl_user("%s: test3: %d\n", __func__, n);
ret |= n;