2 Copyright (C) 2004 by Intra2net AG
4 The software in this package is distributed under the GNU General
5 Public License version 2 (with a special exception described below).
7 A copy of GNU General Public License (GPL) is included in this distribution,
8 in the file COPYING.GPL.
10 As a special exception, if other files instantiate templates or use macros
11 or inline functions from this file, or you compile this file and link it
12 with other works to produce a work based on this file, this file
13 does not by itself cause the resulting work to be covered
14 by the GNU General Public License.
16 However the source code for this file must still be made available
17 in accordance with section (3) of the GNU General Public License.
19 This exception does not invalidate any other reasons why a work based
20 on this file might be covered by the GNU General Public License.
22 #include <sys/types.h>
33 #include <cppunit/extensions/TestFactoryRegistry.h>
34 #include <cppunit/ui/text/TestRunner.h>
35 #include <cppunit/extensions/HelperMacros.h>
37 #include <boost/archive/binary_oarchive.hpp>
38 #include <boost/archive/binary_iarchive.hpp>
39 #include <boost/archive/xml_oarchive.hpp>
40 #include <boost/archive/xml_iarchive.hpp>
41 #include <boost/serialization/serialization.hpp>
43 #include <container.hxx>
44 #include <socket_client.hxx>
45 #include <socket_server.hxx>
46 #include <command_client.hxx>
47 #include <command_server.hxx>
50 using namespace CppUnit;
51 using namespace libt2n;
56 command_server *global_server = NULL;
59 int requests_per_child = 100;
60 int all_requests = (2 << (fork_count-1)) * requests_per_child;
62 int seen_client_requests = 0;
64 string testfunc(const string& str)
67 ret=str+", testfunc() was here";
69 // call handle, eventually reentrant
71 global_server->handle(10000);
73 ++seen_client_requests;
78 class testfunc_res : public libt2n::result
83 friend class boost::serialization::access;
84 template<class Archive>
85 void serialize(Archive & ar, const unsigned int version)
87 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
88 ar & BOOST_SERIALIZATION_NVP(res);
96 testfunc_res(const string& str)
108 class testfunc_cmd : public libt2n::command
113 friend class boost::serialization::access;
114 template<class Archive>
115 void serialize(Archive & ar, const unsigned int version)
117 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
118 ar & BOOST_SERIALIZATION_NVP(param);
126 testfunc_cmd(const string& str)
131 libt2n::result* operator()()
133 return new testfunc_res(testfunc(param));
140 #include <boost/serialization/export.hpp>
142 BOOST_CLASS_EXPORT(reentrant::testfunc_cmd)
143 BOOST_CLASS_EXPORT(reentrant::testfunc_res)
145 using namespace reentrant;
147 class test_reentrant : public TestFixture
149 CPPUNIT_TEST_SUITE(test_reentrant);
151 CPPUNIT_TEST(ReentrantServer);
153 CPPUNIT_TEST_SUITE_END();
163 void ReentrantServer()
169 CPPUNIT_FAIL("fork error");
175 // wait till server is up
179 for (int i = 0; i < fork_count; i++)
184 for (int i=0; i < requests_per_child; i++)
186 socket_client_connection sc("./socket");
187 // sc.set_logging(&cerr,debug);
188 command_client cc(&sc);
191 cc.send_command(new testfunc_cmd("hello"),rc);
193 testfunc_res *res = dynamic_cast<testfunc_res*>(rc.get_result());
196 string ret = res->get_data();
197 if (ret != "hello, testfunc() was here")
198 std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n";
202 std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n";
205 } catch (exception &e)
207 cerr << "caught exception: " << e.what() << endl;
210 std::cerr << "exception in child. ignoring\n";
213 // don't call atexit and stuff
220 // don't kill us on broken pipe
221 signal(SIGPIPE, SIG_IGN);
223 socket_server ss("./socket");
224 command_server cs(ss);
228 // Wait until all requests have successed
229 int safety_check = 0;
230 while (seen_client_requests < all_requests)
233 if (safety_check > 10) {
234 std::cerr << "reached safety check, aborting.\n";
238 long long maxtime=1000000;
240 cs.handle(maxtime,&maxtime);
243 global_server = NULL;
246 // we are still alive, everything is ok
247 CPPUNIT_ASSERT_EQUAL(all_requests, seen_client_requests);
254 CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant);