diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-02-16 23:25:44 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-02-16 23:25:44 +0100 |
| commit | 52a515d18724bbb34e3ccbbb0218efcc4eccc0a8 (patch) | |
| tree | 16a5a05a328d7e0bd2b4b1bfbcaf543cf8a36d33 | |
| parent | dc207f669675a271812a21b0ddbe3b894adf8e4c (diff) | |
| download | busybox-w32-52a515d18724bbb34e3ccbbb0218efcc4eccc0a8.tar.gz busybox-w32-52a515d18724bbb34e3ccbbb0218efcc4eccc0a8.tar.bz2 busybox-w32-52a515d18724bbb34e3ccbbb0218efcc4eccc0a8.zip | |
udhcp: use poll() instead of select()
function old new delta
udhcp_sp_read 65 46 -19
udhcp_sp_fd_set 79 54 -25
udhcpd_main 1530 1482 -48
udhcpc_main 2780 2730 -50
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-142) Total: -142 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/udhcp/common.h | 4 | ||||
| -rw-r--r-- | networking/udhcp/d6_dhcpc.c | 26 | ||||
| -rw-r--r-- | networking/udhcp/dhcpc.c | 26 | ||||
| -rw-r--r-- | networking/udhcp/dhcpd.c | 21 | ||||
| -rw-r--r-- | networking/udhcp/signalpipe.c | 21 |
5 files changed, 45 insertions, 53 deletions
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index a526494d7..ee12cf91b 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
| @@ -300,8 +300,8 @@ int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | |||
| 300 | uint32_t dest_nip, int dest_port) FAST_FUNC; | 300 | uint32_t dest_nip, int dest_port) FAST_FUNC; |
| 301 | 301 | ||
| 302 | void udhcp_sp_setup(void) FAST_FUNC; | 302 | void udhcp_sp_setup(void) FAST_FUNC; |
| 303 | int udhcp_sp_fd_set(fd_set *rfds, int extra_fd) FAST_FUNC; | 303 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; |
| 304 | int udhcp_sp_read(const fd_set *rfds) FAST_FUNC; | 304 | int udhcp_sp_read(struct pollfd *pfds) FAST_FUNC; |
| 305 | 305 | ||
| 306 | int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; | 306 | int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; |
| 307 | 307 | ||
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 64339c9b5..067d35115 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
| @@ -935,9 +935,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 935 | int timeout; /* must be signed */ | 935 | int timeout; /* must be signed */ |
| 936 | unsigned already_waited_sec; | 936 | unsigned already_waited_sec; |
| 937 | unsigned opt; | 937 | unsigned opt; |
| 938 | int max_fd; | ||
| 939 | int retval; | 938 | int retval; |
| 940 | fd_set rfds; | ||
| 941 | 939 | ||
| 942 | setup_common_bufsiz(); | 940 | setup_common_bufsiz(); |
| 943 | 941 | ||
| @@ -1063,7 +1061,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 1063 | * "continue" statements in code below jump to the top of the loop. | 1061 | * "continue" statements in code below jump to the top of the loop. |
| 1064 | */ | 1062 | */ |
| 1065 | for (;;) { | 1063 | for (;;) { |
| 1066 | struct timeval tv; | 1064 | int tv; |
| 1065 | struct pollfd pfds[2]; | ||
| 1067 | struct d6_packet packet; | 1066 | struct d6_packet packet; |
| 1068 | uint8_t *packet_end; | 1067 | uint8_t *packet_end; |
| 1069 | /* silence "uninitialized!" warning */ | 1068 | /* silence "uninitialized!" warning */ |
| @@ -1078,16 +1077,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 1078 | * to change_listen_mode(). Thus we open listen socket | 1077 | * to change_listen_mode(). Thus we open listen socket |
| 1079 | * BEFORE we send renew request (see "case BOUND:"). */ | 1078 | * BEFORE we send renew request (see "case BOUND:"). */ |
| 1080 | 1079 | ||
| 1081 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); | 1080 | udhcp_sp_fd_set(pfds, sockfd); |
| 1082 | 1081 | ||
| 1083 | tv.tv_sec = timeout - already_waited_sec; | 1082 | tv = timeout - already_waited_sec; |
| 1084 | tv.tv_usec = 0; | ||
| 1085 | retval = 0; | 1083 | retval = 0; |
| 1086 | /* If we already timed out, fall through with retval = 0, else... */ | 1084 | /* If we already timed out, fall through with retval = 0, else... */ |
| 1087 | if ((int)tv.tv_sec > 0) { | 1085 | if (tv > 0) { |
| 1088 | log1("waiting on select %u seconds", (int)tv.tv_sec); | 1086 | log1("waiting on select %u seconds", tv); |
| 1089 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1087 | timestamp_before_wait = (unsigned)monotonic_sec(); |
| 1090 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1088 | retval = poll(pfds, 2, tv * 1000); |
| 1091 | if (retval < 0) { | 1089 | if (retval < 0) { |
| 1092 | /* EINTR? A signal was caught, don't panic */ | 1090 | /* EINTR? A signal was caught, don't panic */ |
| 1093 | if (errno == EINTR) { | 1091 | if (errno == EINTR) { |
| @@ -1222,8 +1220,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 1222 | /* select() didn't timeout, something happened */ | 1220 | /* select() didn't timeout, something happened */ |
| 1223 | 1221 | ||
| 1224 | /* Is it a signal? */ | 1222 | /* Is it a signal? */ |
| 1225 | /* note: udhcp_sp_read checks FD_ISSET before reading */ | 1223 | /* note: udhcp_sp_read checks poll result before reading */ |
| 1226 | switch (udhcp_sp_read(&rfds)) { | 1224 | switch (udhcp_sp_read(pfds)) { |
| 1227 | case SIGUSR1: | 1225 | case SIGUSR1: |
| 1228 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1226 | client_config.first_secs = 0; /* make secs field count from 0 */ |
| 1229 | already_waited_sec = 0; | 1227 | already_waited_sec = 0; |
| @@ -1258,7 +1256,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 1258 | } | 1256 | } |
| 1259 | 1257 | ||
| 1260 | /* Is it a packet? */ | 1258 | /* Is it a packet? */ |
| 1261 | if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds)) | 1259 | if (listen_mode == LISTEN_NONE || !pfds[1].revents) |
| 1262 | continue; /* no */ | 1260 | continue; /* no */ |
| 1263 | 1261 | ||
| 1264 | { | 1262 | { |
| @@ -1460,8 +1458,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
| 1460 | if (lease_seconds < 0x10) | 1458 | if (lease_seconds < 0x10) |
| 1461 | lease_seconds = 0x10; | 1459 | lease_seconds = 0x10; |
| 1462 | /// TODO: check for 0 lease time? | 1460 | /// TODO: check for 0 lease time? |
| 1463 | if (lease_seconds >= 0x10000000) | 1461 | if (lease_seconds > 0x7fffffff / 1000) |
| 1464 | lease_seconds = 0x0fffffff; | 1462 | lease_seconds = 0x7fffffff / 1000; |
| 1465 | /* enter bound state */ | 1463 | /* enter bound state */ |
| 1466 | timeout = lease_seconds / 2; | 1464 | timeout = lease_seconds / 2; |
| 1467 | bb_error_msg("lease obtained, lease time %u", | 1465 | bb_error_msg("lease obtained, lease time %u", |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 0e236261b..8f7f59e08 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
| @@ -1281,9 +1281,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1281 | unsigned already_waited_sec; | 1281 | unsigned already_waited_sec; |
| 1282 | unsigned opt; | 1282 | unsigned opt; |
| 1283 | IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) | 1283 | IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) |
| 1284 | int max_fd; | ||
| 1285 | int retval; | 1284 | int retval; |
| 1286 | fd_set rfds; | ||
| 1287 | 1285 | ||
| 1288 | setup_common_bufsiz(); | 1286 | setup_common_bufsiz(); |
| 1289 | 1287 | ||
| @@ -1432,7 +1430,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1432 | * "continue" statements in code below jump to the top of the loop. | 1430 | * "continue" statements in code below jump to the top of the loop. |
| 1433 | */ | 1431 | */ |
| 1434 | for (;;) { | 1432 | for (;;) { |
| 1435 | struct timeval tv; | 1433 | int tv; |
| 1434 | struct pollfd pfds[2]; | ||
| 1436 | struct dhcp_packet packet; | 1435 | struct dhcp_packet packet; |
| 1437 | /* silence "uninitialized!" warning */ | 1436 | /* silence "uninitialized!" warning */ |
| 1438 | unsigned timestamp_before_wait = timestamp_before_wait; | 1437 | unsigned timestamp_before_wait = timestamp_before_wait; |
| @@ -1446,16 +1445,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1446 | * to change_listen_mode(). Thus we open listen socket | 1445 | * to change_listen_mode(). Thus we open listen socket |
| 1447 | * BEFORE we send renew request (see "case BOUND:"). */ | 1446 | * BEFORE we send renew request (see "case BOUND:"). */ |
| 1448 | 1447 | ||
| 1449 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); | 1448 | udhcp_sp_fd_set(pfds, sockfd); |
| 1450 | 1449 | ||
| 1451 | tv.tv_sec = timeout - already_waited_sec; | 1450 | tv = timeout - already_waited_sec; |
| 1452 | tv.tv_usec = 0; | ||
| 1453 | retval = 0; | 1451 | retval = 0; |
| 1454 | /* If we already timed out, fall through with retval = 0, else... */ | 1452 | /* If we already timed out, fall through with retval = 0, else... */ |
| 1455 | if ((int)tv.tv_sec > 0) { | 1453 | if (tv > 0) { |
| 1456 | log1("waiting on select %u seconds", (int)tv.tv_sec); | 1454 | log1("waiting on select %u seconds", tv); |
| 1457 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1455 | timestamp_before_wait = (unsigned)monotonic_sec(); |
| 1458 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1456 | retval = poll(pfds, 2, tv * 1000); |
| 1459 | if (retval < 0) { | 1457 | if (retval < 0) { |
| 1460 | /* EINTR? A signal was caught, don't panic */ | 1458 | /* EINTR? A signal was caught, don't panic */ |
| 1461 | if (errno == EINTR) { | 1459 | if (errno == EINTR) { |
| @@ -1591,8 +1589,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1591 | /* select() didn't timeout, something happened */ | 1589 | /* select() didn't timeout, something happened */ |
| 1592 | 1590 | ||
| 1593 | /* Is it a signal? */ | 1591 | /* Is it a signal? */ |
| 1594 | /* note: udhcp_sp_read checks FD_ISSET before reading */ | 1592 | /* note: udhcp_sp_read checks poll result before reading */ |
| 1595 | switch (udhcp_sp_read(&rfds)) { | 1593 | switch (udhcp_sp_read(pfds)) { |
| 1596 | case SIGUSR1: | 1594 | case SIGUSR1: |
| 1597 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1595 | client_config.first_secs = 0; /* make secs field count from 0 */ |
| 1598 | already_waited_sec = 0; | 1596 | already_waited_sec = 0; |
| @@ -1627,7 +1625,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1627 | } | 1625 | } |
| 1628 | 1626 | ||
| 1629 | /* Is it a packet? */ | 1627 | /* Is it a packet? */ |
| 1630 | if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds)) | 1628 | if (listen_mode == LISTEN_NONE || !pfds[1].revents) |
| 1631 | continue; /* no */ | 1629 | continue; /* no */ |
| 1632 | 1630 | ||
| 1633 | { | 1631 | { |
| @@ -1742,8 +1740,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
| 1742 | /* paranoia: must not be too small and not prone to overflows */ | 1740 | /* paranoia: must not be too small and not prone to overflows */ |
| 1743 | if (lease_seconds < 0x10) | 1741 | if (lease_seconds < 0x10) |
| 1744 | lease_seconds = 0x10; | 1742 | lease_seconds = 0x10; |
| 1745 | if (lease_seconds >= 0x10000000) | 1743 | if (lease_seconds > 0x7fffffff / 1000) |
| 1746 | lease_seconds = 0x0fffffff; | 1744 | lease_seconds = 0x7fffffff / 1000; |
| 1747 | } | 1745 | } |
| 1748 | #if ENABLE_FEATURE_UDHCPC_ARPING | 1746 | #if ENABLE_FEATURE_UDHCPC_ARPING |
| 1749 | if (opt & OPT_a) { | 1747 | if (opt & OPT_a) { |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index e116ba3af..5eff026bc 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
| @@ -794,7 +794,7 @@ static NOINLINE void send_inform(struct dhcp_packet *oldpacket) | |||
| 794 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 794 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 795 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) | 795 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) |
| 796 | { | 796 | { |
| 797 | int server_socket = -1, retval, max_sock; | 797 | int server_socket = -1, retval; |
| 798 | uint8_t *state; | 798 | uint8_t *state; |
| 799 | unsigned timeout_end; | 799 | unsigned timeout_end; |
| 800 | unsigned num_ips; | 800 | unsigned num_ips; |
| @@ -891,10 +891,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 891 | continue_with_autotime: | 891 | continue_with_autotime: |
| 892 | timeout_end = monotonic_sec() + server_config.auto_time; | 892 | timeout_end = monotonic_sec() + server_config.auto_time; |
| 893 | while (1) { /* loop until universe collapses */ | 893 | while (1) { /* loop until universe collapses */ |
| 894 | fd_set rfds; | 894 | struct pollfd pfds[2]; |
| 895 | struct dhcp_packet packet; | 895 | struct dhcp_packet packet; |
| 896 | int bytes; | 896 | int bytes; |
| 897 | struct timeval tv; | 897 | int tv; |
| 898 | uint8_t *server_id_opt; | 898 | uint8_t *server_id_opt; |
| 899 | uint8_t *requested_ip_opt; | 899 | uint8_t *requested_ip_opt; |
| 900 | uint32_t requested_nip = requested_nip; /* for compiler */ | 900 | uint32_t requested_nip = requested_nip; /* for compiler */ |
| @@ -906,16 +906,11 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 906 | server_config.interface); | 906 | server_config.interface); |
| 907 | } | 907 | } |
| 908 | 908 | ||
| 909 | max_sock = udhcp_sp_fd_set(&rfds, server_socket); | 909 | udhcp_sp_fd_set(pfds, server_socket); |
| 910 | if (server_config.auto_time) { | 910 | tv = timeout_end - monotonic_sec(); |
| 911 | /* cast to signed is essential if tv_sec is wider than int */ | ||
| 912 | tv.tv_sec = (int)(timeout_end - monotonic_sec()); | ||
| 913 | tv.tv_usec = 0; | ||
| 914 | } | ||
| 915 | retval = 0; | 911 | retval = 0; |
| 916 | if (!server_config.auto_time || tv.tv_sec > 0) { | 912 | if (!server_config.auto_time || tv > 0) { |
| 917 | retval = select(max_sock + 1, &rfds, NULL, NULL, | 913 | retval = poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1); |
| 918 | server_config.auto_time ? &tv : NULL); | ||
| 919 | } | 914 | } |
| 920 | if (retval == 0) { | 915 | if (retval == 0) { |
| 921 | write_leases(); | 916 | write_leases(); |
| @@ -926,7 +921,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 926 | continue; | 921 | continue; |
| 927 | } | 922 | } |
| 928 | 923 | ||
| 929 | switch (udhcp_sp_read(&rfds)) { | 924 | switch (udhcp_sp_read(pfds)) { |
| 930 | case SIGUSR1: | 925 | case SIGUSR1: |
| 931 | bb_error_msg("received %s", "SIGUSR1"); | 926 | bb_error_msg("received %s", "SIGUSR1"); |
| 932 | write_leases(); | 927 | write_leases(); |
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c index 30bccd6bf..b101b4ce4 100644 --- a/networking/udhcp/signalpipe.c +++ b/networking/udhcp/signalpipe.c | |||
| @@ -48,28 +48,29 @@ void FAST_FUNC udhcp_sp_setup(void) | |||
| 48 | , signal_handler); | 48 | , signal_handler); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /* Quick little function to setup the rfds. Will return the | 51 | /* Quick little function to setup the pfds. |
| 52 | * max_fd for use with select. Limited in that you can only pass | 52 | * Limited in that you can only pass one extra fd. |
| 53 | * one extra fd */ | 53 | */ |
| 54 | int FAST_FUNC udhcp_sp_fd_set(fd_set *rfds, int extra_fd) | 54 | void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd) |
| 55 | { | 55 | { |
| 56 | FD_ZERO(rfds); | 56 | pfds[0].fd = signal_pipe.rd; |
| 57 | FD_SET(signal_pipe.rd, rfds); | 57 | pfds[0].events = POLLIN; |
| 58 | pfds[1].fd = -1; | ||
| 58 | if (extra_fd >= 0) { | 59 | if (extra_fd >= 0) { |
| 59 | close_on_exec_on(extra_fd); | 60 | close_on_exec_on(extra_fd); |
| 60 | FD_SET(extra_fd, rfds); | 61 | pfds[1].fd = extra_fd; |
| 62 | pfds[1].events = POLLIN; | ||
| 61 | } | 63 | } |
| 62 | return signal_pipe.rd > extra_fd ? signal_pipe.rd : extra_fd; | ||
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | /* Read a signal from the signal pipe. Returns 0 if there is | 66 | /* Read a signal from the signal pipe. Returns 0 if there is |
| 66 | * no signal, -1 on error (and sets errno appropriately), and | 67 | * no signal, -1 on error (and sets errno appropriately), and |
| 67 | * your signal on success */ | 68 | * your signal on success */ |
| 68 | int FAST_FUNC udhcp_sp_read(const fd_set *rfds) | 69 | int FAST_FUNC udhcp_sp_read(struct pollfd pfds[2]) |
| 69 | { | 70 | { |
| 70 | unsigned char sig; | 71 | unsigned char sig; |
| 71 | 72 | ||
| 72 | if (!FD_ISSET(signal_pipe.rd, rfds)) | 73 | if (!pfds[0].revents) |
| 73 | return 0; | 74 | return 0; |
| 74 | 75 | ||
| 75 | if (safe_read(signal_pipe.rd, &sig, 1) != 1) | 76 | if (safe_read(signal_pipe.rd, &sig, 1) != 1) |
