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;
c->close();
// store a copy of the exception that you can find out details about the error later
- std::auto_ptr<t2n_exception> tmp(e.clone());
- constructorException=tmp;
+ constructorException = e.clone();
}
catch (...)
{
}
}
+/**
+ * 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
(*ostr) << "sending command, decoded data: " << std::endl;
boost::archive::xml_oarchive xo(*ostr);
xo << BOOST_SERIALIZATION_NVP(cc);
- }
+ }
c->write(ofs.str());
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<t2n_exception> 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);
bool is_connection_closed(void)
{ return c->is_closed(); }
t2n_exception* get_constuctor_exception(void)
- { return constructorException.get(); }
+ { return constructorException; }
};
}
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;
if (global_server)
global_server->handle(10000);
+ ++seen_client_requests;
+
return ret;
}
public:
testfunc_res()
- { }
+ {
+ }
testfunc_res(const string& str)
{
public:
testfunc_cmd()
- { }
+ {
+ }
testfunc_cmd(const string& str)
{
}
+
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(testfunc_cmd)
// 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;
{
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)
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);
}
}