When socket dropped before finished, it failed to cleanup.
void
cli_free(cli *c)
{
- CALL(c->cleanup, c);
+ bool done = c->cleanup ? c->cleanup(c) : true;
if (c == cmd_reconfig_stored_cli)
cmd_reconfig_stored_cli = NULL;
- rp_free(c->pool);
+ if (done)
+ rp_free(c->pool);
+ else
+ {
+ sk_close(c->sock);
+ c->sock = NULL;
+ }
}
/**
struct cli_out *tx_buf, *tx_pos, *tx_write;
event *event;
void (*cont)(struct cli *c);
- void (*cleanup)(struct cli *c); /* The CLI has closed prematurely */
+ bool (*cleanup)(struct cli *c); /* The CLI has closed prematurely; if done, return true,
+ otherwise return false and call rp_free(c->pool) later yourself.
+ The socket is closed anyway, tho. */
void *rover; /* Private to continuation routine */
struct config *main_config; /* Main config currently in use */
int last_reply;
}
}
-static void
+static bool
rt_show_cleanup(struct cli *c)
{
struct rt_show_data *d = c->rover;
/* Unreference the config */
OBSREF_CLEAR(d->running_on_config);
+
+ /* Everything cleaned up */
+ return true;
}
static void
return mrt_table_dump_step(c->rover);
}
-void
+static bool
mrt_dump_cleanup(struct cli *c)
{
mrt_table_dump_free(c->rover);
c->rover = NULL;
+ return true;
}
void
/* Explicitly do nothing to prevent CLI from trying to parse another command. */
}
-static int
+static bool
bird_thread_show_cli_cleanup(struct cli *c UNUSED)
{
- return 1; /* Defer the cleanup until the writeout is finished. */
+ /* Defer the cleanup until the writeout is finished. */
+ return false;
}
static void
SKIP_BACK_DECLARE(struct bird_thread_show_data, tsd, sync, sync);
ASSERT_DIE(birdloop_inside(&main_birdloop));
+ /* The client lost their patience and dropped the session early. */
+ if (!tsd->cli->sock)
+ {
+ mb_free(tsd);
+ rp_free(tsd->cli->pool);
+ return;
+ }
+
tsd->cli->cont = NULL;
tsd->cli->cleanup = NULL;