Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / orbsvcs / ImplRepo_Service / AsyncAccessManager.cpp
blobbcb9e1ea3440fa04e38a907e3f40c6bcc4170e3c
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 ()
36 if (ImR_Locator_i::debug () > 4)
38 this->report ("~AsyncAccessManager");
42 void
43 AsyncAccessManager::started_running ()
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 () const
56 return this->status_ == ImplementationRepository::AAM_ACTIVE_TERMINATE ||
57 remove_on_death_rh_ != 0;
60 bool
61 AsyncAccessManager::is_running () 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 ()
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 ()
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";
390 return "<undefined status>";
393 ImplementationRepository::AAM_Status
394 AsyncAccessManager::status () const
396 return this->status_;
399 void
400 AsyncAccessManager::status (ImplementationRepository::AAM_Status s)
402 ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
403 this->status_ = s;
404 if (s == ImplementationRepository::AAM_SERVER_DEAD)
406 this->info_.edit()->pid = 0;
410 void
411 AsyncAccessManager::update_status (ImplementationRepository::AAM_Status s)
413 this->status (s);
414 if (ImR_Locator_i::debug () > 4)
416 this->report ("update_status");
418 this->info_.notify_remote_access (s);
421 void
422 AsyncAccessManager::activator_replied_start_running (bool success, int pid)
424 if (ImR_Locator_i::debug () > 4)
426 this->report ("activator_replied_start_running");
429 if (success)
431 if (pid != 0)
433 this->update_status (ImplementationRepository::AAM_SERVER_READY);
434 this->info_.edit()->pid = pid;
435 this->final_state ();
438 else
440 this->status (ImplementationRepository::AAM_NO_ACTIVATOR);
441 this->final_state ();
445 void
446 AsyncAccessManager::shutdown_initiated ()
448 if (ImR_Locator_i::debug () > 4)
450 this->report ("shutdown_initiated");
452 this->prev_pid_ = this->info_->pid;
453 this->status (ImplementationRepository::AAM_ACTIVE_TERMINATE);
454 if (this->info_->pid != 0)
456 AsyncAccessManager_ptr aam (this->_add_ref());
457 this->locator_.make_terminating (aam,this->info_->ping_id(), this->info_->pid);
459 this->notify_waiters ();
462 void
463 AsyncAccessManager::server_is_shutting_down ()
465 if (ImR_Locator_i::debug () > 4)
467 this->report ("server_is_shutting_down-start");
469 // We are informed directly by the server that it is shutting down. This doesn't
470 // imply that the server is dead at this point, there can be some time between
471 // the POA destroy and the server process exit so we have to wait for the death
472 // of the process before we can mark this server as dead
473 this->prev_pid_ = this->info_->pid;
474 if (this->info_->death_notify)
476 // We get a death notify of the activator so we can wait on the death
477 // of the process
478 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
480 else
482 // We don't get a death notify of the activator so we have to assume at
483 // this point the server is death
484 this->status (ImplementationRepository::AAM_SERVER_DEAD);
485 this->final_state ();
487 if (ImR_Locator_i::debug () > 4)
489 this->report ("server_is_shutting_down-end");
493 void
494 AsyncAccessManager::server_is_running (const char *partial_ior,
495 ImplementationRepository::ServerObject_ptr ref)
497 if (ImR_Locator_i::debug () > 4)
499 this->report ("server_is_running-start");
502 this->update_status (ImplementationRepository::AAM_WAIT_FOR_ALIVE);
503 // Only when we are not using per client activation we should store the
504 // information of the started server within our repository
505 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
507 this->partial_ior_ = partial_ior;
508 this->server_ = ImplementationRepository::ServerObject::_duplicate (ref);
510 else
512 this->info_.edit ()->partial_ior = partial_ior;
513 this->info_.edit ()->server = ImplementationRepository::ServerObject::_duplicate (ref);
516 if (this->locator_.pinger().is_alive (this->info_->ping_id()) == LS_ALIVE)
518 this->status (ImplementationRepository::AAM_SERVER_READY);
519 this->final_state ();
522 AccessLiveListener *l = 0;
523 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
525 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
526 this,
527 this->locator_.pinger(),
528 this->server_.in ()));
530 else
532 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
533 this,
534 this->locator_.pinger()));
537 LiveListener_ptr llp(l);
538 if (!l->start())
540 this->status (ImplementationRepository::AAM_SERVER_DEAD);
541 this->final_state ();
544 if (ImR_Locator_i::debug () > 4)
546 this->report ("server_is_running-end");
550 bool
551 AsyncAccessManager::notify_child_death (int pid)
553 if (ImR_Locator_i::debug () > 4)
555 ORBSVCS_DEBUG ((LM_DEBUG,
556 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@), notify_child_death, server <%C> pid <%d> status <%C> ")
557 ACE_TEXT ("this info_.pid <%d> prev_pid <%d> waiter count <%d>\n"),
558 this, info_->ping_id (), pid, status_name (status_),
559 this->info_->pid, this->prev_pid_, this->rh_list_.size()));
561 if (this->info_->pid == pid || this->prev_pid_ == pid)
563 if ((this->status_ == ImplementationRepository::AAM_WAIT_FOR_DEATH) &&
564 this->rh_list_.size() > 0)
566 // When we have successfully made another start request we just let the
567 // waiters wait on the result of the new start request
568 if (this->send_start_request ())
570 return true;
573 this->status (ImplementationRepository::AAM_SERVER_DEAD);
574 this->final_state ();
575 return true;
577 else
579 if (ImR_Locator_i::debug () > 1)
581 ORBSVCS_ERROR ((LM_ERROR,
582 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@), notify_child_death, server <%C> pid <%d> does not match ")
583 ACE_TEXT ("this info_.pid <%d> prev_pid <%d>\n"),
584 this, info_->ping_id (), pid,
585 this->info_->pid, this->prev_pid_));
588 return false;
591 void
592 AsyncAccessManager::listener_disconnected ()
594 if (ImR_Locator_i::debug () > 4)
596 this->report ("listener_disconnected");
599 if (this->info_->death_notify)
601 // We get a death notify of the activator so we can wait on the death
602 // of the process
603 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
605 else
607 // We don't get a death notify of the activator so we have to assume at
608 // this point the server is death
609 this->status (ImplementationRepository::AAM_SERVER_DEAD);
613 void
614 AsyncAccessManager::ping_replied (LiveStatus server)
616 if (ImR_Locator_i::debug () > 4)
618 ORBSVCS_DEBUG ((LM_DEBUG,
619 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied <%C>")
620 ACE_TEXT (" this status <%C>\n"),
621 this, LiveEntry::status_name (server), status_name (this->status_)));
624 switch (server)
626 case LS_ALIVE:
627 case LS_LAST_TRANSIENT:
628 case LS_TIMEDOUT:
629 this->status (ImplementationRepository::AAM_SERVER_READY);
630 break;
631 case LS_CANCELED:
633 if (this->status_ == ImplementationRepository::AAM_WAIT_FOR_PING)
635 AccessLiveListener *l = 0;
636 ACE_NEW (l, AccessLiveListener (this->info_->ping_id(),
637 this,
638 this->locator_.pinger()));
639 LiveListener_ptr llp(l);
641 return;
643 case LS_DEAD:
645 if (this->status_ == ImplementationRepository::AAM_WAIT_FOR_PING)
647 if (this->info_->death_notify && this->info_->pid != 0)
649 if (ImR_Locator_i::debug () > 4)
651 ORBSVCS_DEBUG ((LM_DEBUG,
652 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
653 ACE_TEXT (" waiting on ping, transition to <WAIT_FOR_DEATH>\n"),
654 this, this->info_->pid));
656 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
657 return;
659 if (ImR_Locator_i::debug () > 4)
661 ORBSVCS_DEBUG ((LM_DEBUG,
662 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
663 ACE_TEXT (" trying to restart server\n"),
664 this, this->info_->pid));
666 if (this->send_start_request ())
668 return;
671 else
673 // If we get a death notify we wait for the death of the process, the fact that the
674 // ping failed doesn't mean the process itself is already death
675 if (this->info_->death_notify && this->info_->pid != 0)
677 if (ImR_Locator_i::debug () > 4)
679 ORBSVCS_DEBUG ((LM_DEBUG,
680 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
681 ACE_TEXT (" transition to <WAIT_FOR_DEATH>\n"),
682 this, this->info_->pid));
684 this->status (ImplementationRepository::AAM_WAIT_FOR_DEATH);
685 return;
687 else
689 if (ImR_Locator_i::debug () > 4)
691 ORBSVCS_DEBUG ((LM_DEBUG,
692 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::ping_replied pid <%d>,")
693 ACE_TEXT (" transition to <SERVER_DEAD>\n"),
694 this, this->info_->pid));
696 this->status (ImplementationRepository::AAM_SERVER_DEAD);
700 break;
701 default:
702 return;
704 this->final_state();
707 bool
708 AsyncAccessManager::send_start_request ()
710 if (ImR_Locator_i::debug () > 4)
712 ORBSVCS_DEBUG ((LM_DEBUG,
713 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> manual_start <%d> retries <%d>\n"),
714 this, this->info_->ping_id(), this->manual_start_, this->retries_));
717 if ((this->locator_.opts ()->lockout () && !this->info_.edit ()->start_allowed ()) ||
718 (this->retries_ == 0))
720 if (ImR_Locator_i::debug () > 4)
722 ORBSVCS_ERROR ((LM_ERROR,
723 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because retries exceeded\n"),
724 this, this->info_->ping_id()));
726 this->status (ImplementationRepository::AAM_RETRIES_EXCEEDED);
727 return false;
730 --this->retries_;
732 if (this->info_->is_mode (ImplementationRepository::MANUAL) &&
733 !this->manual_start_)
735 if (ImR_Locator_i::debug () > 4)
737 ORBSVCS_ERROR ((LM_ERROR,
738 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because only a manual start is allowed\n"),
739 this, this->info_->ping_id()));
741 this->status (ImplementationRepository::AAM_NOT_MANUAL);
742 return false;
745 const Server_Info *startup = this->info_->active_info ();
747 if (startup->cmdline.length () == 0)
749 if (ImR_Locator_i::debug () > 4)
751 ORBSVCS_ERROR ((LM_ERROR,
752 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because no commandline has been configured\n"),
753 this, this->info_->ping_id()));
755 this->status (ImplementationRepository::AAM_NO_COMMANDLINE);
756 return false;
759 Activator_Info_Ptr ainfo =
760 this->locator_.get_activator (startup->activator);
762 if (ainfo.null () || CORBA::is_nil (ainfo->activator.in ()))
764 if (ImR_Locator_i::debug () > 4)
766 ORBSVCS_ERROR ((LM_ERROR,
767 ACE_TEXT ("(%P|%t) AsyncAccessManager(%@)::send_start_request, server <%C> not started because no activator has been found\n"),
768 this, this->info_->ping_id()));
770 this->status (ImplementationRepository::AAM_NO_ACTIVATOR);
771 return false;
774 PortableServer::ServantBase_var callback = new ActivatorReceiver (this,
775 this->poa_.in());
776 PortableServer::ObjectId_var oid = this->poa_->activate_object (callback.in());
777 CORBA::Object_var obj = this->poa_->id_to_reference (oid.in());
778 ImplementationRepository::AMI_ActivatorHandler_var cb =
779 ImplementationRepository::AMI_ActivatorHandler::_narrow (obj.in());
781 ACE_CString servername;
783 if (this->info_->is_mode (ImplementationRepository::PER_CLIENT))
785 servername = startup->key_name_;
787 else
789 // When we start a new server we need set our process id back to zero
790 // so that we ignore an asynchronous child death which can happens after
791 // we already restarted the server
792 this->info_.edit()->pid = 0;
793 servername = unique_prefix + startup->key_name_;
796 ainfo->activator->sendc_start_server (cb.in(),
797 servername.c_str (),
798 startup->cmdline.c_str (),
799 startup->dir.c_str (),
800 startup->env_vars);
801 this->update_status (ImplementationRepository::AAM_WAIT_FOR_RUNNING);
802 return true;
805 AsyncAccessManager *
806 AsyncAccessManager::_add_ref ()
808 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, mon, this->lock_, 0);
809 ++this->refcount_;
811 return this;
814 void
815 AsyncAccessManager::_remove_ref ()
817 int count = 0;
819 ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_);
820 count = --this->refcount_;
822 if (count == 0)
824 delete this;
828 //---------------------------------------------------------------------------
829 //---------------------------------------------------------------------------
831 ActivatorReceiver::ActivatorReceiver (AsyncAccessManager *aam,
832 PortableServer::POA_ptr poa)
833 :aam_ (aam->_add_ref ()),
834 poa_ (PortableServer::POA::_duplicate (poa))
838 ActivatorReceiver::~ActivatorReceiver ()
842 void
843 ActivatorReceiver::start_server ()
845 if (ImR_Locator_i::debug () > 4)
847 ORBSVCS_DEBUG ((LM_DEBUG,
848 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server, received start_server reply\n"),
849 this));
852 PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
853 poa_->deactivate_object (oid.in());
856 void
857 ActivatorReceiver::start_server_excep (Messaging::ExceptionHolder *holder)
859 if (ImR_Locator_i::debug () > 4)
861 ORBSVCS_DEBUG ((LM_DEBUG,
862 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server_excep, received start_server_excep reply\n"),
863 this));
868 holder->raise_exception ();
870 catch (const ImplementationRepository::CannotActivate &ca)
872 if (ImR_Locator_i::debug () > 1)
874 ORBSVCS_DEBUG ((LM_DEBUG,
875 ACE_TEXT ("(%P|%t) ActivatorReceiver(%@)::start_server_excep, reason <%C>\n"),
876 this, ca.reason.in ()));
878 if (ACE_OS::strstr (ca.reason.in(),"pid:") == ca.reason.in())
880 int const pid = ACE_OS::atoi (ca.reason.in()+4);
881 this->aam_->activator_replied_start_running (true, pid);
883 else
885 this->aam_->activator_replied_start_running (false, 0);
888 catch (const CORBA::Exception& ex)
890 if (ImR_Locator_i::debug () > 1)
892 ex._tao_print_exception ("ActivatorReceiver::start_server_excep");
896 PortableServer::ObjectId_var oid = this->poa_->servant_to_id (this);
897 poa_->deactivate_object (oid.in());
900 void
901 ActivatorReceiver::shutdown ()
905 void
906 ActivatorReceiver::shutdown_excep (Messaging::ExceptionHolder * )
910 void
911 ActivatorReceiver::kill_server (CORBA::Boolean )
915 void
916 ActivatorReceiver::kill_server_excep (Messaging::ExceptionHolder * )
921 //---------------------------------------------------------------------------
922 //---------------------------------------------------------------------------
924 AccessLiveListener::AccessLiveListener (const char *server,
925 AsyncAccessManager *aam,
926 LiveCheck &pinger)
927 :LiveListener (server),
928 aam_ (aam->_add_ref ()),
929 pinger_ (pinger),
930 status_ (LS_UNKNOWN),
931 per_client_ (false),
932 srv_ref_ (ImplementationRepository::ServerObject::_nil())
936 AccessLiveListener::AccessLiveListener (const char *server,
937 AsyncAccessManager *aam,
938 LiveCheck &pinger,
939 ImplementationRepository::ServerObject_ptr ref)
940 :LiveListener (server),
941 aam_ (aam->_add_ref ()),
942 pinger_ (pinger),
943 status_ (LS_UNKNOWN),
944 per_client_ (true),
945 srv_ref_ (ImplementationRepository::ServerObject::_duplicate (ref))
949 AccessLiveListener::~AccessLiveListener ()
951 if (!this->aam_.is_nil())
953 aam_->listener_disconnected();
957 bool
958 AccessLiveListener::start ()
960 bool const started = this->per_client_ ?
961 this->pinger_.add_per_client_listener (this, srv_ref_.in()) :
962 this->pinger_.add_listener (this);
963 if (!started)
965 this->aam_ = 0;
967 return started;
970 bool
971 AccessLiveListener::status_changed (LiveStatus status)
973 this->status_ = status;
974 switch (status_) {
975 case LS_TRANSIENT:
977 return false;
979 default:
980 if (!this->aam_.is_nil())
982 this->aam_->ping_replied (status);
984 this->aam_ = 0;
986 return true;