diff options
author | ajs <ajs> | 2004-11-04 19:26:16 +0000 |
---|---|---|
committer | ajs <ajs> | 2004-11-04 19:26:16 +0000 |
commit | 49ff6d9d7a9ef9419dd7aab58ac9f7806e3e1040 (patch) | |
tree | bb9e1d36b5bef56d2e47c69b6bab1ef54cf9696e /lib/vty.c | |
parent | 62d8e96a06e664c929a164bfb66b515d1c6877a8 (diff) |
2004-11-04 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* vty.c: Vtysh connections to daemons should use buffering.
(vty_out) Remove exception for vty_shell_serv, just use buffer_write.
(vty_new) Increase output buffer size to 4096 rounded up to a
multiple of pagesize.
(vtysh_read) After command has been executed and all output buffered,
call buffer_flush_available and schedule further writes if the
buffers are not yet empty.
(vtysh_write) New function to flush output to vtysh when the socket
is writeable.
(vty_event) Added new VTYSH_WRITE event for flushing buffers to vtysh
clients. Also, should save read thread in vty->t_read so the
thread can be cancelled in vty_close.
* buffer.h: In struct buffer_data, remove unused "parent" field.
Convert "unsigned char *data" to "unsigned char data[0]" to save
a malloc. Declare new function buffer_flush_available that works
with non-blocking sockets.
* buffer.c: (buffer_data_new) Use a single malloc now that data is
a variable-size array at end of structure.
(buffer_data_free) Just a single free now that data is part of the
structure.
(buffer_write) Simplify the logic to make behavior more transparent.
(buffer_flush) Decrease b->length as data is written out.
(buffer_flush_vty_all) Decrease b->length as buffers are freed.
(buffer_flush_vty) Decrease b->length as data is written out.
(buffer_flush_available) New function to flush non-blocking sockets.
Diffstat (limited to 'lib/vty.c')
-rw-r--r-- | lib/vty.c | 34 |
1 files changed, 26 insertions, 8 deletions
@@ -45,10 +45,14 @@ enum event VTY_TIMEOUT_RESET, #ifdef VTYSH VTYSH_SERV, - VTYSH_READ + VTYSH_READ, + VTYSH_WRITE #endif /* VTYSH */ }; +/* Minimum size of output buffers; to be rounded up to multiple of pagesize. */ +#define VTY_OBUF_SIZE 4096 + static void vty_event (enum event, int, struct vty *); /* Extern host structure from command.c */ @@ -127,10 +131,7 @@ vty_out (struct vty *vty, const char *format, ...) p = buf; /* Pointer p must point out buffer. */ - if (vty_shell_serv (vty)) - write (vty->fd, (u_char *) p, len); - else - buffer_write (vty->obuf, (u_char *) p, len); + buffer_write (vty->obuf, (u_char *) p, len); /* If p is not different with buf, it is allocated buffer. */ if (p != buf) @@ -264,8 +265,9 @@ struct vty * vty_new () { struct vty *new = XCALLOC (MTYPE_VTY, sizeof (struct vty)); + int pgsz = getpagesize(); - new->obuf = (struct buffer *) buffer_new (100); + new->obuf = (struct buffer *) buffer_new ((((VTY_OBUF_SIZE-1)/pgsz)+1)*pgsz); new->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ); new->max = VTY_BUFSIZ; new->sb_buffer = NULL; @@ -2014,12 +2016,25 @@ vtysh_read (struct thread *thread) #endif /* VTYSH_DEBUG */ header[3] = ret; - write (vty->fd, header, 4); + buffer_write(vty->obuf, header, 4); + if (!vty->t_write && buffer_flush_available(vty->obuf, vty->fd)) + vty_event (VTYSH_WRITE, vty->fd, vty); vty_event (VTYSH_READ, sock, vty); return 0; } + +static int +vtysh_write (struct thread *thread) +{ + struct vty *vty = THREAD_ARG (thread); + + vty->t_write = NULL; + if (buffer_flush_available(vty->obuf, vty->fd)) + vty_event (VTYSH_WRITE, vty->fd, vty); +} + #endif /* VTYSH */ /* Determine address family to bind. */ @@ -2364,7 +2379,10 @@ vty_event (enum event event, int sock, struct vty *vty) thread_add_read (master, vtysh_accept, vty, sock); break; case VTYSH_READ: - thread_add_read (master, vtysh_read, vty, sock); + vty->t_read = thread_add_read (master, vtysh_read, vty, sock); + break; + case VTYSH_WRITE: + vty->t_write = thread_add_write (master, vtysh_write, vty, sock); break; #endif /* VTYSH */ case VTY_READ: |