1 /*------------------------------------------------------------------------------
2 Name: xmlBlaster/demo/c++/Leak.cpp
3 Project: xmlBlaster.org
4 Comment: Manually check for memory leaks (use for example valgrind to check)
5 Author: Marcel Ruff
6 ------------------------------------------------------------------------------*/
7 #include <client/XmlBlasterAccess.h>
8 #include <util/Global.h>
9 #include <vector>
10
11 using namespace std;
12 using namespace org::xmlBlaster::util;
13 using namespace org::xmlBlaster::util::qos;
14 using namespace org::xmlBlaster::util::dispatch;
15 using namespace org::xmlBlaster::client;
16 using namespace org::xmlBlaster::client::qos;
17 using namespace org::xmlBlaster::client::key;
18
19 class SpecificCallback : public I_Callback
20 {
21 private:
22 const string ME;
23 I_Log& log_;
24 public:
25 SpecificCallback(const GlobalRef global) : ME(global->getInstanceName()),
26 log_(global->getLog("Leak"))
27 {}
28
29 string update(const string& sessionId, UpdateKey& updateKey,
30 const unsigned char* content,
31 long contentSize, UpdateQos& updateQos)
32 {
33 string contentStr(reinterpret_cast<char *>(const_cast<unsigned char *>(content)), contentSize);
34 log_.info(ME, "Received update message with secret sessionId '" + sessionId + "':" +
35 updateKey.toXml() +
36 "\n content=" + contentStr +
37 updateQos.toXml());
38 return "";
39 }
40 };
41
42
43 class Leak
44 {
45 private:
46 string ME; /**< the string identifying this class when logging */
47 Global& global_; /**< The singleton Global instance, handled by Object_Lifetime_Manager */
48 I_Log& log_; /**< Logging output */
49 int count;
50 bool holdReferenceCount;
51
52 public:
53 Leak(Global& glob) : ME("Leak"), global_(glob),
54 log_(glob.getLog("Leak")),
55 count(5),
56 holdReferenceCount(false) {
57 count = global_.getProperty().get("count", count);
58 holdReferenceCount = global_.getProperty().get("holdReferenceCount", holdReferenceCount);
59 }
60
61 virtual ~Leak() {}
62
63 void checkGlobal()
64 {
65 log_.info(ME, "checkGlobal()");
66 try {
67 for (int i=0; i<count; i++) {
68 string instanceName = string("connection-") + lexical_cast<std::string>(i);
69 Property::MapType propMap;
70 GlobalRef globalRef = global_.createInstance(instanceName, &propMap, holdReferenceCount);
71 log_.info(ME, "Global created " + globalRef->getId());
72 if (holdReferenceCount)
73 global_.destroyInstance(instanceName);
74 }
75 }
76 catch (const XmlBlasterException &e) {
77 log_.error(ME, e.toXml());
78 }
79 }
80
81 void checkGlobal2()
82 {
83 log_.info(ME, "checkGlobal2()");
84 vector<GlobalRef> globVec; // Holding all connections to xmlBlaster
85 try {
86 for (int i=0; i<count; i++) {
87 string instanceName = string("connection-") + lexical_cast<std::string>(i);
88 Property::MapType propMap;
89 GlobalRef globalRef = global_.createInstance(instanceName, &propMap, holdReferenceCount);
90 globVec.push_back(globalRef);
91 log_.info(ME, "Global created " + globalRef->getId());
92 if (holdReferenceCount)
93 global_.destroyInstance(instanceName);
94 }
95 for (int i=0; i<count; i++) {
96 GlobalRef globalRef = globVec[i];
97 log_.info(ME, "Global destroy " + globalRef->getId());
98 if (holdReferenceCount)
99 global_.destroyInstance(globalRef->getInstanceName());
100 }
101 globVec.clear();
102 }
103 catch (const XmlBlasterException &e) {
104 log_.error(ME, e.toXml());
105 }
106 }
107
108 void checkConnection()
109 {
110 log_.info(ME, "checkConnection()");
111 try {
112 for (int i=0; i<count; i++) {
113 string instanceName = string("connection-") + lexical_cast<std::string>(i);
114 Property::MapType propMap;
115 GlobalRef globalRef = global_.createInstance(instanceName, &propMap);
116 XmlBlasterAccessRef con = XmlBlasterAccessRef(new XmlBlasterAccess(globalRef));
117 SpecificCallback* cbP = new SpecificCallback(globalRef);
118 ConnectQos qos(*globalRef);
119 ConnectReturnQos retQos = con->connect(qos, cbP);
120 log_.info(ME, "Successfully connected to xmlBlaster as " +
121 retQos.getSessionQos().getSessionName()->getAbsoluteName());
122 con->disconnect(DisconnectQos(con->getGlobal()));
123 delete con->getCallback(); // same as *cbP
124 }
125 }
126 catch (const XmlBlasterException &e) {
127 log_.error(ME, e.toXml());
128 }
129 }
130
131 // Using the pointers seems to leak memory -> this issue is not yet resolved!
132 void checkConnection2()
133 {
134 log_.info(ME, "checkConnection2()");
135 try {
136 XmlBlasterAccess** refs;
137 refs = new XmlBlasterAccess*[count];
138 for (int i=0; i<count; i++) {
139 string instanceName = string("connection2-") + lexical_cast<std::string>(i);
140 Property::MapType propMap;
141 GlobalRef globalRef = global_.createInstance(instanceName, &propMap);
142 XmlBlasterAccess* con = new XmlBlasterAccess(globalRef);
143 refs[i] = con;
144 SpecificCallback* cbP = new SpecificCallback(globalRef);
145 ConnectQos qos(*globalRef);
146 ConnectReturnQos retQos = con->connect(qos, cbP);
147 log_.info(ME, "Successfully connected to xmlBlaster as " +
148 retQos.getSessionQos().getSessionName()->getAbsoluteName());
149 }
150 for (int i=0; i<count; i++) {
151 XmlBlasterAccess* con = refs[i];
152 con->disconnect(DisconnectQos(con->getGlobal()));
153 delete con->getCallback(); // same as *cbP
154 delete con;
155 }
156 delete [] refs;
157 }
158 catch (const XmlBlasterException &e) {
159 log_.error(ME, e.toXml());
160 }
161 }
162
163 // Using the vector seems to leak memory -> this issue is not yet resolved!
164 void checkConnection3()
165 {
166 log_.info(ME, "checkConnection3()");
167 try {
168 vector<XmlBlasterAccessRef> connVec; // Holding all connections to xmlBlaster
169 for (int i=0; i<count; i++) {
170 string instanceName = string("connection2-") + lexical_cast<std::string>(i);
171 Property::MapType propMap;
172 GlobalRef globalRef = global_.createInstance(instanceName, &propMap);
173 XmlBlasterAccessRef con = XmlBlasterAccessRef(new XmlBlasterAccess(globalRef));
174 connVec.push_back(con);
175 SpecificCallback* cbP = new SpecificCallback(globalRef);
176 ConnectQos qos(*globalRef);
177 ConnectReturnQos retQos = con->connect(qos, cbP);
178 log_.info(ME, "Successfully connected to xmlBlaster as " +
179 retQos.getSessionQos().getSessionName()->getAbsoluteName());
180 }
181 for (int i=0; i<count; i++) {
182 XmlBlasterAccessRef con = connVec[i];
183 con->disconnect(DisconnectQos(con->getGlobal()));
184 delete con->getCallback(); // same as *cbP
185 }
186 connVec.erase(connVec.begin(), connVec.end());
187 }
188 catch (const XmlBlasterException &e) {
189 log_.error(ME, e.toXml());
190 }
191 }
192 };
193
194 #include <iostream>
195
196 /**
197 * Try
198 * <pre>
199 * Leak -help
200 * </pre>
201 * for usage help
202 */
203 int main(int args, char ** argv)
204 {
205 try {
206 org::xmlBlaster::util::Object_Lifetime_Manager::init();
207 Global& glob = Global::getInstance();
208 glob.initialize(args, argv);
209
210 string intro = "XmlBlaster C++ client " + glob.getReleaseId() +
211 ", try option '-help' if you need usage informations.";
212 glob.getLog().info("Leak", intro);
213
214 if (glob.wantsHelp()) {
215 cout << Global::usage() << endl;
216 cout << endl << "Leak";
217 cout << endl << " -sleep Sleep after publishing [1000 millisec]" << endl;
218 cout << endl << "Example:" << endl;
219 cout << endl << "Leak -trace true -sleep 2000";
220 cout << endl << "Leak -dispatch/connection/delay 10000 -sleep 2000000" << endl << endl;
221 org::xmlBlaster::util::Object_Lifetime_Manager::fini();
222 return 1;
223 }
224
225 Leak hello(glob);
226 if (glob.getProperty().get("global", false))
227 hello.checkGlobal();
228 if (glob.getProperty().get("global2", false))
229 hello.checkGlobal2();
230 if (glob.getProperty().get("con", false))
231 hello.checkConnection();
232 if (glob.getProperty().get("con2", false))
233 hello.checkConnection2();
234 if (glob.getProperty().get("con3", false))
235 hello.checkConnection3();
236 }
237 catch (XmlBlasterException &e) {
238 std::cerr << "Caught exception: " << e.getMessage() << std::endl;
239 }
240 catch (...) {
241 std::cerr << "Caught exception, exit" << std::endl;
242 }
243 org::xmlBlaster::util::Object_Lifetime_Manager::fini();
244 return 0;
245 }
syntax highlighted by Code2HTML, v. 0.9.1