Commit aa0bc6b68c98d4b8122a846c962a1bac1c329ca4
1 parent
1c213d19
avoid losing chars in serial console
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1564 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
28 additions
and
6 deletions
vl.c
| @@ -1138,7 +1138,11 @@ CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) | @@ -1138,7 +1138,11 @@ CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) | ||
| 1138 | 1138 | ||
| 1139 | #define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */ | 1139 | #define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */ |
| 1140 | 1140 | ||
| 1141 | +#define TERM_FIFO_MAX_SIZE 1 | ||
| 1142 | + | ||
| 1141 | static int term_got_escape, client_index; | 1143 | static int term_got_escape, client_index; |
| 1144 | +static uint8_t term_fifo[TERM_FIFO_MAX_SIZE]; | ||
| 1145 | +int term_fifo_size; | ||
| 1142 | 1146 | ||
| 1143 | void term_print_help(void) | 1147 | void term_print_help(void) |
| 1144 | { | 1148 | { |
| @@ -1207,19 +1211,37 @@ static void stdio_received_byte(int ch) | @@ -1207,19 +1211,37 @@ static void stdio_received_byte(int ch) | ||
| 1207 | 1211 | ||
| 1208 | chr = stdio_clients[client_index]; | 1212 | chr = stdio_clients[client_index]; |
| 1209 | s = chr->opaque; | 1213 | s = chr->opaque; |
| 1210 | - buf[0] = ch; | ||
| 1211 | - /* XXX: should queue the char if the device is not | ||
| 1212 | - ready */ | ||
| 1213 | - if (s->fd_can_read(s->fd_opaque) > 0) | 1214 | + if (s->fd_can_read(s->fd_opaque) > 0) { |
| 1215 | + buf[0] = ch; | ||
| 1214 | s->fd_read(s->fd_opaque, buf, 1); | 1216 | s->fd_read(s->fd_opaque, buf, 1); |
| 1217 | + } else if (term_fifo_size == 0) { | ||
| 1218 | + term_fifo[term_fifo_size++] = ch; | ||
| 1219 | + } | ||
| 1215 | } | 1220 | } |
| 1216 | } | 1221 | } |
| 1217 | } | 1222 | } |
| 1218 | 1223 | ||
| 1219 | static int stdio_can_read(void *opaque) | 1224 | static int stdio_can_read(void *opaque) |
| 1220 | { | 1225 | { |
| 1221 | - /* XXX: not strictly correct */ | ||
| 1222 | - return 1; | 1226 | + CharDriverState *chr; |
| 1227 | + FDCharDriver *s; | ||
| 1228 | + | ||
| 1229 | + if (client_index < stdio_nb_clients) { | ||
| 1230 | + chr = stdio_clients[client_index]; | ||
| 1231 | + s = chr->opaque; | ||
| 1232 | + /* try to flush the queue if needed */ | ||
| 1233 | + if (term_fifo_size != 0 && s->fd_can_read(s->fd_opaque) > 0) { | ||
| 1234 | + s->fd_read(s->fd_opaque, term_fifo, 1); | ||
| 1235 | + term_fifo_size = 0; | ||
| 1236 | + } | ||
| 1237 | + /* see if we can absorb more chars */ | ||
| 1238 | + if (term_fifo_size == 0) | ||
| 1239 | + return 1; | ||
| 1240 | + else | ||
| 1241 | + return 0; | ||
| 1242 | + } else { | ||
| 1243 | + return 1; | ||
| 1244 | + } | ||
| 1223 | } | 1245 | } |
| 1224 | 1246 | ||
| 1225 | static void stdio_read(void *opaque, const uint8_t *buf, int size) | 1247 | static void stdio_read(void *opaque, const uint8_t *buf, int size) |