Use a variable on the stack to not have a temporary in the call
[ACE_TAO.git] / ACE / protocols / ace / INet / ConnectionCache.cpp
blob703b06be77e7326960331649b33b9ee73ae1cf89
1 #include "ace/INet/ConnectionCache.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/ConnectionCache.inl"
5 #endif
7 #include "ace/INet/INet_Log.h"
10 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
12 namespace ACE
14 namespace INet
16 ConnectionKey::ConnectionKey ()
19 ConnectionKey::~ConnectionKey ()
22 ConnectionCacheKey::ConnectionCacheKey ()
23 : key_ (0),
24 delete_key_ (false)
28 ConnectionCacheKey::ConnectionCacheKey (const ConnectionKey& key)
29 : key_ (&const_cast<ConnectionKey&> (key)),
30 delete_key_ (false)
34 ConnectionCacheKey::ConnectionCacheKey (const ConnectionCacheKey& cachekey)
35 : key_ (0),
36 delete_key_ (false)
38 *this = cachekey;
41 ConnectionCacheKey::~ConnectionCacheKey ()
43 if (this->key_ != 0 && this->delete_key_)
45 delete this->key_;
46 this->delete_key_ = false;
50 ConnectionCacheKey& ConnectionCacheKey::operator =(const ConnectionCacheKey& cachekey)
52 if (this != &cachekey)
54 if (this->key_ != 0 && this->delete_key_)
56 delete this->key_;
57 this->delete_key_ = false;
60 this->key_ = cachekey.key_->duplicate ();
62 if (this->key_ == 0)
64 this->delete_key_ = false;
66 else
68 this->delete_key_ = true;
71 return *this;
74 u_long ConnectionCacheKey::hash () const
76 return this->key_ ? this->key ().hash () : 0;
79 ConnectionHolder::~ConnectionHolder () {}
80 ConnectionHolder::ConnectionHolder () {}
82 ConnectionFactory::~ConnectionFactory () {}
83 ConnectionFactory::ConnectionFactory () {}
85 ConnectionCacheValue::ConnectionCacheValue ()
86 : state_ (CST_INIT),
87 connection_ (0)
91 ConnectionCacheValue::ConnectionCacheValue (connection_type* connection)
92 : state_ (connection ? CST_IDLE : CST_INIT),
93 connection_ (connection)
97 ConnectionCacheValue::ConnectionCacheValue (const ConnectionCacheValue& cacheval)
99 *this = cacheval;
102 ConnectionCacheValue& ConnectionCacheValue::operator =(const ConnectionCacheValue& cacheval)
104 if (this != &cacheval)
106 this->state_ = cacheval.state ();
107 this->connection_ = const_cast<connection_type*> (cacheval.connection ());
109 return *this;
112 ConnectionCache::ConnectionCache(size_t size)
113 : condition_ (lock_),
114 cache_map_ (size)
118 ConnectionCache::~ConnectionCache ()
120 this->close_all_connections ();
123 bool ConnectionCache::find_connection (const ConnectionKey& key,
124 ConnectionCacheValue& cacheval)
126 if (this->cache_map_.find (ConnectionCacheKey (key),
127 cacheval) == 0)
129 return true;
131 return false;
134 bool ConnectionCache::set_connection (const ConnectionKey& key,
135 const ConnectionCacheValue& cacheval)
137 return this->cache_map_.rebind (ConnectionCacheKey (key),
138 cacheval) != -1;
141 bool ConnectionCache::claim_existing_connection(const ConnectionKey& key,
142 connection_type*& connection,
143 ConnectionCacheValue::State& state)
145 INET_TRACE ("ConnectionCache::claim_existing_connection");
147 ConnectionCacheValue cacheval;
148 if (this->find_connection (key, cacheval))
150 state = cacheval.state ();
151 if (state == ConnectionCacheValue::CST_IDLE)
153 cacheval.state (ConnectionCacheValue::CST_BUSY);
154 if (this->set_connection (key, cacheval))
156 connection = cacheval.connection ();
157 return true;
159 else
161 INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_existing_connection - ")
162 ACE_TEXT ("failed to claim connection entry")));
166 return false;
169 bool ConnectionCache::claim_connection(const ConnectionKey& key,
170 connection_type*& connection,
171 const factory_type& connection_factory,
172 bool wait)
174 INET_TRACE ("ConnectionCache::claim_connection");
176 while (1)
178 bool create_connection = false;
179 ConnectionCacheValue::State state = ConnectionCacheValue::CST_NONE;
182 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
183 guard_,
184 this->lock_,
185 false));
187 if (this->claim_existing_connection (key, connection, state))
189 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("%P|%t) ConnectionCache::claim_connection - ")
190 ACE_TEXT ("successfully claimed existing connection\n")));
191 return true;
194 if ((state == ConnectionCacheValue::CST_BUSY ||
195 state == ConnectionCacheValue::CST_INIT) && !wait)
196 return false;
198 if (state == ConnectionCacheValue::CST_CLOSED ||
199 state == ConnectionCacheValue::CST_NONE)
201 if (!this->set_connection (key, ConnectionCacheValue ()))
203 INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
204 ACE_TEXT ("failed to initialize connection entry")));
205 return false;
208 create_connection = true;
210 else
212 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
213 ACE_TEXT ("waiting for connection to become available\n")));
214 // wait for connection to become ready/free
215 if (this->condition_.wait () != 0)
217 INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("(%P|%t) ConnectionCache::claim_connection - ")
218 ACE_TEXT ("error waiting for connection condition (%p)\n")));
219 return false;
221 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
222 ACE_TEXT ("awoken and retrying to claim connection\n")));
225 while (0);
227 if (create_connection)
229 connection = connection_factory.create_connection (key);
230 if (connection)
232 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::claim_connection - ")
233 ACE_TEXT ("successfully created new connection\n")));
235 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
236 guard_,
237 this->lock_,
238 false));
240 ConnectionCacheValue cacheval (connection);
241 cacheval.state (ConnectionCacheValue::CST_BUSY);
242 return this->set_connection (key, cacheval);
244 else
245 return false;
250 bool ConnectionCache::release_connection(const ConnectionKey& key,
251 connection_type* connection)
253 INET_TRACE ("ConnectionCache::release_connection");
255 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
256 ACE_TEXT ("releasing connection\n")));
258 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
259 guard_,
260 this->lock_,
261 false));
263 ConnectionCacheValue cacheval;
264 if (this->find_connection (key, cacheval) &&
265 cacheval.connection () == connection &&
266 cacheval.state () == ConnectionCacheValue::CST_BUSY)
268 cacheval.state (ConnectionCacheValue::CST_IDLE);
269 if (this->set_connection (key, cacheval))
271 // signal other threads about free connection
272 this->condition_.broadcast ();
273 return true;
275 else
277 INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::release_connection - ")
278 ACE_TEXT ("failed to release connection entry")));
279 return false;
282 else
283 return false;
286 bool ConnectionCache::close_connection(const ConnectionKey& key,
287 connection_type* connection)
289 INET_TRACE ("ConnectionCache::close_connection");
291 INET_DEBUG (9, (LM_INFO, DLINFO ACE_TEXT ("ConnectionCache::close_connection - ")
292 ACE_TEXT ("closing connection\n")));
294 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
295 guard_,
296 this->lock_,
297 false));
299 ConnectionCacheValue cacheval;
300 if (this->find_connection (key, cacheval) &&
301 cacheval.connection () == connection &&
302 cacheval.state () == ConnectionCacheValue::CST_BUSY)
304 connection_type* conn = cacheval.connection ();
305 cacheval.connection (0);
306 cacheval.state (ConnectionCacheValue::CST_CLOSED);
307 if (this->set_connection (key, cacheval))
309 // signal other threads about closed connection
310 this->condition_.broadcast ();
311 delete conn; // clean up
312 return true;
314 else
316 INET_ERROR (1, (LM_ERROR, DLINFO ACE_TEXT ("ConnectionCache::close_connection - ")
317 ACE_TEXT ("failed to close connection entry")));
318 return false;
321 else
322 return false;
325 bool ConnectionCache::has_connection(const ConnectionKey& key)
327 INET_TRACE ("ConnectionCache::has_connection");
329 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX,
330 guard_,
331 this->lock_,
332 false));
334 ConnectionCacheValue cacheval;
335 return (this->find_connection (key, cacheval) &&
336 cacheval.state () != ConnectionCacheValue::CST_CLOSED);
339 void ConnectionCache::close_all_connections()
341 INET_TRACE ("ConnectionCache::close_all_connections");
343 ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX,
344 guard_,
345 this->lock_));
347 map_iter_type iter = this->cache_map_.end ();
348 for (iter = this->cache_map_.begin ();
349 iter != this->cache_map_.end ();
350 ++iter)
352 if ((*iter).int_id_.state () != ConnectionCacheValue::CST_CLOSED)
354 connection_type* conn = (*iter).int_id_.connection ();
355 (*iter).int_id_.connection (0);
356 (*iter).int_id_.state (ConnectionCacheValue::CST_CLOSED);
357 delete conn;
360 this->cache_map_.unbind_all ();
366 ACE_END_VERSIONED_NAMESPACE_DECL