Cleanup ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE, all platforms support it so far as I can...
[ACE_TAO.git] / TAO / orbsvcs / ImplRepo_Service / AsyncListManager.cpp
blob3c6db946c54e7238f421424e32bf8266bafabe4e
1 // -*- C++ -*-
2 #include "AsyncListManager.h"
3 #include "Iterator.h"
4 #include "Locator_Repository.h"
5 #include "ImR_Locator_i.h"
7 #include "orbsvcs/Log_Macros.h"
9 //---------------------------------------------------------------------------
10 //---------------------------------------------------------------------------
12 AsyncListManager::AsyncListManager (const Locator_Repository *repo,
13 PortableServer::POA_ptr poa,
14 LiveCheck *pinger)
15 :repo_ (repo),
16 poa_ (PortableServer::POA::_duplicate (poa)),
17 primary_ (ImplementationRepository::AMH_AdministrationResponseHandler::_nil ()),
18 secondary_ (ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_nil ()),
19 pinger_ (pinger),
20 server_list_ (0),
21 first_ (0),
22 how_many_ (0),
23 waiters_ (0),
24 refcount_ (1)
28 AsyncListManager::~AsyncListManager ()
30 if (ImR_Locator_i::debug() > 4)
32 ORBSVCS_DEBUG ((LM_DEBUG,
33 ACE_TEXT ("(%P|%t) AsyncListManager(%@)::dtor\n"),
34 this));
38 PortableServer::POA_ptr
39 AsyncListManager::poa ()
41 return PortableServer::POA::_duplicate (this->poa_.in());
44 void
45 AsyncListManager::init_list ()
47 CORBA::ULong const len =
48 static_cast<CORBA::ULong> (this->repo_->servers ().current_size ());
49 Locator_Repository::SIMap::ENTRY* entry = 0;
50 Locator_Repository::SIMap::CONST_ITERATOR it (this->repo_->servers ());
51 this->server_list_.length (len);
52 this->waiters_ = 0;
53 for (CORBA::ULong i = 0; i < len; i++)
55 it.next (entry);
56 it.advance ();
58 Server_Info_Ptr info = entry->int_id_;
59 info->setImRInfo (&this->server_list_[i]);
60 if (this->pinger_ != 0)
62 ListLiveListener *l = 0;
63 ACE_NEW (l, ListLiveListener (info->ping_id (),
64 info->pid,
66 this,
67 *this->pinger_));
69 LiveListener_ptr llp (l);
70 if (!l->start ())
72 this->server_list_[i].activeStatus =
73 ImplementationRepository::ACTIVE_NO;
74 l->cancel ();
76 else
78 if (!evaluate_status (i, l->status(), info->pid))
80 ++this->waiters_;
82 else
84 l->cancel ();
90 if (ImR_Locator_i::debug() > 4)
92 ORBSVCS_DEBUG ((LM_DEBUG,
93 ACE_TEXT ("(%P|%t) AsyncListManager(%@)::init_list, <%d> waiters")
94 ACE_TEXT (" out of <%d> registered servers\n"),
95 this, this->waiters_, len));
99 bool
100 AsyncListManager::make_iterator (ImplementationRepository::ServerInformationIterator_out si, CORBA::ULong start)
102 si = ImplementationRepository::ServerInformationIterator::_nil ();
105 ImR_AsyncIterator* imr_iter = 0;
106 ACE_NEW_THROW_EX (imr_iter,
107 ImR_AsyncIterator (start, this),
108 CORBA::NO_MEMORY ());
110 PortableServer::ServantBase_var tmp (imr_iter);
112 PortableServer::ObjectId_var id =
113 this->poa_->activate_object (imr_iter);
114 CORBA::Object_var obj = this->poa_->id_to_reference (id.in ());
115 si = ImplementationRepository::
116 ServerInformationIterator::_unchecked_narrow (obj.in ());
117 return true;
119 catch (const CORBA::SystemException& ex)
121 ex._tao_print_exception ("AsyncListManager:final state constructing iterator\n");
122 ImplementationRepository::AMH_AdministrationExceptionHolder h (ex._tao_duplicate());
125 this->primary_->list_excep (&h);
127 catch (const CORBA::Exception& ex2)
129 ex2._tao_print_exception ("AsyncListManager:final calling list_excep\n");
132 catch (const CORBA::UserException& ex)
134 ex._tao_print_exception ("AsyncListManager:final state constructing iterator\n");
135 ImplementationRepository::AMH_AdministrationExceptionHolder h (new CORBA::INTERNAL);
138 this->primary_->list_excep (&h);
140 catch (const CORBA::Exception& ex2)
142 ex2._tao_print_exception ("AsyncListManager:final calling list_excep\n");
145 return false;
148 void
149 AsyncListManager::final_state ()
151 if (ImR_Locator_i::debug() > 4)
153 ORBSVCS_DEBUG ((LM_DEBUG,
154 ACE_TEXT ("(%P|%t) AsyncListManager(%@)::final_state, ")
155 ACE_TEXT ("waiters count = %d, has pinger? %d\n"),
156 this, this->waiters_, (this->pinger_ != 0)));
159 if (this->pinger_ != 0 && this->waiters_ > 0)
161 return;
164 bool excepted = false;
165 CORBA::ULong const len = this->server_list_.length ();
166 ImplementationRepository::ServerInformationList alt_list (this->how_many_);
167 ImplementationRepository::ServerInformationList *sil = &this->server_list_;
168 if (this->first_ > 0 || this->how_many_ < len)
170 alt_list.length (this->how_many_);
171 for (CORBA::ULong i = 0; i < this->how_many_; i++)
173 alt_list[i] = this->server_list_[i + this->first_];
175 sil = &alt_list;
178 if (!CORBA::is_nil (this->primary_.in ()))
180 ImplementationRepository::ServerInformationIterator_var server_iterator;
181 if (sil != &this->server_list_)
183 excepted = !this->make_iterator (server_iterator.out(), this->how_many_);
185 else
187 server_iterator =
188 ImplementationRepository::ServerInformationIterator::_nil ();
191 if (!excepted)
195 this->primary_->list (*sil, server_iterator.in ());
197 catch (const CORBA::Exception &ex)
199 ex._tao_print_exception ("AsyncListManager:final state sending list\n");
200 ImplementationRepository::AMH_AdministrationExceptionHolder h (ex._tao_duplicate());
201 this->primary_->list_excep (&h);
204 this->primary_ =
205 ImplementationRepository::AMH_AdministrationResponseHandler::_nil ();
207 else if (!CORBA::is_nil (this->secondary_.in()))
209 CORBA::Boolean done = this->first_ + sil->length() == len;
212 this->secondary_->next_n (done, *sil);
214 catch (const CORBA::Exception &ex)
216 ex._tao_print_exception ("AsyncListManager:final state sending secondary list\n");
217 ImplementationRepository::AMH_ServerInformationIteratorExceptionHolder h (ex._tao_duplicate());
218 this->secondary_->next_n_excep (&h);
220 this->secondary_ =
221 ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_nil ();
225 CORBA::ULong
226 AsyncListManager::list
227 (ImplementationRepository::AMH_ServerInformationIteratorResponseHandler_ptr _tao_rh,
228 CORBA::ULong start,
229 CORBA::ULong count)
231 this->secondary_ =
232 ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_duplicate (_tao_rh);
233 this->list_i (start, count);
234 return this->first_ + this->how_many_;
237 void
238 AsyncListManager::list
239 (ImplementationRepository::AMH_AdministrationResponseHandler_ptr _tao_rh,
240 CORBA::ULong count)
242 this->primary_ =
243 ImplementationRepository::AMH_AdministrationResponseHandler::_duplicate (_tao_rh);
244 this->list_i (0, count);
247 void
248 AsyncListManager::list_i (CORBA::ULong start, CORBA::ULong count)
250 if (this->server_list_.length () == 0)
252 this->init_list ();
255 this->first_ = start;
256 this->how_many_ = this->server_list_.length () - start;
257 if (start > 0 || (count > 0 && count < this->how_many_))
259 if (count > 0 && count < this->how_many_)
261 this->how_many_ = count;
265 if (this->waiters_ == 0)
267 this->final_state ();
271 bool
272 AsyncListManager::evaluate_status (CORBA::ULong index, LiveStatus status, int pid)
274 bool is_final = true;
275 switch (status)
277 case LS_ALIVE:
278 case LS_LAST_TRANSIENT:
279 this->server_list_[index].activeStatus =
280 ImplementationRepository::ACTIVE_YES;
281 break;
282 case LS_TIMEDOUT:
283 this->server_list_[index].activeStatus =
284 ImplementationRepository::ACTIVE_MAYBE;
285 break;
286 case LS_DEAD:
287 this->server_list_[index].activeStatus = (pid == 0) ?
288 ImplementationRepository::ACTIVE_NO : ImplementationRepository::ACTIVE_MAYBE;
289 break;
290 default:
291 is_final = false;
293 return is_final;
296 void
297 AsyncListManager::ping_replied (CORBA::ULong index, LiveStatus status, int pid)
299 if (ImR_Locator_i::debug() > 4)
301 ORBSVCS_DEBUG ((LM_DEBUG,
302 ACE_TEXT ("(%P|%t) AsyncListManager(%@)::ping_replied, index <%d> ")
303 ACE_TEXT ("status <%C> server pid <%d> waiters <%d>\n"),
304 this,index, LiveEntry::status_name (status), pid, this->waiters_));
306 if (evaluate_status (index, status, pid))
308 if (--this->waiters_ == 0)
310 this->final_state ();
315 AsyncListManager *
316 AsyncListManager::_add_ref ()
318 ++this->refcount_;
319 return this;
322 void
323 AsyncListManager::_remove_ref ()
325 int const count = --this->refcount_;
327 if (count == 0)
329 delete this;
333 //---------------------------------------------------------------------------
334 //---------------------------------------------------------------------------
336 ListLiveListener::ListLiveListener (const char *server,
337 int pid,
338 CORBA::ULong index,
339 AsyncListManager *owner,
340 LiveCheck &pinger)
341 :LiveListener (server),
342 owner_ (owner->_add_ref ()),
343 pinger_ (pinger),
344 status_ (LS_UNKNOWN),
345 index_ (index),
346 started_ (false),
347 pid_ (pid)
351 ListLiveListener::~ListLiveListener ()
355 bool
356 ListLiveListener::start ()
358 bool const rtn = this->pinger_.add_poll_listener (this);
359 this->started_ = true;
360 return rtn;
363 LiveStatus
364 ListLiveListener::status ()
366 return this->status_;
369 void
370 ListLiveListener::cancel ()
372 this->pinger_.remove_listener (this);
375 bool
376 ListLiveListener::status_changed (LiveStatus status)
378 this->status_ = status;
379 if (status == LS_TRANSIENT)
381 return false;
383 else
385 if (this->started_)
387 this->owner_->ping_replied (this->index_, status, this->pid_);
390 return true;