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:
parent
1e56dc9642
commit
c38567960a
2 changed files with 2 additions and 202 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue