From: Brian Aker Date: Sun, 19 Feb 2012 21:13:07 +0000 (-0800) Subject: Update free port logic. X-Git-Tag: 1.0.5~29 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=aa431d73f34773d6a4b7fc104f9bd7ae0384e094;p=awesomized%2Flibmemcached Update free port logic. --- diff --git a/libtest/port.cc b/libtest/port.cc index c1f2f945..152d8360 100644 --- a/libtest/port.cc +++ b/libtest/port.cc @@ -45,66 +45,79 @@ using namespace libtest; +struct socket_st { + std::vector fd; + + ~socket_st() + { + for(std::vector::iterator iter= fd.begin(); iter != fd.end(); iter++) + { + close(*iter); + } + } +}; + +static socket_st all_socket_fd; + static in_port_t global_port= 0; -static in_port_t global_max_port= 0; namespace libtest { in_port_t default_port() { - return global_port; -} - -void set_default_port(in_port_t port) -{ - global_port= port; -} - -in_port_t max_port() -{ - return global_max_port; -} - -void set_max_port(in_port_t port) -{ - if (port > global_max_port) + if (global_port == 0) { - global_max_port= port; + global_port= get_free_port(); } - global_max_port= port; + return global_port; } in_port_t get_free_port() { in_port_t ret_port= in_port_t(0); - int sd; - if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1) + + int retries= 1024; + + while (retries--) { - int optval= 1; - if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1) + int sd; + if ((sd= socket(AF_INET, SOCK_STREAM, 0)) != -1) { - struct sockaddr_in sin; - sin.sin_port= 0; - sin.sin_addr.s_addr= 0; - sin.sin_addr.s_addr= INADDR_ANY; - sin.sin_family= AF_INET; - - if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) != -1) + int optval= 1; + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != -1) { - socklen_t addrlen= sizeof(sin); + struct sockaddr_in sin; + sin.sin_port= 0; + sin.sin_addr.s_addr= 0; + sin.sin_addr.s_addr= INADDR_ANY; + sin.sin_family= AF_INET; - if (listen(sd, 100) != -1) + if (bind(sd, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) != -1) { + socklen_t addrlen= sizeof(sin); + if (getsockname(sd, (struct sockaddr *)&sin, &addrlen) != -1) { ret_port= sin.sin_port; + Error << ret_port; } } } + + all_socket_fd.fd.push_back(sd); + } + + if (ret_port > 1024) + { + break; } + } - close(sd); + // We handle the case where if we max out retries, we still abort. + if (ret_port <= 1024) + { + abort(); } return ret_port; diff --git a/libtest/port.h b/libtest/port.h index d6fbcb25..a7accaec 100644 --- a/libtest/port.h +++ b/libtest/port.h @@ -31,15 +31,6 @@ namespace libtest { LIBTEST_API in_port_t default_port(); -LIBTEST_API -void set_default_port(in_port_t port); - -LIBTEST_API -in_port_t max_port(); - -LIBTEST_API -void set_max_port(in_port_t port); - LIBTEST_API in_port_t get_free_port(); diff --git a/libtest/server_container.cc b/libtest/server_container.cc index 2c31796f..528fcd1f 100644 --- a/libtest/server_container.cc +++ b/libtest/server_container.cc @@ -146,23 +146,6 @@ bool server_startup(server_startup_st& construct, const std::string& server_type Outn(); (void)try_port; - set_max_port(try_port); - - // Look to see if we are being provided ports to use - { - char variable_buffer[1024]; - snprintf(variable_buffer, sizeof(variable_buffer), "LIBTEST_PORT_%lu", (unsigned long)construct.count()); - - char *var; - if ((var= getenv(variable_buffer))) - { - in_port_t tmp= in_port_t(atoi(var)); - - if (tmp > 0) - try_port= tmp; - } - } - libtest::Server *server= NULL; if (0) { } @@ -249,12 +232,6 @@ bool server_startup(server_startup_st& construct, const std::string& server_type construct.push_server(server); - if (default_port() == 0) - { - assert(server->has_port()); - set_default_port(server->port()); - } - Outn(); return true; diff --git a/libtest/unittest.cc b/libtest/unittest.cc index 21dcbc74..77326d1c 100644 --- a/libtest/unittest.cc +++ b/libtest/unittest.cc @@ -510,6 +510,18 @@ static test_return_t get_free_port_TEST(void *) { in_port_t ret_port; test_true_hint((ret_port= get_free_port()), ret_port); + test_true(get_free_port() != default_port()); + test_true(get_free_port() != get_free_port()); + + return TEST_SUCCESS; +} + +static test_return_t default_port_TEST(void *) +{ + in_port_t ret_port= default_port(); + test_compare(ret_port, libtest::default_port()); + test_compare(ret_port, libtest::default_port()); + return TEST_SUCCESS; } @@ -599,6 +611,7 @@ test_st cmdline_tests[] ={ test_st get_free_port_TESTS[] ={ {"get_free_port()", 0, get_free_port_TEST }, + {"default_port()", 0, default_port_TEST }, {0, 0, 0} }; diff --git a/tests/failure.cc b/tests/failure.cc index 1348e50c..20c355d3 100644 --- a/tests/failure.cc +++ b/tests/failure.cc @@ -76,7 +76,7 @@ static test_return_t add_shutdown_servers(memcached_st *memc) while (memcached_server_count(memc) < 2) { const char *argv[1]= { "add_shutdown_server" }; - in_port_t port= max_port() +1; + in_port_t port= libtest::get_free_port(); test_true(global_framework->servers().start_socket_server("memcached", port, 1, argv)); test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "localhost", port)); } diff --git a/tests/memstat.cc b/tests/memstat.cc index c99836ac..2ffb26bd 100644 --- a/tests/memstat.cc +++ b/tests/memstat.cc @@ -73,7 +73,7 @@ static test_return_t help_test(void *) static test_return_t binary_TEST(void *) { char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); + snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port())); const char *args[]= { "--quiet", buffer, " --binary ", 0 }; test_true(exec_cmdline(executable, args)); @@ -83,7 +83,7 @@ static test_return_t binary_TEST(void *) static test_return_t server_version_TEST(void *) { char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); + snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port())); const char *args[]= { "--quiet", buffer, " --server-version", 0 }; test_true(exec_cmdline(executable, args)); @@ -93,7 +93,7 @@ static test_return_t server_version_TEST(void *) static test_return_t binary_server_version_TEST(void *) { char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); + snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(libtest::default_port())); const char *args[]= { "--quiet", buffer, " --binary --server-version", 0 }; test_true(exec_cmdline(executable, args)); @@ -123,7 +123,7 @@ static void *world_create(server_startup_st& servers, test_return_t& error) } const char *argv[1]= { "memstat" }; - if (not server_startup(servers, "memcached", libtest::get_free_port(), 1, argv)) + if (server_startup(servers, "memcached", libtest::default_port(), 1, argv) == false) { error= TEST_FAILURE; }