Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / orbsvcs / ImplRepo_Service / AsyncAccessManager.cpp
blob513f5d2e2deba1f7f7945d0b5648d62a8d6f9869
1 // -*- C++ -*-
2 #include "AsyncAccessManager.h"
3 #include "ImR_Locator_i.h"
4 #include "Locator_Repository.h"
5 #include "UpdateableServerInfo.h"
6 #include "orbsvcs/Log_Macros.h"
8 //---------------------------------------------------------------------------
9 //---------------------------------------------------------------------------
11 static ACE_CString unique_prefix = "\001\002\003\004";
13 AsyncAccessManager::AsyncAccessManager (UpdateableServerInfo &info,
14 ImR_Locator_i &locator)
15 :info_(info),
16 manual_start_ (false),
17 retries_ (info->start_limit_),
18 remove_on_death_rh_ (0),
19 locator_ (locator),
20 poa_ (locator.root_poa ()),
21 rh_list_ (),
22 status_ (ImplementationRepository::AAM_INIT),
23 refcount_ (1),
24 lock_ (),
25 prev_pid_ (0)
27 if (ImR_Locator_i::debug () > 4)
29 this->report ("AsyncAccessManager");
31 this->prev_pid_ = info_->pid;
34 AsyncAccessManager::~AsyncAccessManager (void)
36 if (ImR_Locator_i::debug () > 4)
38 this->report ("~AsyncAccessManager");
42 void
43 AsyncAccessManager::started_running (void)
45 if (ImR_Locator_i::debug () > 4)
47 this->report ("started_running");
50 this->update_status(ImplementationRepository::AAM_SERVER_STARTED_RUNNING);
53 bool
54 AsyncAccessManager::is_terminating (void) const
56 return this->status_ == ImplementationRepository::AAM_ACTIVE_TERMINATE ||
57 remove_on_death_rh_ != 0;
60 bool
61 AsyncAccessManager::is_running (void) const
63 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
65 return !CORBA::is_nil (this->server_.in());
67 else
69 return this->info_->is_running ();
73 bool
74 AsyncAccessManager::has_server (const char *s) const
76 return ACE_OS::strcmp (this->info_->ping_id (), s) == 0;
79 void
80 AsyncAccessManager::report (const char* operation) const
82 const Server_Info* si = info_.operator->();
83 ORBSVCS_DEBUG ((LM_DEBUG,
84 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@:%@)::%C - Server <%C> pid <%d> lastpid <%d> status <%C> running <%d> waiters <%d>\n"),
85 this, si, operation, info_->ping_id (), info_->pid, this->prev_pid_, status_name (this->status_), this->is_running(), this->rh_list_.size()));
88 void
89 AsyncAccessManager::update_prev_pid (void)
91 this->prev_pid_ = this->info_->pid;
94 void
95 AsyncAccessManager::add_interest (ImR_ResponseHandler *rh, bool manual)
98 ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
99 this->rh_list_.push_back (rh);
102 if (manual)
104 this->manual_start_ = true;
106 else if (this->is_terminating())
108 this->notify_waiters ();
109 return;
112 if (ImR_Locator_i::debug () > 4)
114 this->report ("add_interest");
117 this->info_.notify_remote_access (this->status_);
119 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
121 if (!this->send_start_request())
123 this->final_state();
125 return;
128 if (this->status_ == ImplementationRepository::AAM_SERVER_READY ||
129 this->status_ == ImplementationRepository::AAM_SERVER_STARTED_RUNNING)
131 if (this->locator_.pinger().is_alive (this->info_->ping_id()) == LS_ALIVE)
133 this->status (ImplementationRepository::AAM_SERVER_READY);
134 this->final_state();
135 return;
139 if (this->status_ == ImplementationRepository::AAM_INIT ||
140 this->status_ == ImplementationRepository::AAM_SERVER_READY ||
141 this->status_ == ImplementationRepository::AAM_SERVER_STARTED_RUNNING)
143 // This is not a leak. The listener registers with
144 // the pinger and will delete itself when done.
145 AccessLiveListener *l = 0;
146 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
147 this,
148 this->locator_.pinger()));
149 LiveListener_ptr llp(l);
150 if (!l->start())
152 if (!this->send_start_request())
154 this->final_state();
157 else
159 if (this->status_ == ImplementationRepository::AAM_SERVER_STARTED_RUNNING)
161 this->update_status (ImplementationRepository::AAM_WAIT_FOR_ALIVE);
163 else
165 this->update_status (ImplementationRepository::AAM_WAIT_FOR_PING);
171 bool
172 AsyncAccessManager::force_remove_rh (ImR_ResponseHandler *rh)
174 bool busy = true;
175 if (this->remove_on_death_rh_ == 0 || rh == 0)
177 if (rh == 0)
179 delete this->remove_on_death_rh_;
181 this->remove_on_death_rh_ = rh;
182 busy = false;
184 return busy;
187 void
188 AsyncAccessManager::remote_state (ImplementationRepository::AAM_Status state)
190 this->status (state);
191 if (this->is_terminating ())
193 AsyncAccessManager_ptr aam (this->_add_ref());
194 this->locator_.make_terminating (aam,this->info_->ping_id(), this->info_->pid);
195 this->notify_waiters ();
197 if (AsyncAccessManager::is_final (state))
199 this->final_state (false);
203 void
204 AsyncAccessManager::final_state (bool active)
206 if (ImR_Locator_i::debug () > 5)
208 ORBSVCS_DEBUG ((LM_DEBUG,
209 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::final_state - ")
210 ACE_TEXT ("server <%C> active <%d> status <%C> waiters <%d>\n"),
211 this, info_->ping_id (), active, status_name (this->status_), this->rh_list_.size()));
213 bool const success = this->status_ == ImplementationRepository::AAM_SERVER_READY;
214 this->info_.edit (active)->started (success);
215 this->retries_ = this->info_->start_limit_;
216 if (active)
218 this->info_.update_repo ();
220 this->notify_waiters ();
221 this->manual_start_ = false;
223 if (active)
225 this->info_.notify_remote_access (this->status_);
227 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT) ||
228 this->status_ != ImplementationRepository::AAM_SERVER_READY)
230 if (ImR_Locator_i::debug () > 5)
232 ORBSVCS_DEBUG ((LM_DEBUG,
233 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::final_state - ")
234 ACE_TEXT ("removing this from map, server <%C> remove_on_death_rh_ <%@>\n"),
235 this, info_->ping_id (), this->remove_on_death_rh_));
237 if (this->remove_on_death_rh_ != 0)
239 this->locator_.remove_server_i (this->info_.edit());
240 this->remove_on_death_rh_->send_ior("");
241 this->remove_on_death_rh_ = 0;
243 AsyncAccessManager_ptr aam (this);
244 this->locator_.remove_aam (aam);
245 aam._retn(); // release w/o decrementing since table held last reference.
249 void
250 AsyncAccessManager::notify_waiter (ImR_ResponseHandler *rh)
252 if (this->status_ == ImplementationRepository::AAM_SERVER_READY)
254 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
256 if (ImR_Locator_i::debug () > 5)
258 ORBSVCS_DEBUG ((LM_DEBUG,
259 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::notify_waiter - ")
260 ACE_TEXT ("For unique server <%C> reporting back IOR <%C>\n"),
261 this, info_->ping_id (), this->partial_ior_.c_str()));
263 rh->send_ior (this->partial_ior_.c_str());
265 else
267 if (ImR_Locator_i::debug () > 5)
269 ORBSVCS_DEBUG ((LM_DEBUG,
270 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::notify_waiter - ")
271 ACE_TEXT ("For server <%C> reporting back IOR <%C>\n"),
272 this, info_->ping_id (), this->info_->partial_ior.c_str()));
274 rh->send_ior (this->info_->partial_ior.c_str());
277 else
281 switch (this->status_)
283 case ImplementationRepository::AAM_NO_ACTIVATOR:
284 throw ImplementationRepository::CannotActivate
285 ("No activator registered for server.");
286 case ImplementationRepository::AAM_NOT_MANUAL:
287 throw ImplementationRepository::CannotActivate
288 ("Cannot implicitly activate MANUAL server.");
289 case ImplementationRepository::AAM_NO_COMMANDLINE:
290 throw ImplementationRepository::CannotActivate
291 ("No command line registered for server.");
292 case ImplementationRepository::AAM_RETRIES_EXCEEDED:
293 throw ImplementationRepository::CannotActivate
294 ("Restart attempt count exceeded.");
295 case ImplementationRepository::AAM_ACTIVE_TERMINATE:
296 throw ImplementationRepository::CannotActivate
297 ("Server terminating.");
298 default: {
299 ACE_CString reason = ACE_CString ("AAM_Status is ") +
300 status_name (this->status_);
301 throw ImplementationRepository::CannotActivate (reason.c_str());
305 catch (const CORBA::Exception &ex)
307 rh->send_exception (ex._tao_duplicate());
312 void
313 AsyncAccessManager::notify_waiters (void)
315 if (ImR_Locator_i::debug () > 4)
317 this->report ("notify_waiters");
320 for (size_t i = 0; i < this->rh_list_.size(); i++)
322 // Sending the IOR through to the response handler could trigger
323 // an exception which we should catch here and log. This way when
324 // we have multiple waiters we do inform them all and not abort
325 // after the first exception
328 ImR_ResponseHandler *rh = this->rh_list_[i];
329 if (rh != 0)
331 this->notify_waiter (rh);
334 catch (const CORBA::Exception& ex)
336 if (ImR_Locator_i::debug () > 1)
338 ex._tao_print_exception ("AsyncAccessManager::notify_waiters");
342 this->rh_list_.clear ();
345 bool
346 AsyncAccessManager::is_final (ImplementationRepository::AAM_Status s)
348 return (s == ImplementationRepository::AAM_SERVER_READY ||
349 s == ImplementationRepository::AAM_SERVER_DEAD ||
350 s == ImplementationRepository::AAM_NOT_MANUAL ||
351 s == ImplementationRepository::AAM_NO_ACTIVATOR ||
352 s == ImplementationRepository::AAM_NO_COMMANDLINE ||
353 s == ImplementationRepository::AAM_RETRIES_EXCEEDED);
356 const char *
357 AsyncAccessManager::status_name (ImplementationRepository::AAM_Status s)
359 switch (s)
361 case ImplementationRepository::AAM_INIT:
362 return "INIT";
363 case ImplementationRepository::AAM_SERVER_STARTED_RUNNING:
364 return "SERVER_STARTED_RUNNING";
365 case ImplementationRepository::AAM_WAIT_FOR_RUNNING:
366 return "WAIT_FOR_RUNNING";
367 case ImplementationRepository::AAM_WAIT_FOR_PING:
368 return "WAIT_FOR_PING";
369 case ImplementationRepository::AAM_WAIT_FOR_ALIVE:
370 return "WAIT_FOR_ALIVE";
371 case ImplementationRepository::AAM_WAIT_FOR_DEATH:
372 return "WAIT_FOR_DEATH";
373 case ImplementationRepository::AAM_SERVER_READY:
374 return "SERVER_READY";
375 case ImplementationRepository::AAM_SERVER_DEAD:
376 return "SERVER_DEAD";
377 case ImplementationRepository::AAM_NOT_MANUAL:
378 return "NOT_MANUAL";
379 case ImplementationRepository::AAM_NO_ACTIVATOR:
380 return "NO_ACTIVATOR";
381 case ImplementationRepository::AAM_NO_COMMANDLINE:
382 return "NO_COMMANDLINE";
383 case ImplementationRepository::AAM_RETRIES_EXCEEDED:
384 return "RETRIES_EXCEEDED";
385 case ImplementationRepository::AAM_UPDATE_FAILED:
386 return "UPDATE_FAILED";
387 case ImplementationRepository::AAM_ACTIVE_TERMINATE:
388 return "ACTIVE_TERMINATE";
391 return "<undefined status>";
394 ImplementationRepository::AAM_Status
395 AsyncAccessManager::status (void) const
397 return this->status_;
400 void
401 AsyncAccessManager::status (ImplementationRepository::AAM_Status s)
403 ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
404 this->status_ = s;
405 if (s == ImplementationRepository::AAM_SERVER_DEAD)
407 this->info_.edit()->pid = 0;
411 void
412 AsyncAccessManager::update_status (ImplementationRepository::AAM_Status s)
414 this->status (s);
415 if (ImR_Locator_i::debug () > 4)
417 this->report ("update_status");
419 this->info_.notify_remote_access (s);
422 void
423 AsyncAccessManager::activator_replied_start_running (bool success, int pid)
425 if (ImR_Locator_i::debug () > 4)
427 this->report ("activator_replied_start_running");
430 if (success)
432 if (pid != 0)
434 this->update_status (ImplementationRepository::AAM_SERVER_READY);
435 this->info_.edit()->pid = pid;
436 this->final_state ();
439 else
441 this->status (ImplementationRepository::AAM_NO_ACTIVATOR);
442 this->final_state ();
446 void
447 AsyncAccessManager::shutdown_initiated (void)
449 if (ImR_Locator_i::debug () > 4)
451 this->report ("shutdown_initiated");
453 this->prev_pid_ = this->info_->pid;
454 this->status (ImplementationRepository::AAM_ACTIVE_TERMINATE);
455 if (this->info_->pid != 0)
457 AsyncAccessManager_ptr aam (this->_add_ref());
458 this->locator_.make_terminating (aam,this->info_->ping_id(), this->info_->pid);
460 this->notify_waiters ();
463 void
464 AsyncAccessManager::server_is_shutting_down (void)
466 if (ImR_Locator_i::debug () > 4)
468 this->report ("server_is_shutting_down-start");
470 // We are informed directly by the server that it is shutting down. This doesn't
471 // imply that the server is dead at this point, there can be some time between
472 // the POA destroy and the server process exit so we have to wait for the death
473 // of the process before we can mark this server as dead
474 this->prev_pid_ = this->info_->pid;
475 if (this->info_->death_notify)
477 // We get a death notify of the activator so we can wait on the death
478 // of the process
479 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
481 else
483 // We don't get a death notify of the activator so we have to assume at
484 // this point the server is death
485 this->status (ImplementationRepository::AAM_SERVER_DEAD);
486 this->final_state ();
488 if (ImR_Locator_i::debug () > 4)
490 this->report ("server_is_shutting_down-end");
494 void
495 AsyncAccessManager::server_is_running (const char *partial_ior,
496 ImplementationRepository::ServerObject_ptr ref)
498 if (ImR_Locator_i::debug () > 4)
500 this->report ("server_is_running-start");
503 this->update_status (ImplementationRepository::AAM_WAIT_FOR_ALIVE);
504 // Only when we are not using per client activation we should store the
505 // information of the started server within our repository
506 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
508 this->partial_ior_ = partial_ior;
509 this->server_ = ImplementationRepository::ServerObject::_duplicate (ref);
511 else
513 this->info_.edit ()->partial_ior = partial_ior;
514 this->info_.edit ()->server = ImplementationRepository::ServerObject::_duplicate (ref);
517 if (this->locator_.pinger().is_alive (this->info_->ping_id()) == LS_ALIVE)
519 this->status (ImplementationRepository::AAM_SERVER_READY);
520 this->final_state ();
523 AccessLiveListener *l = 0;
524 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
526 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
527 this,
528 this->locator_.pinger(),
529 this->server_.in ()));
531 else
533 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
534 this,
535 this->locator_.pinger()));
538 LiveListener_ptr llp(l);
539 if (!l->start())
541 this->status (ImplementationRepository::AAM_SERVER_DEAD);
542 this->final_state ();
545 if (ImR_Locator_i::debug () > 4)
547 this->report ("server_is_running-end");
551 bool
552 AsyncAccessManager::notify_child_death (int pid)
554 if (ImR_Locator_i::debug () > 4)
556 ORBSVCS_DEBUG ((LM_DEBUG,
557 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@), notify_child_death, server <%C> pid <%d> status <%C> ")
558 ACE_TEXT ("this info_.pid <%d> prev_pid <%d> waiter count <%d>\n"),
559 this, info_->ping_id (), pid, status_name (status_),
560 this->info_->pid, this->prev_pid_, this->rh_list_.size()));
562 if (this->info_->pid == pid || this->prev_pid_ == pid)
564 if ((this->status_ == ImplementationRepository::AAM_WAIT_FOR_DEATH) &&
565 this->rh_list_.size() > 0)
567 // When we have successfully made another start request we just let the
568 // waiters wait on the result of the new start request
569 if (this->send_start_request ())
571 return true;
574 this->status (ImplementationRepository::AAM_SERVER_DEAD);
575 this->final_state ();
576 return true;
578 else
580 if (ImR_Locator_i::debug () > 1)
582 ORBSVCS_ERROR ((LM_ERROR,
583 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@), notify_child_death, server <%C> pid <%d> does not match ")
584 ACE_TEXT ("this info_.pid <%d> prev_pid <%d>\n"),
585 this, info_->ping_id (), pid,
586 this->info_->pid, this->prev_pid_));
589 return false;
592 void
593 AsyncAccessManager::listener_disconnected (void)
595 if (ImR_Locator_i::debug () > 4)
597 this->report ("listener_disconnected");
600 if (this->info_->death_notify)
602 // We get a death notify of the activator so we can wait on the death
603 // of the process
604 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
606 else
608 // We don't get a death notify of the activator so we have to assume at
609 // this point the server is death
610 this->status (ImplementationRepository::AAM_SERVER_DEAD);
614 void
615 AsyncAccessManager::ping_replied (LiveStatus server)
617 if (ImR_Locator_i::debug () > 4)
619 ORBSVCS_DEBUG ((LM_DEBUG,
620 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied <%C>")
621 ACE_TEXT (" this status <%C>\n"),
622 this, LiveEntry::status_name (server), status_name (this->status_)));
625 switch (server)
627 case LS_ALIVE:
628 case LS_LAST_TRANSIENT:
629 case LS_TIMEDOUT:
630 this->status (ImplementationRepository::AAM_SERVER_READY);
631 break;
632 case LS_CANCELED:
634 if (this->status_ == ImplementationRepository::AAM_WAIT_FOR_PING)
636 AccessLiveListener *l = 0;
637 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
638 this,
639 this->locator_.pinger()));
640 LiveListener_ptr llp(l);
642 return;
644 case LS_DEAD:
646 if (this->status_ == ImplementationRepository::AAM_WAIT_FOR_PING)
648 if (this->info_->death_notify && this->info_->pid != 0)
650 if (ImR_Locator_i::debug () > 4)
652 ORBSVCS_DEBUG ((LM_DEBUG,
653 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
654 ACE_TEXT (" waiting on ping, transition to <WAIT_FOR_DEATH>\n"),
655 this, this->info_->pid));
657 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
658 return;
660 if (ImR_Locator_i::debug () > 4)
662 ORBSVCS_DEBUG ((LM_DEBUG,
663 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
664 ACE_TEXT (" trying to restart server\n"),
665 this, this->info_->pid));
667 if (this->send_start_request ())
669 return;
672 else
674 // If we get a death notify we wait for the death of the process, the fact that the
675 // ping failed doesn't mean the process itself is already death
676 if (this->info_->death_notify && this->info_->pid != 0)
678 if (ImR_Locator_i::debug () > 4)
680 ORBSVCS_DEBUG ((LM_DEBUG,
681 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
682 ACE_TEXT (" transition to <WAIT_FOR_DEATH>\n"),
683 this, this->info_->pid));
685 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
686 return;
688 else
690 if (ImR_Locator_i::debug () > 4)
692 ORBSVCS_DEBUG ((LM_DEBUG,
693 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
694 ACE_TEXT (" transition to <SERVER_DEAD>\n"),
695 this, this->info_->pid));
697 this->status (ImplementationRepository::AAM_SERVER_DEAD);
701 break;
702 default:
703 return;
705 this->final_state();
708 bool
709 AsyncAccessManager::send_start_request (void)
711 if (ImR_Locator_i::debug () > 4)
713 ORBSVCS_DEBUG ((LM_DEBUG,
714 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> manual_start <%d> retries <%d>\n"),
715 this, this->info_->ping_id(), this->manual_start_, this->retries_));
718 if ((this->locator_.opts ()->lockout () && !this->info_.edit ()->start_allowed ()) ||
719 (this->retries_ == 0))
721 if (ImR_Locator_i::debug () > 4)
723 ORBSVCS_ERROR ((LM_ERROR,
724 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because retries exceeded\n"),
725 this, this->info_->ping_id()));
727 this->status (ImplementationRepository::AAM_RETRIES_EXCEEDED);
728 return false;
731 --this->retries_;
733 if (this->info_->is_mode (ImplementationRepository::MANUAL) &&
734 !this->manual_start_)
736 if (ImR_Locator_i::debug () > 4)
738 ORBSVCS_ERROR ((LM_ERROR,
739 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because only a manual start is allowed\n"),
740 this, this->info_->ping_id()));
742 this->status (ImplementationRepository::AAM_NOT_MANUAL);
743 return false;
746 const Server_Info *startup = this->info_->active_info ();
748 if (startup->cmdline.length () == 0)
750 if (ImR_Locator_i::debug () > 4)
752 ORBSVCS_ERROR ((LM_ERROR,
753 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because no commandline has been configured\n"),
754 this, this->info_->ping_id()));
756 this->status (ImplementationRepository::AAM_NO_COMMANDLINE);
757 return false;
760 Activator_Info_Ptr ainfo =
761 this->locator_.get_activator (startup->activator);
763 if (ainfo.null () || CORBA::is_nil (ainfo->activator.in ()))
765 if (ImR_Locator_i::debug () > 4)
767 ORBSVCS_ERROR ((LM_ERROR,
768 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because no activator has been found\n"),
769 this, this->info_->ping_id()));
771 this->status (ImplementationRepository::AAM_NO_ACTIVATOR);
772 return false;
775 PortableServer::ServantBase_var callback = new ActivatorReceiver (this,
776 this->poa_.in());
777 PortableServer::ObjectId_var oid = this->poa_->activate_object (callback.in());
778 CORBA::Object_var obj = this->poa_->id_to_reference (oid.in());
779 ImplementationRepository::AMI_ActivatorHandler_var cb =
780 ImplementationRepository::AMI_ActivatorHandler::_narrow (obj.in());
782 ACE_CString servername;
784 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
786 servername = startup->key_name_;
788 else
790 // When we start a new server we need set our process id back to zero
791 // so that we ignore an asynchronous child death which can happens after
792 // we already restarted the server
793 this->info_.edit()->pid = 0;
794 servername = unique_prefix + startup->key_name_;
797 ainfo->activator->sendc_start_server (cb.in(),
798 servername.c_str (),
799 startup->cmdline.c_str (),
800 startup->dir.c_str (),
801 startup->env_vars);
802 this->update_status (ImplementationRepository::AAM_WAIT_FOR_RUNNING);
803 return true;
806 AsyncAccessManager *
807 AsyncAccessManager::_add_ref (void)
809 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, mon, this->lock_, 0);
810 ++this->refcount_;
812 return this;
815 void
816 AsyncAccessManager::_remove_ref (void)
818 int count = 0;
820 ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
821 count = --this->refcount_;
823 if (count == 0)
825 delete this;
829 //---------------------------------------------------------------------------
830 //---------------------------------------------------------------------------
832 ActivatorReceiver::ActivatorReceiver (AsyncAccessManager *aam,
833 PortableServer::POA_ptr poa)
834 :aam_ (aam->_add_ref ()),
835 poa_ (PortableServer::POA::_duplicate (poa))
839 ActivatorReceiver::~ActivatorReceiver (void)
843 void
844 ActivatorReceiver::start_server (void)
846 if (ImR_Locator_i::debug () > 4)
848 ORBSVCS_DEBUG ((LM_DEBUG,
849 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server, received start_server reply\n"),
850 this));
853 PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
854 poa_->deactivate_object (oid.in());
857 void
858 ActivatorReceiver::start_server_excep (Messaging::ExceptionHolder *holder)
860 if (ImR_Locator_i::debug () > 4)
862 ORBSVCS_DEBUG ((LM_DEBUG,
863 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server_excep, received start_server_excep reply\n"),
864 this));
869 holder->raise_exception ();
871 catch (const ImplementationRepository::CannotActivate &ca)
873 if (ImR_Locator_i::debug () > 1)
875 ORBSVCS_DEBUG ((LM_DEBUG,
876 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server_excep, reason <%C>\n"),
877 this, ca.reason.in ()));
879 if (ACE_OS::strstr (ca.reason.in(),"pid:") == ca.reason.in())
881 int const pid = ACE_OS::atoi (ca.reason.in()+4);
882 this->aam_->activator_replied_start_running (true, pid);
884 else
886 this->aam_->activator_replied_start_running (false, 0);
889 catch (const CORBA::Exception& ex)
891 if (ImR_Locator_i::debug () > 1)
893 ex._tao_print_exception ("ActivatorReceiver::start_server_excep");
897 PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
898 poa_->deactivate_object (oid.in());
901 void
902 ActivatorReceiver::shutdown (void)
906 void
907 ActivatorReceiver::shutdown_excep (Messaging::ExceptionHolder * )
911 void
912 ActivatorReceiver::kill_server (CORBA::Boolean )
916 void
917 ActivatorReceiver::kill_server_excep (Messaging::ExceptionHolder * )
922 //---------------------------------------------------------------------------
923 //---------------------------------------------------------------------------
925 AccessLiveListener::AccessLiveListener (const char *server,
926 AsyncAccessManager *aam,
927 LiveCheck &pinger)
928 :LiveListener (server),
929 aam_ (aam->_add_ref ()),
930 pinger_ (pinger),
931 status_ (LS_UNKNOWN),
932 per_client_ (false),
933 srv_ref_ (ImplementationRepository::ServerObject::_nil())
937 AccessLiveListener::AccessLiveListener (const char *server,
938 AsyncAccessManager *aam,
939 LiveCheck &pinger,
940 ImplementationRepository::ServerObject_ptr ref)
941 :LiveListener (server),
942 aam_ (aam->_add_ref ()),
943 pinger_ (pinger),
944 status_ (LS_UNKNOWN),
945 per_client_ (true),
946 srv_ref_ (ImplementationRepository::ServerObject::_duplicate (ref))
950 AccessLiveListener::~AccessLiveListener (void)
952 if (!this->aam_.is_nil())
954 aam_->listener_disconnected();
958 bool
959 AccessLiveListener::start (void)
961 bool const started = this->per_client_ ?
962 this->pinger_.add_per_client_listener (this, srv_ref_.in()) :
963 this->pinger_.add_listener (this);
964 if (!started)
966 this->aam_ = 0;
968 return started;
971 bool
972 AccessLiveListener::status_changed (LiveStatus status)
974 this->status_ = status;
975 switch (status_) {
976 case LS_TRANSIENT:
978 return false;
980 default:
981 if (!this->aam_.is_nil())
983 this->aam_->ping_replied (status);
985 this->aam_ = 0;
987 return true;