On 1/21/2016 7:09 PM, Tetsuya Mukawa wrote: [snip] > + > +static int > +qtest_raw_recv(int fd, char *buf, size_t count) > +{ > + size_t len = count; > + size_t total_len = 0; > + int ret = 0; > + > + while (len > 0) { > + ret = read(fd, buf, len); > + if (ret == (int)len) > + break; > + if (*(buf + ret - 1) == '\n') > + break;
The above two lines should be put after the below if block. > + if (ret == -1) { > + if (errno == EINTR) > + continue; > + return ret; > + } > + total_len += ret; > + buf += ret; > + len -= ret; > + } > + return total_len + ret; > +} > + [snip] > + > +static void > +qtest_handle_one_message(struct qtest_session *s, char *buf) > +{ > + int ret; > + > + if (strncmp(buf, interrupt_message, strlen(interrupt_message)) == 0) { > + if (rte_atomic16_read(&s->enable_intr) == 0) > + return; > + > + /* relay interrupt to pipe */ > + ret = write(s->irqfds.writefd, "1", 1); > + if (ret < 0) > + rte_panic("cannot relay interrupt\n"); > + } else { > + /* relay normal message to pipe */ > + ret = qtest_raw_send(s->msgfds.writefd, buf, strlen(buf)); > + if (ret < 0) > + rte_panic("cannot relay normal message\n"); > + } > +} > + > +static char * > +qtest_get_next_message(char *p) > +{ > + p = strchr(p, '\n'); > + if ((p == NULL) || (*(p + 1) == '\0')) > + return NULL; > + return p + 1; > +} > + > +static void > +qtest_close_one_socket(int *fd) > +{ > + if (*fd > 0) { > + close(*fd); > + *fd = -1; > + } > +} > + > +static void > +qtest_close_sockets(struct qtest_session *s) > +{ > + qtest_close_one_socket(&s->qtest_socket); > + qtest_close_one_socket(&s->msgfds.readfd); > + qtest_close_one_socket(&s->msgfds.writefd); > + qtest_close_one_socket(&s->irqfds.readfd); > + qtest_close_one_socket(&s->irqfds.writefd); > + qtest_close_one_socket(&s->ivshmem_socket); > +} > + > +/* > + * This thread relays QTest response using pipe. > + * The function is needed because we need to separate IRQ message from > others. > + */ > +static void * > +qtest_event_handler(void *data) { > + struct qtest_session *s = (struct qtest_session *)data; > + char buf[1024]; > + char *p; > + int ret; > + > + for (;;) { > + memset(buf, 0, sizeof(buf)); > + ret = qtest_raw_recv(s->qtest_socket, buf, sizeof(buf)); > + if (ret < 0) { > + qtest_close_sockets(s); > + return NULL; > + } > + > + /* may receive multiple messages at the same time */ >From the qtest_raw_recv implementation, if at some point one message is received by two qtest_raw_recv calls, then is that message discarded? We could save the last incomplete message in buffer, and combine the message received next time together. > + p = buf; > + do { > + qtest_handle_one_message(s, p); > + } while ((p = qtest_get_next_message(p)) != NULL); > + } > + return NULL; > +} > +