3 #include "ImR_Locator_i.h"
5 #include "orbsvcs/Log_Macros.h"
7 #include "tao/ORB_Core.h"
8 #include "ace/Reactor.h"
9 #include "ace/OS_NS_sys_time.h"
10 #include "ace/Timer_Queue.h"
11 #include "ace/Timer_Queue_Iterator.h"
13 LiveListener::LiveListener (const char *server
)
19 LiveListener::~LiveListener (void)
24 LiveListener::server (void) const
26 return this->server_
.c_str ();
30 LiveListener::_add_ref (void)
32 int const refcount
= ++this->refcount_
;
33 if (ImR_Locator_i::debug () > 5)
35 ORBSVCS_DEBUG ((LM_DEBUG
,
36 ACE_TEXT ("(%P|%t) LiveListener::add_ref <%C> count <%d>\n"),
37 server_
.c_str(), refcount
));
43 LiveListener::_remove_ref (void)
45 int const count
= --this->refcount_
;
46 if (ImR_Locator_i::debug () > 5)
48 ORBSVCS_DEBUG ((LM_DEBUG
,
49 ACE_TEXT ("(%P|%t) LiveListener::remove_ref <%C> count <%d>\n"),
50 server_
.c_str(), count
));
58 //---------------------------------------------------------------------------
59 //---------------------------------------------------------------------------
61 const int LiveEntry::reping_msec_
[] = {10, 100, 500, 1000, 1000, 2000, 2000, 5000, 5000};
62 int LiveEntry::reping_limit_
= sizeof (LiveEntry::reping_msec_
) / sizeof (int);
65 LiveEntry::status_name (LiveStatus s
)
81 case LS_LAST_TRANSIENT
:
82 return "LAST_TRANSIENT";
88 return "<undefined status>";
92 LiveEntry::set_reping_limit (int max
)
94 int array_max
= sizeof (LiveEntry::reping_msec_
) / sizeof (int);
95 LiveEntry::reping_limit_
= max
< array_max
&& max
>= 0 ? max
: array_max
;
99 LiveEntry::reping_available (void) const
101 return this->repings_
< this->max_retry_
;
105 LiveEntry::next_reping (void)
107 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
, mon
, this->lock_
, -1);
108 return this->reping_available() ? LiveEntry::reping_msec_
[this->repings_
++] : -1;
112 LiveEntry::max_retry_msec (int msec
)
114 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
115 for (this->max_retry_
= 0;
116 this->max_retry_
< LiveEntry::reping_limit_
&& msec
> 0;
119 msec
-= LiveEntry::reping_msec_
[this->repings_
];
123 LiveEntry::LiveEntry (LiveCheck
*owner
,
126 ImplementationRepository::ServerObject_ptr ref
,
130 ref_ (ImplementationRepository::ServerObject::_duplicate (ref
)),
131 liveliness_ (LS_INIT
),
132 next_check_ (ACE_OS::gettimeofday()),
134 max_retry_ (LiveEntry::reping_limit_
),
135 may_ping_ (may_ping
),
141 if (ImR_Locator_i::debug () > 4)
143 ORBSVCS_DEBUG ((LM_DEBUG
,
144 ACE_TEXT ("(%P|%t) LiveEntry::ctor server <%C> status <%C> may_ping <%d> pid <%d>\n"),
145 server
, status_name (this->liveliness_
), may_ping
, pid
));
149 LiveEntry::~LiveEntry (void)
151 if (this->callback_
.in () != 0)
153 PingReceiver
*rec
= dynamic_cast<PingReceiver
*>(this->callback_
.in());
162 LiveEntry::release_callback (void)
168 LiveEntry::add_listener (LiveListener
*ll
)
170 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
171 LiveListener_ptr
llp(ll
->_add_ref());
172 int const result
= this->listeners_
.insert (llp
);
173 if (ImR_Locator_i::debug() > 4)
175 ORBSVCS_DEBUG ((LM_DEBUG
,
176 ACE_TEXT ("(%P|%t) LiveEntry::add_listener server <%C> result <%d>\n"),
177 this->server_
.c_str(),
183 LiveEntry::remove_listener (LiveListener
*ll
)
185 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
186 LiveListener_ptr
llp(ll
->_add_ref());
187 int const result
= this->listeners_
.remove (llp
);
188 if (ImR_Locator_i::debug() > 4)
190 ORBSVCS_DEBUG ((LM_DEBUG
,
191 ACE_TEXT ("(%P|%t) LiveEntry::remove_listener server <%C> result <%d>\n"),
192 this->server_
.c_str(),
198 LiveEntry::reset_status (void)
200 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
201 if ( this->liveliness_
== LS_ALIVE
||
202 this->liveliness_
== LS_LAST_TRANSIENT
||
203 this->liveliness_
== LS_TIMEDOUT
)
205 this->liveliness_
= LS_UNKNOWN
;
207 this->next_check_
= ACE_OS::gettimeofday();
209 if (ImR_Locator_i::debug () > 2)
211 ORBSVCS_DEBUG ((LM_DEBUG
,
212 ACE_TEXT ("(%P|%t) LiveEntry::reset_status this <%x> ")
213 ACE_TEXT ("server <%C> status <%C>\n"),
214 this, this->server_
.c_str(),
215 status_name (this->liveliness_
)));
221 LiveEntry::status (void) const
223 if (!this->may_ping_
)
228 if (this->liveliness_
== LS_ALIVE
&&
229 this->owner_
->ping_interval() != ACE_Time_Value::zero
)
231 ACE_Time_Value
now (ACE_OS::gettimeofday());
232 if (now
>= this->next_check_
)
237 return this->liveliness_
;
241 LiveEntry::update_listeners (void)
244 for (Listen_Set::ITERATOR
i(this->listeners_
);
249 if ((*i
)->status_changed (this->liveliness_
))
255 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
256 for (Listen_Set::ITERATOR
i (remove
);
260 LiveListener_ptr
llp (*i
);
261 int const result
= this->listeners_
.remove (llp
);
266 LiveListener_ptr dummy
;
267 this->listeners_
.remove (dummy
);
272 LiveEntry::status (LiveStatus l
)
275 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
276 this->liveliness_
= l
;
279 ACE_Time_Value
now (ACE_OS::gettimeofday());
280 this->next_check_
= now
+ owner_
->ping_interval();
282 if (l
== LS_TRANSIENT
&& !this->reping_available())
284 this->liveliness_
= LS_LAST_TRANSIENT
;
287 this->update_listeners ();
289 if (!this->listeners_
.is_empty ())
291 if (ImR_Locator_i::debug () > 2)
293 ORBSVCS_DEBUG ((LM_DEBUG
,
294 ACE_TEXT ("(%P|%t) LiveEntry::status change, ")
295 ACE_TEXT ("server <%C> status <%C>\n"),
296 this->server_
.c_str(),
297 status_name (this->liveliness_
)));
299 this->owner_
->schedule_ping (this);
303 if (this->owner_
->remove_per_client_entry (this))
310 const ACE_Time_Value
&
311 LiveEntry::next_check (void) const
313 return this->next_check_
;
317 LiveEntry::server_name (void) const
319 return this->server_
.c_str();
323 LiveEntry::set_pid (int pid
)
329 LiveEntry::pid (void) const
335 LiveEntry::may_ping (void) const
337 return this->may_ping_
;
341 LiveEntry::has_pid (int pid
) const
343 return this->pid_
== 0 || pid
== 0 || pid
== this->pid_
;
347 LiveEntry::validate_ping (bool &want_reping
, ACE_Time_Value
& next
)
349 if (ImR_Locator_i::debug () > 4)
351 ORBSVCS_DEBUG ((LM_DEBUG
,
352 ACE_TEXT ("(%P|%t) LiveEntry::validate_ping, status ")
353 ACE_TEXT ("<%C> listeners <%d> server <%C> pid <%d> want_reping <%d> may_ping <%d>\n"),
354 status_name (this->liveliness_
), this->listeners_
.size (),
355 this->server_
.c_str(), this->pid_
, want_reping
, this->may_ping_
));
358 if (this->liveliness_
== LS_PING_AWAY
||
359 this->liveliness_
== LS_DEAD
||
360 this->listeners_
.is_empty ())
364 ACE_Time_Value
const now (ACE_OS::gettimeofday());
365 ACE_Time_Value
const diff
= this->next_check_
- now
;
366 long const msec
= diff
.msec();
369 if (!want_reping
|| this->next_check_
< next
)
372 next
= this->next_check_
;
374 if (ImR_Locator_i::debug () > 2)
376 ORBSVCS_DEBUG ((LM_DEBUG
,
377 ACE_TEXT ("(%P|%t) LiveEntry::validate_ping, ")
378 ACE_TEXT ("status <%C> listeners <%d> ")
379 ACE_TEXT ("msec <%d> server <%C> pid <%d>\n"),
380 status_name (this->liveliness_
), this->listeners_
.size (),
381 msec
, this->server_
.c_str(), this->pid_
));
385 switch (this->liveliness_
)
393 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
, mon
, this->lock_
, false);
394 this->next_check_
= now
+ owner_
->ping_interval();
398 case LS_LAST_TRANSIENT
:
400 int const ms
= this->next_reping ();
403 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
, mon
, this->lock_
, false);
404 if (this->liveliness_
== LS_LAST_TRANSIENT
)
406 this->liveliness_
= LS_TRANSIENT
;
408 ACE_Time_Value
const next (ms
/ 1000, (ms
% 1000) * 1000);
409 this->next_check_
= now
+ next
;
410 if (ImR_Locator_i::debug () > 4)
412 ORBSVCS_DEBUG ((LM_DEBUG
,
413 ACE_TEXT ("(%P|%t) LiveEntry::validate_ping, ")
414 ACE_TEXT ("transient, reping in <%d> ms, ")
415 ACE_TEXT ("server <%C> pid <%d>\n"),
416 ms
, this->server_
.c_str(), this->pid_
));
421 if (this->liveliness_
== LS_TRANSIENT
)
423 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX
, mon
, this->lock_
, false);
424 this->liveliness_
= LS_LAST_TRANSIENT
;
426 if (ImR_Locator_i::debug () > 2)
428 ORBSVCS_DEBUG ((LM_DEBUG
,
429 ACE_TEXT ("(%P|%t) LiveEntry::validate_ping, ")
430 ACE_TEXT ("transient, no more repings, ")
431 ACE_TEXT ("server <%C> pid <%d>\n"),
432 this->server_
.c_str(), this->pid_
));
434 if (!this->listeners_
.is_empty ())
436 this->update_listeners ();
448 LiveEntry::do_ping (PortableServer::POA_ptr poa
)
450 this->callback_
= new PingReceiver (this, poa
);
451 PortableServer::ObjectId_var oid
= poa
->activate_object (this->callback_
.in());
452 CORBA::Object_var obj
= poa
->id_to_reference (oid
.in());
453 ImplementationRepository::AMI_ServerObjectHandler_var cb
=
454 ImplementationRepository::AMI_ServerObjectHandler::_narrow (obj
.in());
456 ACE_GUARD (TAO_SYNCH_MUTEX
, mon
, this->lock_
);
457 this->liveliness_
= LS_PING_AWAY
;
461 if (ImR_Locator_i::debug () > 3)
463 ORBSVCS_DEBUG ((LM_DEBUG
,
464 ACE_TEXT ("(%P|%t) LiveEntry::do_ping, ")
465 ACE_TEXT ("starting sendc_ping for server <%C>\n"),
466 this->server_
.c_str()));
468 this->ref_
->sendc_ping (cb
.in());
469 if (ImR_Locator_i::debug () > 3)
471 ORBSVCS_DEBUG ((LM_DEBUG
,
472 ACE_TEXT ("(%P|%t) LiveEntry::do_ping, ")
473 ACE_TEXT ("sendc_ping for server <%C> returned OK\n"),
474 this->server_
.c_str()));
477 catch (const CORBA::Exception
&ex
)
479 if (ImR_Locator_i::debug () > 3)
481 ORBSVCS_DEBUG ((LM_DEBUG
,
482 ACE_TEXT ("(%P|%t) LiveEntry::do_ping, ")
483 ACE_TEXT ("sendc_ping for server <%C> threw <%C> marking as dead\n"),
484 this->server_
.c_str(), ex
._info ().c_str ()));
486 this->release_callback ();
487 this->status (LS_DEAD
);
491 //---------------------------------------------------------------------------
492 PingReceiver::PingReceiver (LiveEntry
*entry
, PortableServer::POA_ptr poa
)
493 :poa_ (PortableServer::POA::_duplicate(poa
)),
498 PingReceiver::~PingReceiver (void)
503 PingReceiver::cancel (void)
505 if (ImR_Locator_i::debug () > 4)
507 const char *server
= "not available";
508 if (this->entry_
!= 0)
510 server
= this->entry_
->server_name ();
512 ORBSVCS_DEBUG ((LM_DEBUG
,
513 ACE_TEXT ("(%P|%t) PingReceiver::cancel server <%C>\n"),
520 PortableServer::ObjectId_var oid
= this->poa_
->servant_to_id (this);
521 poa_
->deactivate_object (oid
.in());
523 catch (const CORBA::Exception
&ex
)
525 if (ImR_Locator_i::debug () > 4)
527 ORBSVCS_DEBUG ((LM_DEBUG
,
528 ACE_TEXT ("(%P|%t) PingReceiver::cancel caught <%C>\n"),
529 ex
._info ().c_str ()));
535 PingReceiver::ping (void)
537 if (this->entry_
!= 0)
539 if (ImR_Locator_i::debug () > 5)
541 ORBSVCS_DEBUG ((LM_DEBUG
,
542 ACE_TEXT ("(%P|%t) PingReceiver::ping received from <%C>\n"),
543 this->entry_
->server_name ()));
545 this->entry_
->release_callback ();
546 this->entry_
->status (LS_ALIVE
);
548 PortableServer::ObjectId_var oid
= this->poa_
->servant_to_id (this);
549 poa_
->deactivate_object (oid
.in());
553 PingReceiver::ping_excep (Messaging::ExceptionHolder
* excep_holder
)
555 const CORBA::ULong TAO_MINOR_MASK
= 0x00000f80;
558 if (ImR_Locator_i::debug () > 5)
560 ORBSVCS_DEBUG ((LM_DEBUG
,
561 ACE_TEXT ("(%P|%t) PingReceiver::ping_excep received from <%C>\n"),
562 this->entry_
->server_name ()));
564 excep_holder
->raise_exception ();
566 catch (const CORBA::TRANSIENT
&ex
)
568 switch (ex
.minor () & TAO_MINOR_MASK
)
570 case TAO_POA_DISCARDING
:
571 case TAO_POA_HOLDING
:
573 if (this->entry_
!= 0)
575 this->entry_
->release_callback ();
576 this->entry_
->status (LS_TRANSIENT
);
580 default: //case TAO_INVOCATION_SEND_REQUEST_MINOR_CODE:
582 if (this->entry_
!= 0)
584 this->entry_
->release_callback ();
585 this->entry_
->status (LS_DEAD
);
590 catch (const CORBA::TIMEOUT
&ex
)
592 if (this->entry_
!= 0)
594 this->entry_
->release_callback ();
595 if ((ex
.minor () & TAO_MINOR_MASK
) == TAO_TIMEOUT_CONNECT_MINOR_CODE
)
597 this->entry_
->status (LS_DEAD
);
601 this->entry_
->status (LS_TIMEDOUT
);
605 catch (const CORBA::Exception
&)
607 if (this->entry_
!= 0)
609 this->entry_
->release_callback ();
610 this->entry_
->status (LS_DEAD
);
614 PortableServer::ObjectId_var oid
= this->poa_
->servant_to_id (this);
615 poa_
->deactivate_object (oid
.in());
618 //---------------------------------------------------------------------------
619 //---------------------------------------------------------------------------
621 LC_TimeoutGuard::LC_TimeoutGuard (LiveCheck
*owner
, LC_token_type token
)
624 blocked_ (owner
->in_handle_timeout ())
626 if (ImR_Locator_i::debug () > 3)
628 ORBSVCS_DEBUG ((LM_DEBUG
,
629 ACE_TEXT ("(%P|%t) LC_TimeoutGuard(%d)::ctor, ")
630 ACE_TEXT ("blocked <%d>\n"),
631 this->token_
, this->blocked_
));
633 owner_
->enter_handle_timeout ();
636 LC_TimeoutGuard::~LC_TimeoutGuard (void)
638 owner_
->exit_handle_timeout ();
642 if (ImR_Locator_i::debug () > 3)
644 ORBSVCS_DEBUG ((LM_DEBUG
,
645 ACE_TEXT ("(%P|%t) LC_TimeoutGuard(%d)::dtor, ")
646 ACE_TEXT ("doing nothing because our owner is blocked\n"),
652 owner_
->remove_deferred_servers ();
654 if (owner_
->want_timeout_
)
656 ACE_Time_Value delay
= ACE_Time_Value::zero
;
657 if (owner_
->deferred_timeout_
!= ACE_Time_Value::zero
)
659 ACE_Time_Value
const now (ACE_OS::gettimeofday());
660 if (owner_
->deferred_timeout_
> now
)
661 delay
= owner_
->deferred_timeout_
- now
;
664 if (ImR_Locator_i::debug () > 2)
666 ORBSVCS_DEBUG ((LM_DEBUG
,
667 ACE_TEXT ("(%P|%t) LC_TimeoutGuard(%d)::dtor, ")
668 ACE_TEXT ("scheduling new timeout(%d), delay = %d,%d\n"),
669 this->token_
, owner_
->token_
, delay
.sec(), delay
.usec()));
671 owner_
->reactor()->schedule_timer (owner_
,
672 reinterpret_cast<void *>(owner_
->token_
),
674 owner_
->want_timeout_
= false;
678 if (ImR_Locator_i::debug () > 3)
680 ORBSVCS_DEBUG ((LM_DEBUG
,
681 ACE_TEXT ("(%P|%t) LC_TimeoutGuard(%d)::dtor, ")
682 ACE_TEXT ("no pending timeouts requested\n"),
688 bool LC_TimeoutGuard::blocked (void) const
690 return this->blocked_
;
693 //---------------------------------------------------------------------------
694 //---------------------------------------------------------------------------
696 LiveCheck::LiveCheck ()
700 handle_timeout_busy_ (0),
701 want_timeout_ (false),
702 deferred_timeout_ (ACE_Time_Value::zero
)
706 LiveCheck::~LiveCheck (void)
708 for (LiveEntryMap::iterator
em (this->entry_map_
); !em
.done(); em
++)
712 this->entry_map_
.unbind_all();
714 for (PerClientStack::iterator
pc (this->per_client_
); !pc
.done(); pc
++)
718 this->per_client_
.reset ();
719 this->removed_entries_
.reset ();
723 LiveCheck::enter_handle_timeout (void)
725 ++this->handle_timeout_busy_
;
729 LiveCheck::exit_handle_timeout (void)
731 --this->handle_timeout_busy_
;
735 LiveCheck::in_handle_timeout (void)
737 return this->handle_timeout_busy_
!= 0;
741 LiveCheck::init (CORBA::ORB_ptr orb
,
742 const ACE_Time_Value
&pi
)
744 this->ping_interval_
= pi
;
745 ACE_Reactor
*r
= orb
->orb_core()->reactor();
747 CORBA::Object_var obj
= orb
->resolve_initial_references ("RootPOA");
748 this->poa_
= PortableServer::POA::_narrow (obj
.in());
749 this->running_
= true;
753 LiveCheck::shutdown (void)
755 this->running_
= false;
756 this->reactor()->cancel_timer (this);
759 const ACE_Time_Value
&
760 LiveCheck::ping_interval (void) const
762 return this->ping_interval_
;
766 LiveCheck::handle_timeout (const ACE_Time_Value
&,
769 LC_token_type token
= reinterpret_cast<LC_token_type
>(tok
);
770 if (ImR_Locator_i::debug () > 2)
772 ORBSVCS_DEBUG ((LM_DEBUG
,
773 ACE_TEXT ("(%P|%t) LiveCheck::handle_timeout(%d), ")
774 ACE_TEXT ("running <%d>\n"),
775 token
, this->running_
));
780 LC_TimeoutGuard
tg (this, token
);
784 LiveEntryMap::iterator le_end
= this->entry_map_
.end();
785 for (LiveEntryMap::iterator le
= this->entry_map_
.begin();
789 LiveEntry
*entry
= le
->item ();
790 if (entry
->validate_ping (this->want_timeout_
, this->deferred_timeout_
))
792 entry
->do_ping (poa_
.in ());
793 if (ImR_Locator_i::debug () > 2)
795 ORBSVCS_DEBUG ((LM_DEBUG
,
796 ACE_TEXT ("(%P|%t) LiveCheck::handle_timeout(%d)")
797 ACE_TEXT (", ping sent to server <%C>\n"),
798 token
, entry
->server_name ()));
803 if (ImR_Locator_i::debug () > 4)
805 ORBSVCS_DEBUG ((LM_DEBUG
,
806 ACE_TEXT ("(%P|%t) LiveCheck::handle_timeout(%d)")
807 ACE_TEXT (", ping skipped for server <%C> may_ping <%d>\n"),
808 token
, entry
->server_name (), entry
->may_ping ()));
813 PerClientStack::iterator pe_end
= this->per_client_
.end();
814 for (PerClientStack::iterator pe
= this->per_client_
.begin();
818 LiveEntry
*entry
= *pe
;
821 if (entry
->validate_ping (this->want_timeout_
, this->deferred_timeout_
))
823 entry
->do_ping (poa_
.in ());
825 LiveStatus
const status
= entry
->status ();
826 if (status
!= LS_PING_AWAY
&& status
!= LS_TRANSIENT
)
828 this->per_client_
.remove (entry
);
838 LiveCheck::has_server (const char *server
)
840 ACE_CString
s (server
);
841 LiveEntry
*entry
= 0;
842 int const result
= entry_map_
.find (s
, entry
);
843 return (result
== 0 && entry
!= 0);
847 LiveCheck::add_server (const char *server
,
849 ImplementationRepository::ServerObject_ptr ref
,
852 if (ImR_Locator_i::debug () > 2)
854 ORBSVCS_DEBUG ((LM_DEBUG
,
855 ACE_TEXT ("(%P|%t) LiveCheck::add_server <%C> ")
856 ACE_TEXT ("may_ping <%d> running <%d> pid <%d>\n"),
857 server
, may_ping
, this->running_
, pid
));
863 ACE_CString
s (server
);
864 LiveEntry
*entry
= 0;
865 ACE_NEW (entry
, LiveEntry (this, server
, may_ping
, ref
, pid
));
866 int result
= entry_map_
.bind (s
, entry
);
870 result
= entry_map_
.rebind (s
, entry
, old
);
873 old
->status (LS_CANCELED
);
880 LiveCheck::set_pid (const char *server
, int pid
)
882 if (ImR_Locator_i::debug () > 0)
884 ORBSVCS_DEBUG ((LM_DEBUG
,
885 ACE_TEXT ("(%P|%t) LiveCheck::set_pid <%C> pid <%d>\n"),
888 ACE_CString
s(server
);
889 LiveEntry
*entry
= 0;
890 int const result
= entry_map_
.find (s
, entry
);
891 if (result
!= -1 && entry
!= 0)
893 entry
->set_pid (pid
);
897 if (ImR_Locator_i::debug () > 0)
899 ORBSVCS_DEBUG ((LM_DEBUG
,
900 ACE_TEXT ("(%P|%t) LiveCheck::set_pid <%C> pid <%d> cannot find entry\n"),
907 LiveCheck::remove_server (const char *server
, int pid
)
909 if (ImR_Locator_i::debug () > 0)
911 ORBSVCS_DEBUG ((LM_DEBUG
,
912 ACE_TEXT ("(%P|%t) LiveCheck::remove_server <%C> pid <%d>\n"),
915 ACE_CString
s(server
);
916 LiveEntry
*entry
= 0;
917 int const result
= entry_map_
.find (s
, entry
);
918 if (result
!= -1 && entry
!= 0 && entry
->has_pid (pid
))
920 if (!this->in_handle_timeout ())
922 if (ImR_Locator_i::debug () > 0)
924 ORBSVCS_DEBUG ((LM_DEBUG
,
925 ACE_TEXT ("(%P|%t) LiveCheck::remove_server removing <%C> pid <%d> entry pid <%d> status <%C>\n"),
926 server
, pid
, entry
->pid (), LiveEntry::status_name (entry
->status ())));
928 if (entry_map_
.unbind (s
, entry
) == 0)
935 // We got a request to remove the server but we are in handle timeout, so we have to postpone
936 // the remove. We do set the status to dead so that we make sure that we only remove later
937 // on the dead server and not a possible restart
938 entry
->status (LS_DEAD
);
940 if (ImR_Locator_i::debug () > 0)
942 ORBSVCS_DEBUG ((LM_DEBUG
,
943 ACE_TEXT ("(%P|%t) LiveCheck::remove_server <%C> pid <%d> entry pid <%d> status <%C> ")
944 ACE_TEXT ("called during handle_timeout\n"), server
, pid
, entry
->pid (), LiveEntry::status_name (entry
->status ())));
946 this->removed_entries_
.insert_tail (std::make_pair (s
, pid
));
951 if (ImR_Locator_i::debug () > 0)
955 ORBSVCS_DEBUG ((LM_DEBUG
,
956 ACE_TEXT ("(%P|%t) LiveCheck::remove_server <%C> ")
957 ACE_TEXT ("Can't find server entry, server probably already removed earlier\n"),
962 ORBSVCS_DEBUG ((LM_DEBUG
,
963 ACE_TEXT ("(%P|%t) LiveCheck::remove_server <%C> ")
964 ACE_TEXT ("pid <%d> does not match entry pid <%d>\n"),
965 server
, pid
, entry
->pid ()));
972 LiveCheck::remove_deferred_servers (void)
974 if (!this->removed_entries_
.is_empty ())
976 // When we are in handle_timeout we can't remove deferred servers
977 if (!this->in_handle_timeout ())
979 NamePidStack::iterator re_end
= this->removed_entries_
.end();
980 for (NamePidStack::iterator re
= this->removed_entries_
.begin();
984 NamePidPair
const & name_pid_pair
= (*re
);
985 if (ImR_Locator_i::debug () > 4)
987 ORBSVCS_DEBUG ((LM_DEBUG
,
988 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers ")
989 ACE_TEXT ("removing <%C> pid <%d>\n"),
990 name_pid_pair
.first
.c_str(), name_pid_pair
.second
));
992 // Now try to remove the server, we have to make sure
993 // that we only remove the server when the
994 // name and pid match. These could potentially not
995 // match when the server has already been restarted between the
996 // moment it got in the removed_entries_ stack and this point
997 // where we remove it from the internal administration
998 LiveEntry
*entry
= 0;
999 int const result
= entry_map_
.find (name_pid_pair
.first
, entry
);
1000 if (result
!= -1 && entry
!= 0)
1002 if (entry
->pid () == name_pid_pair
.second
)
1004 if (entry
->status () == LS_DEAD
)
1006 // We have a matched process id
1007 if (ImR_Locator_i::debug () > 4)
1009 ORBSVCS_DEBUG ((LM_DEBUG
,
1010 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers <%C> ")
1011 ACE_TEXT ("removing dead server using matched pid <%d>\n"),
1012 name_pid_pair
.first
.c_str(), name_pid_pair
.second
));
1014 if (entry_map_
.unbind (name_pid_pair
.first
, entry
) == 0)
1021 ORBSVCS_DEBUG ((LM_DEBUG
,
1022 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers <%C> ")
1023 ACE_TEXT ("matched pid <%d> but is not dead but <%C>\n"),
1024 name_pid_pair
.first
.c_str(), name_pid_pair
.second
, LiveEntry::status_name (entry
->status ())));
1029 ORBSVCS_DEBUG ((LM_DEBUG
,
1030 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers <%C> ")
1031 ACE_TEXT ("pid <%d> does not match entry pid <%d>\n"),
1032 name_pid_pair
.first
.c_str(), name_pid_pair
.second
, entry
->pid ()));
1037 if (ImR_Locator_i::debug () > 0)
1039 ORBSVCS_DEBUG ((LM_DEBUG
,
1040 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers <%C> ")
1041 ACE_TEXT ("Can't find server entry, server probably already removed earlier\n"),
1042 name_pid_pair
.first
.c_str()));
1046 this->removed_entries_
.reset ();
1050 if (ImR_Locator_i::debug () > 0)
1052 ORBSVCS_DEBUG ((LM_DEBUG
,
1053 ACE_TEXT ("(%P|%t) LiveCheck::remove_deferred_servers ")
1054 ACE_TEXT ("Can't remove <%d> servers because we are still in handle timeout\n"),
1055 this->removed_entries_
.size ()));
1062 LiveCheck::remove_per_client_entry (LiveEntry
*e
)
1064 return (this->per_client_
.remove (e
) == 0);
1068 LiveCheck::add_per_client_listener (LiveListener
*l
,
1069 ImplementationRepository::ServerObject_ptr ref
)
1071 if (!this->running_
)
1074 LiveEntry
*entry
= 0;
1075 ACE_NEW_RETURN (entry
, LiveEntry (this, l
->server (), true, ref
, 0), false);
1077 if (this->per_client_
.insert_tail(entry
) == 0)
1079 entry
->add_listener (l
);
1081 if (!this->in_handle_timeout ())
1084 this->reactor()->schedule_timer (this,
1085 reinterpret_cast<void *>(this->token_
),
1086 ACE_Time_Value::zero
);
1090 this->want_timeout_
= true;
1091 this->deferred_timeout_
= ACE_Time_Value::zero
;
1099 LiveCheck::add_poll_listener (LiveListener
*l
)
1101 if (!this->running_
)
1104 LiveEntry
*entry
= 0;
1105 ACE_CString
key (l
->server());
1106 int const result
= entry_map_
.find (key
, entry
);
1107 if (result
== -1 || entry
== 0)
1112 entry
->add_listener (l
);
1113 entry
->reset_status ();
1114 l
->status_changed (entry
->status());
1115 return this->schedule_ping (entry
);
1119 LiveCheck::add_listener (LiveListener
*l
)
1121 if (!this->running_
)
1124 LiveEntry
*entry
= 0;
1125 ACE_CString
key (l
->server());
1126 int const result
= entry_map_
.find (key
, entry
);
1127 if (result
== -1 || entry
== 0)
1132 entry
->add_listener (l
);
1133 return this->schedule_ping (entry
);
1137 LiveCheck::remove_listener (LiveListener
*l
)
1139 if (!this->running_
)
1142 LiveEntry
*entry
= 0;
1143 ACE_CString
key (l
->server());
1144 int const result
= entry_map_
.find (key
, entry
);
1145 if (result
!= -1 && entry
!= 0)
1147 entry
->remove_listener (l
);
1152 LiveCheck::schedule_ping (LiveEntry
*entry
)
1154 if (!this->running_
)
1157 LiveStatus
const status
= entry
->status();
1158 if (status
== LS_PING_AWAY
|| status
== LS_DEAD
)
1160 return status
!= LS_DEAD
;
1163 ACE_Time_Value
const now (ACE_OS::gettimeofday());
1164 ACE_Time_Value
const next
= entry
->next_check ();
1166 if (!this->in_handle_timeout ())
1168 ACE_Time_Value delay
= ACE_Time_Value::zero
;
1174 ACE_Timer_Queue
*tq
= this->reactor ()->timer_queue ();
1175 if (!tq
->is_empty ())
1177 for (ACE_Timer_Queue_Iterator_T
<ACE_Event_Handler
*> &i
= tq
->iter ();
1178 !i
.isdone (); i
.next())
1180 if (i
.item ()->get_type () == this)
1182 if (next
>= tq
->earliest_time ())
1184 if (ImR_Locator_i::debug () > 2)
1186 ORBSVCS_DEBUG ((LM_DEBUG
,
1187 ACE_TEXT ("(%P|%t) LiveCheck::schedule_ping ")
1188 ACE_TEXT ("already scheduled\n")));
1197 if (ImR_Locator_i::debug () > 2)
1199 ORBSVCS_DEBUG ((LM_DEBUG
,
1200 ACE_TEXT ("(%P|%t) LiveCheck::schedule_ping (%d),")
1201 ACE_TEXT (" delay <%d,%d>\n"),
1202 this->token_
, delay
.sec(), delay
.usec()));
1204 this->reactor()->schedule_timer (this,
1205 reinterpret_cast<void *>(this->token_
),
1210 if (ImR_Locator_i::debug () > 2)
1212 ORBSVCS_DEBUG ((LM_DEBUG
,
1213 ACE_TEXT ("(%P|%t) LiveCheck::schedule_ping deferred because we are in handle timeout\n")));
1215 if (!this->want_timeout_
|| next
< this->deferred_timeout_
)
1217 this->want_timeout_
= true;
1218 this->deferred_timeout_
= next
;
1225 LiveCheck::is_alive (const char *server
)
1227 if (!this->running_
)
1230 if (this->ping_interval_
== ACE_Time_Value::zero
)
1235 ACE_CString
s(server
);
1236 LiveEntry
*entry
= 0;
1237 int const result
= entry_map_
.find (s
, entry
);
1238 if (result
== 0 && entry
!= 0)
1240 return entry
->status ();