Fixes bug in CLI TX buffer management.
This commit is contained in:
parent
70670bf317
commit
6baef17ecf
3 changed files with 55 additions and 30 deletions
36
nest/cli.c
36
nest/cli.c
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue