From: Thomas Jarosch Date: Wed, 26 Nov 2008 13:08:33 +0000 (+0000) Subject: libt2n: (tomj) don't use std::auto_ptr in command_client, the pointer will get lost... X-Git-Tag: v0.5~4 X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=commitdiff_plain;h=696c95c2808d6f88df2b348f9e77fc66c9068976 libt2n: (tomj) don't use std::auto_ptr in command_client, the pointer will get lost if the command_client is stored in a STL container. Improve reentrant test to check for positive results after all clients finished (nice stress test) --- diff --git a/src/command_client.cpp b/src/command_client.cpp index 52ca0f1..5d71692 100644 --- a/src/command_client.cpp +++ b/src/command_client.cpp @@ -39,8 +39,15 @@ using namespace std; namespace libt2n { +/** + * Constructor + * @param _c connection for this command. Ownership of the pointer is outside. + * @param _command_timeout_usec timeout until the command has to be completed + * @param _hello_timeout_usec timeout until hello has to be received + */ command_client::command_client(client_connection* _c, long long _command_timeout_usec, long long _hello_timeout_usec) : c(_c) + , constructorException(NULL) { command_timeout_usec=_command_timeout_usec; hello_timeout_usec=_hello_timeout_usec; @@ -60,8 +67,7 @@ command_client::command_client(client_connection* _c, long long _command_timeout c->close(); // store a copy of the exception that you can find out details about the error later - std::auto_ptr tmp(e.clone()); - constructorException=tmp; + constructorException = e.clone(); } catch (...) { @@ -70,6 +76,18 @@ command_client::command_client(client_connection* _c, long long _command_timeout } } +/** + * Destructor + */ +command_client::~command_client() +{ + if (constructorException) + { + delete constructorException; + constructorException = NULL; + } +} + /** @brief replace the connection currently in use with a new one @param _c pointer to the new connection @@ -259,7 +277,7 @@ void command_client::send_command(command* cmd, result_container &res) (*ostr) << "sending command, decoded data: " << std::endl; boost::archive::xml_oarchive xo(*ostr); xo << BOOST_SERIALIZATION_NVP(cc); - } + } c->write(ofs.str()); diff --git a/src/command_client.hxx b/src/command_client.hxx index 49f2819..dee28a1 100644 --- a/src/command_client.hxx +++ b/src/command_client.hxx @@ -45,14 +45,13 @@ class command_client std::string read_packet(const long long &usec_timeout); bool check_hello(const std::string& hellostr); - // TODO: Deny access to copy constructor or use boost::shared_ptr - std::auto_ptr constructorException; + t2n_exception *constructorException; public: command_client(client_connection* _c, long long _command_timeout_usec=command_timeout_usec_default, long long _hello_timeout_usec=hello_timeout_usec_default); - virtual ~command_client() {} + virtual ~command_client(); void replace_connection(client_connection* _c); @@ -69,7 +68,7 @@ class command_client bool is_connection_closed(void) { return c->is_closed(); } t2n_exception* get_constuctor_exception(void) - { return constructorException.get(); } + { return constructorException; } }; } diff --git a/test/reentrant.cpp b/test/reentrant.cpp index 7187ffe..c60baae 100644 --- a/test/reentrant.cpp +++ b/test/reentrant.cpp @@ -40,6 +40,12 @@ namespace command_server *global_server = NULL; +int fork_count = 3; +int requests_per_child = 100; +int all_requests = (2 << (fork_count-1)) * requests_per_child; + +int seen_client_requests = 0; + string testfunc(const string& str) { string ret; @@ -49,6 +55,8 @@ string testfunc(const string& str) if (global_server) global_server->handle(10000); + ++seen_client_requests; + return ret; } @@ -67,7 +75,8 @@ class testfunc_res : public libt2n::result public: testfunc_res() - { } + { + } testfunc_res(const string& str) { @@ -96,7 +105,8 @@ class testfunc_cmd : public libt2n::command public: testfunc_cmd() - { } + { + } testfunc_cmd(const string& str) { @@ -111,6 +121,7 @@ class testfunc_cmd : public libt2n::command } + #include BOOST_CLASS_EXPORT(testfunc_cmd) @@ -145,18 +156,18 @@ class test_reentrant : public TestFixture // child { // wait till server is up - sleep(3); + sleep(2); - // we want 8 identical childs hammering the server - fork(); - fork(); - fork(); + // hammer the server + for (int i = 0; i < fork_count; i++) + fork(); try { - for (int i=0; i < 100; i++) + for (int i=0; i < requests_per_child; i++) { socket_client_connection sc("./socket"); + // sc.set_logging(&cerr,debug); command_client cc(&sc); result_container rc; @@ -167,11 +178,11 @@ class test_reentrant : public TestFixture { string ret = res->get_data(); if (ret != "hello, testfunc() was here") - std::cout << "ERROR reentrant server testfunc_res failed, res: " << ret << "\n"; + std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n"; } else { - std::cout << "ERROR result from reentrant server empty\n"; + std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n"; } } } catch (exception &e) @@ -194,26 +205,26 @@ class test_reentrant : public TestFixture global_server=&cs; - // max 10 sec - long long maxtime=1000000; - while(maxtime > 0) - cs.handle(maxtime,&maxtime); - - // max 10 sec - maxtime=1000000; - while(maxtime > 0) - cs.handle(maxtime,&maxtime); + // Wait until all requests have successed + int safety_check = 0; + while (seen_client_requests < all_requests) + { + ++safety_check; + if (safety_check > 10) { + std::cerr << "reached safety check, aborting.\n"; + break; + } - // max 10 sec - maxtime=1000000; - while(maxtime > 0) - cs.handle(maxtime,&maxtime); + long long maxtime=1000000; + while(maxtime > 0) + cs.handle(maxtime,&maxtime); + } global_server = NULL; } // we are still alive, everything is ok - CPPUNIT_ASSERT_EQUAL(1,1); + CPPUNIT_ASSERT_EQUAL(all_requests, seen_client_requests); } }