1
1

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().
Этот коммит содержится в:
Jef Poskanzer 2013-01-18 10:17:05 -08:00
родитель d7613a8e9f
Коммит 6177a7f1f1
4 изменённых файлов: 42 добавлений и 70 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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