1 #include "ace/INet/ConnectionCache.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/ConnectionCache.inl"
7 #include "ace/INet/INet_Log.h"
10 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
16 ConnectionKey::ConnectionKey ()
19 ConnectionKey::~ConnectionKey ()
22 ConnectionCacheKey::ConnectionCacheKey ()
28 ConnectionCacheKey::ConnectionCacheKey (const ConnectionKey
& key
)
29 : key_ (&const_cast<ConnectionKey
&> (key
)),
34 ConnectionCacheKey::ConnectionCacheKey (const ConnectionCacheKey
& cachekey
)
41 ConnectionCacheKey::~ConnectionCacheKey ()
43 if (this->key_
!= 0 && this->delete_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_
)
57 this->delete_key_
= false;
60 this->key_
= cachekey
.key_
->duplicate ();
64 this->delete_key_
= false;
68 this->delete_key_
= true;
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 ()
91 ConnectionCacheValue::ConnectionCacheValue (connection_type
* connection
)
92 : state_ (connection
? CST_IDLE
: CST_INIT
),
93 connection_ (connection
)
97 ConnectionCacheValue::ConnectionCacheValue (const ConnectionCacheValue
& 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 ());
112 ConnectionCache::ConnectionCache(size_t size
)
113 : condition_ (lock_
),
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
),
134 bool ConnectionCache::set_connection (const ConnectionKey
& key
,
135 const ConnectionCacheValue
& cacheval
)
137 return this->cache_map_
.rebind (ConnectionCacheKey (key
),
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 ();
161 INET_ERROR (1, (LM_ERROR
, DLINFO
ACE_TEXT ("ConnectionCache::claim_existing_connection - ")
162 ACE_TEXT ("failed to claim connection entry")));
169 bool ConnectionCache::claim_connection(const ConnectionKey
& key
,
170 connection_type
*& connection
,
171 const factory_type
& connection_factory
,
174 INET_TRACE ("ConnectionCache::claim_connection");
178 bool create_connection
= false;
179 ConnectionCacheValue::State state
= ConnectionCacheValue::CST_NONE
;
182 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
,
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")));
194 if ((state
== ConnectionCacheValue::CST_BUSY
||
195 state
== ConnectionCacheValue::CST_INIT
) && !wait
)
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")));
208 create_connection
= true;
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")));
221 INET_DEBUG (9, (LM_INFO
, DLINFO
ACE_TEXT ("ConnectionCache::claim_connection - ")
222 ACE_TEXT ("awoken and retrying to claim connection\n")));
227 if (create_connection
)
229 connection
= connection_factory
.create_connection (key
);
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
,
240 ConnectionCacheValue
cacheval (connection
);
241 cacheval
.state (ConnectionCacheValue::CST_BUSY
);
242 return this->set_connection (key
, cacheval
);
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
,
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 ();
277 INET_ERROR (1, (LM_ERROR
, DLINFO
ACE_TEXT ("ConnectionCache::release_connection - ")
278 ACE_TEXT ("failed to release connection entry")));
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
,
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
316 INET_ERROR (1, (LM_ERROR
, DLINFO
ACE_TEXT ("ConnectionCache::close_connection - ")
317 ACE_TEXT ("failed to close connection entry")));
325 bool ConnectionCache::has_connection(const ConnectionKey
& key
)
327 INET_TRACE ("ConnectionCache::has_connection");
329 ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX
,
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
,
347 map_iter_type iter
= this->cache_map_
.end ();
348 for (iter
= this->cache_map_
.begin ();
349 iter
!= this->cache_map_
.end ();
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
);
360 this->cache_map_
.unbind_all ();
366 ACE_END_VERSIONED_NAMESPACE_DECL