Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Cached_Connect_Strategy_T.cpp
blobee11f25d8ae7c36f25f1eb0b96121e6bf6a4f53a
1 #ifndef ACE_CACHED_CONNECT_STRATEGY_T_CPP
2 #define ACE_CACHED_CONNECT_STRATEGY_T_CPP
4 #include "ace/Cached_Connect_Strategy_T.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 #pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #include "ace/ACE.h"
11 #include "ace/Service_Repository.h"
12 #include "ace/Service_Types.h"
13 #include "ace/Thread_Manager.h"
14 #include "ace/WFMO_Reactor.h"
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 ACE_ALLOC_HOOK_DEFINE_Tcoccc (ACE_Cached_Connect_Strategy_Ex)
19 ACE_ALLOC_HOOK_DEFINE_Tcoccc (ACE_Bounded_Cached_Connect_Strategy)
21 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX>
22 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::ACE_Cached_Connect_Strategy_Ex
23 (CACHING_STRATEGY &caching_s,
24 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
25 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
26 ACE_Recycling_Strategy<SVC_HANDLER> *rec_s,
27 MUTEX *lock,
28 int delete_lock)
29 : CCSBASE (cre_s, con_s, rec_s, lock, delete_lock),
30 connection_cache_ (caching_s)
32 if (this->open (cre_s, con_s, rec_s) == -1)
33 ACELIB_ERROR ((LM_ERROR,
34 ACE_TEXT ("%p\n"),
35 ACE_TEXT ("ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>\n")));
38 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX>
39 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::~ACE_Cached_Connect_Strategy_Ex ()
41 cleanup ();
45 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
46 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::check_hint_i
47 (SVC_HANDLER *&sh,
48 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
49 ACE_Time_Value *timeout,
50 const ACE_PEER_CONNECTOR_ADDR &local_addr,
51 bool reuse_addr,
52 int flags,
53 int perms,
54 ACE_Hash_Map_Entry<ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR>, std::pair<SVC_HANDLER *, ATTRIBUTES> > *&entry,
55 int &found)
57 ACE_UNUSED_ARG (remote_addr);
58 ACE_UNUSED_ARG (timeout);
59 ACE_UNUSED_ARG (local_addr);
60 ACE_UNUSED_ARG (reuse_addr);
61 ACE_UNUSED_ARG (flags);
62 ACE_UNUSED_ARG (perms);
64 found = 0;
66 // Get the recycling act for the svc_handler
67 CONNECTION_CACHE_ENTRY *possible_entry =
68 (CONNECTION_CACHE_ENTRY *) sh->recycling_act ();
70 // Check to see if the hint svc_handler has been closed down
71 if (possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED)
73 // If close, decrement refcount
74 if (possible_entry->ext_id_.decrement () == 0)
76 // If refcount goes to zero, close down the svc_handler
77 possible_entry->int_id_.first->recycler (0, 0);
78 possible_entry->int_id_.first->close ();
79 this->purge_i (possible_entry);
82 // Hint not successful
83 found = 0;
85 // Reset hint
86 sh = 0;
89 // If hint is not closed, see if it is connected to the correct
90 // address and is recyclable
91 else if ((possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_AND_PURGABLE ||
92 possible_entry->ext_id_.recycle_state () == ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE) &&
93 possible_entry->ext_id_.subject () == remote_addr)
95 // Hint successful
96 found = 1;
98 // Tell the <svc_handler> that it should prepare itself for
99 // being recycled.
100 this->prepare_for_recycling (sh);
103 // Update the caching attributes directly since we don't do a
104 // find() on the cache map.
107 // Indicates successful find.
108 int find_result = 0;
110 int result = this->caching_strategy ().notify_find (find_result,
111 possible_entry->int_id_.second);
113 if (result == -1)
114 return result;
116 else
118 // This hint will not be used.
119 possible_entry->ext_id_.decrement ();
121 // Hint not successful
122 found = 0;
124 // If <sh> is not connected to the correct address or is busy,
125 // we will not use it.
126 sh = 0;
129 if (found)
130 entry = possible_entry;
132 return 0;
135 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
136 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::find_or_create_svc_handler_i
137 (SVC_HANDLER *&sh,
138 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
139 ACE_Time_Value *timeout,
140 const ACE_PEER_CONNECTOR_ADDR &local_addr,
141 bool reuse_addr,
142 int flags,
143 int perms,
144 ACE_Hash_Map_Entry<ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR>, std::pair<SVC_HANDLER *, ATTRIBUTES> > *&entry,
145 int &found)
147 REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr);
149 // Try to find the address in the cache. Only if we don't find it
150 // do we create a new <SVC_HANDLER> and connect it with the server.
151 while (this->find (search_addr, entry) != -1)
153 // We found a cached svc_handler.
154 // Get the cached <svc_handler>
155 sh = entry->int_id_.first;
157 // Is the connection clean?
158 int const state_result =
159 ACE::handle_ready (sh->peer ().get_handle (),
160 &ACE_Time_Value::zero,
161 true, // read ready
162 false, // write ready
163 true);// exception ready
165 if (state_result == 1)
167 if (sh->close () == -1)
168 return -1;
170 sh = 0;
172 // Cycle it once again..
174 else if ((state_result == -1) && (errno == ETIME))
176 // Found!!!
177 // Set the flag
178 found = 1;
180 // Tell the <svc_handler> that it should prepare itself for
181 // being recycled.
182 if (this->prepare_for_recycling (sh) == -1)
183 return -1;
185 return 0;
187 else
189 return -1;
193 // Not found...
195 // Set the flag
196 found = 0;
198 // We need to use a temporary variable here since we are not
199 // allowed to change <sh> because other threads may use this
200 // when we let go of the lock during the OS level connect.
202 // Note that making a new svc_handler, connecting remotely,
203 // binding to the map, and assigning of the hint and recycler
204 // should be atomic to the outside world.
205 SVC_HANDLER *potential_handler = 0;
207 // Create a new svc_handler
208 if (this->make_svc_handler (potential_handler) == -1)
209 return -1;
211 // Connect using the svc_handler.
212 if (this->cached_connect (potential_handler,
213 remote_addr,
214 timeout,
215 local_addr,
216 reuse_addr,
217 flags,
218 perms) == -1)
220 // Close the svc handler.
221 potential_handler->close (0);
223 return -1;
225 else
227 // Insert the new SVC_HANDLER instance into the cache.
228 if (this->connection_cache_.bind (search_addr,
229 potential_handler,
230 entry) == -1)
232 // Close the svc handler and reset <sh>.
233 potential_handler->close (0);
235 return -1;
238 // Everything succeeded as planned. Assign <sh> to
239 // <potential_handler>.
240 sh = potential_handler;
242 // Set the recycler and the recycling act
244 this->assign_recycler (sh, this, entry);
247 return 0;
250 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
251 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::cached_connect (SVC_HANDLER *&sh,
252 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
253 ACE_Time_Value *timeout,
254 const ACE_PEER_CONNECTOR_ADDR &local_addr,
255 bool reuse_addr,
256 int flags,
257 int perms)
259 // Actively establish the connection. This is a timed blocking
260 // connect.
261 if (this->new_connection (sh,
262 remote_addr,
263 timeout,
264 local_addr,
265 reuse_addr,
266 flags,
267 perms) == -1)
269 // If connect() failed because of timeouts, we have to reject
270 // the connection entirely. This is necessary since currently
271 // there is no way for the non-blocking connects to complete and
272 // for the <Connector> to notify the cache of the completion of
273 // connect().
275 if (errno == EWOULDBLOCK || errno == ETIMEDOUT)
276 errno = ENOTSUP;
277 else if (ACE::out_of_handles (errno) || errno == EADDRINUSE)
279 // If the connect failed due to the process running out of
280 // file descriptors then, auto_purging of some connections
281 // are done from the CONNECTION_CACHE. This frees the
282 // descriptors which get used in the connect process and
283 // hence the same method is called again!
284 if (this->purge_connections () == -1)
285 return -1;
287 // Try connecting again.
288 if (this->new_connection (sh,
289 remote_addr,
290 timeout,
291 local_addr,
292 reuse_addr,
293 flags,
294 perms) == -1)
296 if (errno == EWOULDBLOCK || errno == ETIMEDOUT)
297 errno = ENOTSUP;
298 return -1;
301 else
303 return -1;
307 return 0;
311 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
312 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::connect_svc_handler_i
313 (SVC_HANDLER *&sh,
314 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
315 ACE_Time_Value *timeout,
316 const ACE_PEER_CONNECTOR_ADDR &local_addr,
317 bool reuse_addr,
318 int flags,
319 int perms,
320 int& found)
322 CONNECTION_CACHE_ENTRY *entry = 0;
324 // Check if the user passed a hint svc_handler
325 if (sh != 0)
327 int result = this->check_hint_i (sh,
328 remote_addr,
329 timeout,
330 local_addr,
331 reuse_addr,
332 flags,
333 perms,
334 entry,
335 found);
336 if (result != 0)
337 return result;
340 // If not found
341 if (!found)
343 int result = this->find_or_create_svc_handler_i (sh,
344 remote_addr,
345 timeout,
346 local_addr,
347 reuse_addr,
348 flags,
349 perms,
350 entry,
351 found);
353 if (result != 0)
354 return result;
356 // Increment the refcount
357 entry->ext_id_.increment ();
360 if (entry)
362 // For all successful cases: mark the <svc_handler> in the cache
363 // as being <in_use>. Therefore recyclable is BUSY.
364 entry->ext_id_.recycle_state (ACE_RECYCLABLE_BUSY);
367 return 0;
371 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
372 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::cache_i (const void *recycling_act)
374 // The wonders and perils of ACT
375 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
377 // Mark the <svc_handler> in the cache as not being <in_use>.
378 // Therefore recyclable is IDLE.
379 entry->ext_id_.recycle_state (ACE_RECYCLABLE_IDLE_AND_PURGABLE);
381 return 0;
384 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
385 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::recycle_state_i (const void *recycling_act,
386 ACE_Recyclable_State new_state)
388 // The wonders and perils of ACT
389 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
391 // Mark the <svc_handler> in the cache as not being <in_use>.
392 // Therefore recyclable is IDLE.
393 entry->ext_id_.recycle_state (new_state);
395 return 0;
398 template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> ACE_Recyclable_State
399 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::recycle_state_i (const void *recycling_act) const
401 // The wonders and perils of ACT
402 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
404 // Mark the <svc_handler> in the cache as not being <in_use>.
405 // Therefore recyclable is IDLE.
406 return entry->ext_id_.recycle_state ();
409 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
410 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::purge_i (const void *recycling_act)
412 // The wonders and perils of ACT
413 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
415 return this->connection_cache_.unbind (entry);
419 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
420 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::mark_as_closed_i (const void *recycling_act)
422 // The wonders and perils of ACT
423 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
425 // Mark the <svc_handler> in the cache as CLOSED.
426 entry->ext_id_.recycle_state (ACE_RECYCLABLE_CLOSED);
428 return 0;
431 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
432 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::cleanup_hint_i (const void *recycling_act,
433 void **act_holder)
435 // Reset the <*act_holder> in the confines and protection of the
436 // lock.
437 if (act_holder)
438 *act_holder = 0;
440 // The wonders and perils of ACT
441 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *) recycling_act;
443 // Decrement the refcount on the <svc_handler>.
444 int refcount = entry->ext_id_.decrement ();
446 // If the svc_handler state is closed and the refcount == 0, call
447 // close() on svc_handler.
448 if (entry->ext_id_.recycle_state () == ACE_RECYCLABLE_CLOSED &&
449 refcount == 0)
451 entry->int_id_.first->recycler (0, 0);
452 entry->int_id_.first->close ();
453 this->purge_i (entry);
456 return 0;
459 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
460 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::purge_connections ()
462 return this->connection_cache_.purge ();
465 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> CACHING_STRATEGY &
466 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::caching_strategy ()
468 return this->connection_cache_.caching_strategy ();
471 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> int
472 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::find (ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR> &search_addr,
473 ACE_Hash_Map_Entry<ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR>, std::pair<SVC_HANDLER *, ATTRIBUTES> > *&entry)
475 typedef ACE_Hash_Map_Bucket_Iterator<REFCOUNTED_HASH_RECYCLABLE_ADDRESS,
476 std::pair<SVC_HANDLER *, ATTRIBUTES>,
477 ACE_Hash<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>,
478 ACE_Equal_To<REFCOUNTED_HASH_RECYCLABLE_ADDRESS>,
479 ACE_Null_Mutex>
480 CONNECTION_CACHE_BUCKET_ITERATOR;
482 CONNECTION_CACHE_BUCKET_ITERATOR iterator (this->connection_cache_.map (),
483 search_addr);
485 CONNECTION_CACHE_BUCKET_ITERATOR end (this->connection_cache_.map (),
486 search_addr,
489 for (;
490 iterator != end;
491 ++iterator)
493 REFCOUNTED_HASH_RECYCLABLE_ADDRESS &addr = (*iterator).ext_id_;
495 if (addr.recycle_state () != ACE_RECYCLABLE_IDLE_AND_PURGABLE &&
496 addr.recycle_state () != ACE_RECYCLABLE_IDLE_BUT_NOT_PURGABLE)
497 continue;
499 if (addr.subject () != search_addr.subject ())
500 continue;
502 entry = &(*iterator);
505 // Update the caching attributes directly since we don't do a
506 // find() on the cache map.
509 // Indicates successful find.
510 int find_result = 0;
512 int result = this->caching_strategy ().notify_find (find_result,
513 entry->int_id_.second);
515 if (result == -1)
516 return result;
518 return 0;
521 return -1;
524 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX> void
525 ACE_Cached_Connect_Strategy_Ex<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::cleanup ()
527 // Excluded other threads from changing the cache while we cleanup
528 ACE_GUARD (MUTEX, ace_mon, *this->lock_);
530 // Close down all cached service handlers.
531 typename CONNECTION_CACHE::ITERATOR iter = this->connection_cache_.begin ();
532 while (iter != this->connection_cache_.end ())
534 if ((*iter).second () != 0)
536 // save entry for future use
537 CONNECTION_CACHE_ENTRY *entry = (CONNECTION_CACHE_ENTRY *)
538 (*iter).second ()->recycling_act ();
540 // close handler
541 (*iter).second ()->recycler (0, 0);
542 (*iter).second ()->close ();
544 // remember next iter
545 typename CONNECTION_CACHE::ITERATOR next_iter = iter;
546 ++next_iter;
548 // purge the item from the hash
549 this->purge_i (entry);
551 // assign next iter
552 iter = next_iter;
554 else
555 ++iter;
559 /////////////////////////////////////////////////////////////////////////
561 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX>
562 ACE_Bounded_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::ACE_Bounded_Cached_Connect_Strategy
563 (size_t max_size,
564 CACHING_STRATEGY &caching_s,
565 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
566 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
567 ACE_Recycling_Strategy<SVC_HANDLER> *rec_s,
568 MUTEX *lock,
569 int delete_lock)
570 : CCSEBASE (caching_s, cre_s, con_s, rec_s, lock, delete_lock),
571 max_size_ (max_size)
575 template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1, class CACHING_STRATEGY, class ATTRIBUTES, class MUTEX>
577 ACE_Bounded_Cached_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2, CACHING_STRATEGY, ATTRIBUTES, MUTEX>::find_or_create_svc_handler_i
578 (SVC_HANDLER *&sh,
579 const ACE_PEER_CONNECTOR_ADDR &remote_addr,
580 ACE_Time_Value *timeout,
581 const ACE_PEER_CONNECTOR_ADDR &local_addr,
582 bool reuse_addr,
583 int flags,
584 int perms,
585 ACE_Hash_Map_Entry<ACE_Refcounted_Hash_Recyclable<ACE_PEER_CONNECTOR_ADDR>,
586 std::pair<SVC_HANDLER *, ATTRIBUTES> > *&entry,
587 int &found)
589 REFCOUNTED_HASH_RECYCLABLE_ADDRESS search_addr (remote_addr);
591 // Try to find the address in the cache. Only if we don't find it
592 // do we create a new <SVC_HANDLER> and connect it with the server.
593 while (this->find (search_addr, entry) != -1)
595 // We found a cached svc_handler.
596 // Get the cached <svc_handler>
597 sh = entry->int_id_.first ();
599 // Is the connection clean?
600 int state_result= ACE::handle_ready (sh->peer ().get_handle (),
601 &ACE_Time_Value::zero,
602 true, // read ready
603 false, // write ready
604 true);// exception ready
606 if (state_result == 1)
608 // The connection was disconnected during idle.
609 // close the svc_handler down.
610 if (sh->close () == -1)
612 ACE_ASSERT (0);
613 return -1;
615 sh = 0;
616 // and rotate once more...
618 else if ((state_result == -1) && (errno == ETIME))
620 // Found!!!
621 // Set the flag
622 found = 1;
624 // Tell the <svc_handler> that it should prepare itself for
625 // being recycled.
626 if (this->prepare_for_recycling (sh) == -1)
628 ACE_ASSERT (0);
629 return -1;
632 return 0;
634 else // some other return value or error...
636 ACE_ASSERT (0); // just to see it coming
638 ACELIB_ERROR ((LM_ERROR,
639 ACE_TEXT ("(%t)ACE_Bounded_Cached_Connect_Strategy<>::")
640 ACE_TEXT ("find_or_create_svc_handler_i - ")
641 ACE_TEXT ("error polling server socket state.\n")));
643 return -1;
647 // Not found...
649 // Set the flag
650 found = 0;
652 // Check the limit of handlers...
653 if ((this->max_size_ > 0) &&
654 (this->connection_cache_.current_size () >= this->max_size_))
656 // Try to purge idle connections
657 if (this->purge_connections () == -1)
658 return -1;
660 // Check limit again.
661 if (this->connection_cache_.current_size () >= this->max_size_)
662 // still too much!
663 return -1;
665 // OK, we have room now...
668 // We need to use a temporary variable here since we are not
669 // allowed to change <sh> because other threads may use this
670 // when we let go of the lock during the OS level connect.
672 // Note that making a new svc_handler, connecting remotely,
673 // binding to the map, and assigning of the hint and recycler
674 // should be atomic to the outside world.
675 SVC_HANDLER *potential_handler = 0;
677 // Create a new svc_handler
678 if (this->make_svc_handler (potential_handler) == -1)
679 return -1;
681 // Connect using the svc_handler.
682 if (this->cached_connect (potential_handler,
683 remote_addr,
684 timeout,
685 local_addr,
686 reuse_addr,
687 flags,
688 perms) == -1)
690 // Close the svc handler.
691 potential_handler->close (0);
692 return -1;
694 else
696 // Insert the new SVC_HANDLER instance into the cache.
697 if (this->connection_cache_.bind (search_addr,
698 potential_handler,
699 entry) == -1)
701 // Close the svc handler and reset <sh>.
702 potential_handler->close (0);
704 return -1;
707 // Everything succeeded as planned. Assign <sh> to
708 // <potential_handler>.
709 sh = potential_handler;
711 // Set the recycler and the recycling act
712 this->assign_recycler (sh, this, entry);
715 return 0;
718 ACE_END_VERSIONED_NAMESPACE_DECL
720 #endif /* ACE_CACHED_CONNECT_STRATEGY_T_CPP */