Get rid of extra select() calls before reading and writing,

in both client and server.  Instead we pass in and use the
fdsets from the main loop's select().
This commit is contained in:
Jef Poskanzer 2013-01-18 10:17:05 -08:00
parent d7613a8e9f
commit 6177a7f1f1
4 changed files with 42 additions and 70 deletions

View File

@ -561,68 +561,40 @@ all_data_sent(struct iperf_test * test)
}
int
iperf_send(struct iperf_test *test)
iperf_send(struct iperf_test *test, fd_set *write_setP)
{
int result;
iperf_size_t bytes_sent;
fd_set temp_write_set;
struct timeval tv;
struct iperf_stream *sp;
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
tv.tv_sec = 15;
tv.tv_usec = 0;
result = select(test->max_fd + 1, NULL, &temp_write_set, NULL, &tv);
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
SLIST_FOREACH(sp, &test->streams, streams) {
if (FD_ISSET(sp->socket, &temp_write_set)) {
if ((bytes_sent = sp->snd(sp)) < 0) {
i_errno = IESTREAMWRITE;
return -1;
}
test->bytes_sent += bytes_sent;
FD_CLR(sp->socket, &temp_write_set);
}
}
SLIST_FOREACH(sp, &test->streams, streams) {
if (FD_ISSET(sp->socket, write_setP)) {
if ((bytes_sent = sp->snd(sp)) < 0) {
i_errno = IESTREAMWRITE;
return -1;
}
test->bytes_sent += bytes_sent;
FD_CLR(sp->socket, write_setP);
}
}
return 0;
}
int
iperf_recv(struct iperf_test *test)
iperf_recv(struct iperf_test *test, fd_set *read_setP)
{
int result;
iperf_size_t bytes_sent;
fd_set temp_read_set;
struct timeval tv;
struct iperf_stream *sp;
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
tv.tv_sec = 15;
tv.tv_usec = 0;
result = select(test->max_fd + 1, &temp_read_set, NULL, NULL, &tv);
if (result < 0) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
SLIST_FOREACH(sp, &test->streams, streams) {
if (FD_ISSET(sp->socket, &temp_read_set)) {
if ((bytes_sent = sp->rcv(sp)) < 0) {
i_errno = IESTREAMREAD;
return -1;
}
test->bytes_sent += bytes_sent;
FD_CLR(sp->socket, &temp_read_set);
}
}
SLIST_FOREACH(sp, &test->streams, streams) {
if (FD_ISSET(sp->socket, read_setP)) {
if ((bytes_sent = sp->rcv(sp)) < 0) {
i_errno = IESTREAMREAD;
return -1;
}
test->bytes_sent += bytes_sent;
FD_CLR(sp->socket, read_setP);
}
}
return 0;

View File

@ -157,8 +157,8 @@ void print_tcpinfo(struct iperf_test *test);
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
void print_interval_results(struct iperf_test * test, struct iperf_stream *sp);
int iperf_send(struct iperf_test *);
int iperf_recv(struct iperf_test *);
int iperf_send(struct iperf_test *, fd_set *);
int iperf_recv(struct iperf_test *, fd_set *);
void sig_handler(int);
void usage();
void usage_long();

View File

@ -183,7 +183,7 @@ int
iperf_run_client(struct iperf_test * test)
{
int result;
fd_set temp_read_set, temp_write_set;
fd_set read_set, write_set;
struct timeval now;
/* Start the client and connect to the server */
@ -197,31 +197,31 @@ iperf_run_client(struct iperf_test * test)
(void) gettimeofday(&now, NULL);
while (test->state != IPERF_DONE) {
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, tmr_timeout(&now));
result = select(test->max_fd + 1, &read_set, &write_set, NULL, tmr_timeout(&now));
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
if (FD_ISSET(test->ctrl_sck, &temp_read_set)) {
if (FD_ISSET(test->ctrl_sck, &read_set)) {
if (iperf_handle_message_client(test) < 0) {
return -1;
}
FD_CLR(test->ctrl_sck, &temp_read_set);
FD_CLR(test->ctrl_sck, &read_set);
}
if (test->state == TEST_RUNNING) {
if (test->reverse) {
// Reverse mode. Client receives.
if (iperf_recv(test) < 0) {
if (iperf_recv(test, &read_set) < 0) {
return -1;
}
} else {
// Regular mode. Client sends.
if (iperf_send(test) < 0) {
if (iperf_send(test, &write_set) < 0) {
return -1;
}
}

View File

@ -273,7 +273,7 @@ int
iperf_run_server(struct iperf_test *test)
{
int result, s, streams_accepted;
fd_set temp_read_set, temp_write_set;
fd_set read_set, write_set;
struct iperf_stream *sp;
struct timeval now;
@ -291,31 +291,31 @@ iperf_run_server(struct iperf_test *test)
(void) gettimeofday(&now, NULL);
while (test->state != IPERF_DONE) {
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, tmr_timeout(&now));
result = select(test->max_fd + 1, &read_set, &write_set, NULL, tmr_timeout(&now));
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
return -1;
}
if (result > 0) {
if (FD_ISSET(test->listener, &temp_read_set)) {
if (FD_ISSET(test->listener, &read_set)) {
if (test->state != CREATE_STREAMS) {
if (iperf_accept(test) < 0) {
return -1;
}
FD_CLR(test->listener, &temp_read_set);
FD_CLR(test->listener, &read_set);
}
}
if (FD_ISSET(test->ctrl_sck, &temp_read_set)) {
if (FD_ISSET(test->ctrl_sck, &read_set)) {
if (iperf_handle_message_server(test) < 0)
return -1;
FD_CLR(test->ctrl_sck, &temp_read_set);
FD_CLR(test->ctrl_sck, &read_set);
}
if (test->state == CREATE_STREAMS) {
if (FD_ISSET(test->prot_listener, &temp_read_set)) {
if (FD_ISSET(test->prot_listener, &read_set)) {
if ((s = test->protocol->accept(test)) < 0)
return -1;
@ -333,7 +333,7 @@ iperf_run_server(struct iperf_test *test)
if (test->on_new_stream)
test->on_new_stream(sp);
}
FD_CLR(test->prot_listener, &temp_read_set);
FD_CLR(test->prot_listener, &read_set);
}
if (streams_accepted == test->num_streams) {
@ -372,11 +372,11 @@ iperf_run_server(struct iperf_test *test)
if (test->state == TEST_RUNNING) {
if (test->reverse) {
// Reverse mode. Server sends.
if (iperf_send(test) < 0)
if (iperf_send(test, &write_set) < 0)
return -1;
} else {
// Regular mode. Server receives.
if (iperf_recv(test) < 0)
if (iperf_recv(test, &read_set) < 0)
return -1;
}