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
|
* 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
|
* currently parsed, but it's of course available only in command handlers
|
||||||
* not entered using the @cont hook.
|
* 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"
|
#include "nest/bird.h"
|
||||||
|
@ -196,6 +210,14 @@ cli_free_out(cli *c)
|
||||||
c->async_msg_size = 0;
|
c->async_msg_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cli_written(cli *c)
|
||||||
|
{
|
||||||
|
cli_free_out(c);
|
||||||
|
ev_schedule(c->event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static byte *cli_rh_pos;
|
static byte *cli_rh_pos;
|
||||||
static unsigned int cli_rh_len;
|
static unsigned int cli_rh_len;
|
||||||
static int cli_rh_trick_flag;
|
static int cli_rh_trick_flag;
|
||||||
|
@ -263,11 +285,8 @@ cli_event(void *data)
|
||||||
else
|
else
|
||||||
cli_command(c);
|
cli_command(c);
|
||||||
}
|
}
|
||||||
if (cli_write(c))
|
|
||||||
{
|
cli_write_trigger(c);
|
||||||
cli_free_out(c);
|
|
||||||
ev_schedule(c->event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cli *
|
cli *
|
||||||
|
@ -296,13 +315,6 @@ cli_kick(cli *c)
|
||||||
ev_schedule(c->event);
|
ev_schedule(c->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cli_written(cli *c)
|
|
||||||
{
|
|
||||||
cli_free_out(c);
|
|
||||||
ev_schedule(c->event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static list cli_log_hooks;
|
static list cli_log_hooks;
|
||||||
static int cli_log_inited;
|
static int cli_log_inited;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ void cli_echo(unsigned int class, byte *msg);
|
||||||
|
|
||||||
/* Functions provided by sysdep layer */
|
/* Functions provided by sysdep layer */
|
||||||
|
|
||||||
int cli_write(cli *);
|
void cli_write_trigger(cli *);
|
||||||
int cli_get_command(cli *);
|
int cli_get_command(cli *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -178,22 +178,44 @@ cmd_reconfig(char *name, int type)
|
||||||
static sock *cli_sk;
|
static sock *cli_sk;
|
||||||
static char *path_control_socket = PATH_CONTROL_SOCKET;
|
static char *path_control_socket = PATH_CONTROL_SOCKET;
|
||||||
|
|
||||||
int
|
|
||||||
|
static void
|
||||||
cli_write(cli *c)
|
cli_write(cli *c)
|
||||||
{
|
{
|
||||||
sock *s = c->priv;
|
sock *s = c->priv;
|
||||||
|
|
||||||
if (c->tx_pos)
|
while (c->tx_pos)
|
||||||
{
|
{
|
||||||
struct cli_out *o = c->tx_pos;
|
struct cli_out *o = c->tx_pos;
|
||||||
|
|
||||||
|
int len = o->wpos - o->outpos;
|
||||||
s->tbuf = o->outpos;
|
s->tbuf = o->outpos;
|
||||||
if (sk_send(s, o->wpos - o->outpos) > 0)
|
o->outpos = o->wpos;
|
||||||
{
|
|
||||||
|
if (sk_send(s, len) <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
c->tx_pos = o->next;
|
c->tx_pos = o->next;
|
||||||
ev_schedule(c->event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Everything is written */
|
||||||
|
s->tbuf = NULL;
|
||||||
|
cli_written(c);
|
||||||
}
|
}
|
||||||
return !c->tx_pos;
|
|
||||||
|
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
|
int
|
||||||
|
@ -232,15 +254,6 @@ cli_rx(sock *s, int size UNUSED)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
cli_tx(sock *s)
|
|
||||||
{
|
|
||||||
cli *c = s->data;
|
|
||||||
|
|
||||||
if (cli_write(c))
|
|
||||||
cli_written(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cli_err(sock *s, int err)
|
cli_err(sock *s, int err)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue