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 #define BOOST_TEST_DYN_LINK
34 #include <boost/test/unit_test.hpp>
36 #include <boost/archive/binary_oarchive.hpp>
37 #include <boost/archive/binary_iarchive.hpp>
38 #include <boost/archive/xml_oarchive.hpp>
39 #include <boost/archive/xml_iarchive.hpp>
40 #include <boost/serialization/serialization.hpp>
42 #include <container.hxx>
43 #include <socket_client.hxx>
44 #include <socket_server.hxx>
45 #include <command_client.hxx>
46 #include <command_server.hxx>
49 using namespace libt2n;
54 command_server *global_server = NULL;
57 int requests_per_child = 100;
58 int all_requests = (2 << (fork_count-1)) * requests_per_child;
60 int seen_client_requests = 0;
62 string testfunc(const string& str)
65 ret=str+", testfunc() was here";
67 // call handle, eventually reentrant
69 global_server->handle(10000);
71 ++seen_client_requests;
76 class testfunc_res : public libt2n::result
81 friend class boost::serialization::access;
82 template<class Archive>
83 void serialize(Archive & ar, const unsigned int version)
85 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
86 ar & BOOST_SERIALIZATION_NVP(res);
94 testfunc_res(const string& str)
106 class testfunc_cmd : public libt2n::command
111 friend class boost::serialization::access;
112 template<class Archive>
113 void serialize(Archive & ar, const unsigned int version)
115 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
116 ar & BOOST_SERIALIZATION_NVP(param);
124 testfunc_cmd(const string& str)
129 libt2n::result* operator()()
131 return new testfunc_res(testfunc(param));
138 #include <boost/serialization/export.hpp>
140 BOOST_CLASS_EXPORT(reentrant::testfunc_cmd)
141 BOOST_CLASS_EXPORT(reentrant::testfunc_res)
143 using namespace reentrant;
145 BOOST_AUTO_TEST_SUITE(test_reentrant)
147 BOOST_AUTO_TEST_CASE(ReentrantServer)
153 BOOST_FAIL("fork error");
159 // wait till server is up
163 for (int i = 0; i < fork_count; i++)
168 for (int i=0; i < requests_per_child; i++)
170 socket_client_connection sc("./socket");
171 // sc.set_logging(&cerr,debug);
172 command_client cc(&sc);
175 cc.send_command(new testfunc_cmd("hello"),rc);
177 testfunc_res *res = dynamic_cast<testfunc_res*>(rc.get_result());
180 string ret = res->get_data();
181 if (ret != "hello, testfunc() was here")
182 std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n";
186 std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n";
189 } catch (exception &e)
191 cerr << "caught exception: " << e.what() << endl;
194 std::cerr << "exception in child. ignoring\n";
197 // don't call atexit and stuff
204 // don't kill us on broken pipe
205 signal(SIGPIPE, SIG_IGN);
207 socket_server ss("./socket");
208 command_server cs(ss);
212 // Wait until all requests have successed
213 int safety_check = 0;
214 while (seen_client_requests < all_requests)
217 if (safety_check > 10) {
218 std::cerr << "reached safety check, aborting.\n";
222 long long maxtime=1000000;
224 cs.handle(maxtime,&maxtime);
227 global_server = NULL;
230 // we are still alive, everything is ok
231 BOOST_CHECK_EQUAL(all_requests, seen_client_requests);
235 BOOST_AUTO_TEST_SUITE_END()