From: Camilo Roca Date: Wed, 10 Jul 2013 08:52:56 +0000 (+0200) Subject: get_sockets_set added for external select() calls. Boost test case added to check... X-Git-Tag: latest_release~8 X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=commitdiff_plain;h=1fdd03d219ebc40bf0ec17fdfea4bf1a20666e3a get_sockets_set added for external select() calls. Boost test case added to check proper behavior. --- diff --git a/src/socket_handler.hxx b/src/socket_handler.hxx index c3522d8..b6776ec 100644 --- a/src/socket_handler.hxx +++ b/src/socket_handler.hxx @@ -70,6 +70,9 @@ class socket_handler socket_type_value get_type() { return socket_type; } + int get_socket() + { return sock; } + bool is_closed(); void set_recv_buffer_size(unsigned int new_recv_buffer_size); diff --git a/src/socket_server.cpp b/src/socket_server.cpp index 18bb722..1d18fd2 100644 --- a/src/socket_server.cpp +++ b/src/socket_server.cpp @@ -165,6 +165,7 @@ void socket_server::start_listening() /* clear & insert server sock into the fd_tab to prepare select */ FD_ZERO(&connection_set); FD_SET (sock, &connection_set); + sockets_set.insert(sock); } /// handle a new connection from a client @@ -190,6 +191,7 @@ void socket_server::new_connection() } FD_SET (newsock, &connection_set); + sockets_set.insert(newsock); socket_server_connection *nc=new socket_server_connection(newsock, get_type(), get_default_timeout()); nc->set_socket_options(newsock); @@ -287,6 +289,7 @@ bool socket_server::fill_connection_buffers() void socket_server::remove_connection_socket(int sock) { FD_CLR(sock, &connection_set); + sockets_set.erase(sock); } /** diff --git a/src/socket_server.hxx b/src/socket_server.hxx index ae30833..74d8e07 100644 --- a/src/socket_server.hxx +++ b/src/socket_server.hxx @@ -24,6 +24,7 @@ on this file might be covered by the GNU General Public License. #include #include +#include #include "server.hxx" #include "socket_handler.hxx" @@ -48,6 +49,7 @@ class socket_server : public socket_handler, public server private: fd_set connection_set; std::string unix_path; + std::set sockets_set; void start_listening(); @@ -67,6 +69,8 @@ class socket_server : public socket_handler, public server ~socket_server(); bool fill_buffer(long long usec_timeout=-1,long long* usec_timeout_remaining=NULL); + std::set get_sockets_set() + { return sockets_set; }; }; /** @brief Socket based connection diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 66f7e7a..8037493 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,7 @@ set(test_SOURCES simplecmd.cpp timeout.cpp wrapper.cpp + getsocket.cpp test_fixtures.hxx ) include_directories(BEFORE diff --git a/test/getsocket.cpp b/test/getsocket.cpp new file mode 100644 index 0000000..96964cb --- /dev/null +++ b/test/getsocket.cpp @@ -0,0 +1,190 @@ +/* +Copyright (C) 2004 by Intra2net AG + +The software in this package is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of GNU General Public License (GPL) is included in this distribution, +in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. +*/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define BOOST_TEST_DYN_LINK +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "test_fixtures.hxx" + +using namespace std; + +set SocketSet; + +bool check_sockets(const int& test_socket) +{ + bool ret = false; + set::iterator it; + for (it = SocketSet.begin(); it != SocketSet.end(); it++) + { + if (test_socket == *it) + { + ret = true; + break; + } + } + return ret; +} + +class checkfunc_res : public libt2n::result +{ + private: + bool res; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result); + ar & BOOST_SERIALIZATION_NVP(res); + } + + public: + checkfunc_res() + { } + + checkfunc_res(const bool& value) + { + res=value; + } + + bool get_data() + { + return res; + } +}; + + +class checkfunc_cmd : public libt2n::command +{ + private: + int param; + + friend class boost::serialization::access; + template + void serialize(Archive & ar, const unsigned int version) + { + ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command); + ar & BOOST_SERIALIZATION_NVP(param); + } + + public: + checkfunc_cmd() + {} + + checkfunc_cmd(const int& value) + { + param=value; + } + + libt2n::result* operator()() + { + return new checkfunc_res(check_sockets(param)); + } +}; + +#include + +BOOST_CLASS_EXPORT(checkfunc_cmd) +BOOST_CLASS_EXPORT(checkfunc_res) + +using namespace libt2n; + +BOOST_FIXTURE_TEST_SUITE(test_getsocket, KillChildOnShutdownFixture) + +BOOST_AUTO_TEST_CASE(SocketCheck) +{ + switch(child_pid=fork()) + { + case -1: + { + BOOST_FAIL("fork error"); + break; + } + case 0: + // child + { + try + { + socket_server ss("./socket"); + command_server cs(ss); + + // max 10 sec + for (int i=0; i < 10; i++) + { + SocketSet = ss.get_sockets_set(); + cs.handle(1000000); + } + } catch(...) + { + std::cerr << "exception in child. ignoring\n"; + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + sc.set_logging(&cerr,debug); + command_client cc(&sc); + + result_container rc; + int socket_fd = sc.get_socket(); + // Next line causes problem + cc.send_command(new checkfunc_cmd(socket_fd),rc); + + bool ret=dynamic_cast(rc.get_result())->get_data(); + + BOOST_CHECK(ret); + } + } +} + + +BOOST_AUTO_TEST_SUITE_END()