Skip to content
Snippets Groups Projects
Commit 6baef17e authored by Ondřej Zajíček's avatar Ondřej Zajíček
Browse files

Fixes bug in CLI TX buffer management.

parent 70670bf3
No related branches found
No related tags found
No related merge requests found
......@@ -47,6 +47,20 @@
* The @this_cli variable points to a &cli structure of the session being
* currently parsed, but it's of course available only in command handlers
* not entered using the @cont hook.
*
* TX buffer management works as follows: At cli.tx_buf there is a
* list of TX buffers (struct cli_out), cli.tx_write is the buffer
* currently used by the producer (cli_printf(), cli_alloc_out()) and
* cli.tx_pos is the buffer currently used by the consumer
* (cli_write(), in system dependent code). The producer uses
* cli_out.wpos ptr as the current write position and the consumer
* uses cli_out.outpos ptr as the current read position. When the
* producer produces something, it calls cli_write_trigger(). If there
* is not enough space in the current buffer, the producer allocates
* the new one. When the consumer processes everything in the buffer
* queue, it calls cli_written(), tha frees all buffers (except the
* first one) and schedules cli.event .
*
*/
#include "nest/bird.h"
......@@ -196,6 +210,14 @@ cli_free_out(cli *c)
c->async_msg_size = 0;
}
void
cli_written(cli *c)
{
cli_free_out(c);
ev_schedule(c->event);
}
static byte *cli_rh_pos;
static unsigned int cli_rh_len;
static int cli_rh_trick_flag;
......@@ -263,11 +285,8 @@ cli_event(void *data)
else
cli_command(c);
}
if (cli_write(c))
{
cli_free_out(c);
ev_schedule(c->event);
}
cli_write_trigger(c);
}
cli *
......@@ -296,13 +315,6 @@ cli_kick(cli *c)
ev_schedule(c->event);
}
void
cli_written(cli *c)
{
cli_free_out(c);
ev_schedule(c->event);
}
static list cli_log_hooks;
static int cli_log_inited;
......
......@@ -62,7 +62,7 @@ void cli_echo(unsigned int class, byte *msg);
/* Functions provided by sysdep layer */
int cli_write(cli *);
void cli_write_trigger(cli *);
int cli_get_command(cli *);
#endif
......@@ -178,22 +178,44 @@ cmd_reconfig(char *name, int type)
static sock *cli_sk;
static char *path_control_socket = PATH_CONTROL_SOCKET;
int
static void
cli_write(cli *c)
{
sock *s = c->priv;
if (c->tx_pos)
while (c->tx_pos)
{
struct cli_out *o = c->tx_pos;
int len = o->wpos - o->outpos;
s->tbuf = o->outpos;
if (sk_send(s, o->wpos - o->outpos) > 0)
{
c->tx_pos = o->next;
ev_schedule(c->event);
}
o->outpos = o->wpos;
if (sk_send(s, len) <= 0)
return;
c->tx_pos = o->next;
}
return !c->tx_pos;
/* Everything is written */
s->tbuf = NULL;
cli_written(c);
}
void
cli_write_trigger(cli *c)
{
sock *s = c->priv;
if (s->tbuf == NULL)
cli_write(c);
}
static void
cli_tx(sock *s)
{
cli_write(s->data);
}
int
......@@ -232,15 +254,6 @@ cli_rx(sock *s, int size UNUSED)
return 0;
}
static void
cli_tx(sock *s)
{
cli *c = s->data;
if (cli_write(c))
cli_written(c);
}
static void
cli_err(sock *s, int err)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment