2 #include "AsyncListManager.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
,
16 poa_ (PortableServer::POA::_duplicate (poa
)),
17 primary_ (ImplementationRepository::AMH_AdministrationResponseHandler::_nil ()),
18 secondary_ (ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_nil ()),
28 AsyncListManager::~AsyncListManager ()
30 if (ImR_Locator_i::debug() > 4)
32 ORBSVCS_DEBUG ((LM_DEBUG
,
33 ACE_TEXT ("(%P|%t) AsyncListManager(%@)::dtor\n"),
38 PortableServer::POA_ptr
39 AsyncListManager::poa ()
41 return PortableServer::POA::_duplicate (this->poa_
.in());
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
);
53 for (CORBA::ULong i
= 0; i
< len
; i
++)
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 (),
69 LiveListener_ptr
llp (l
);
72 this->server_list_
[i
].activeStatus
=
73 ImplementationRepository::ACTIVE_NO
;
78 if (!evaluate_status (i
, l
->status(), info
->pid
))
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
));
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 ());
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");
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)
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_
];
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_
);
188 ImplementationRepository::ServerInformationIterator::_nil ();
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
);
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
);
221 ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_nil ();
226 AsyncListManager::list
227 (ImplementationRepository::AMH_ServerInformationIteratorResponseHandler_ptr _tao_rh
,
232 ImplementationRepository::AMH_ServerInformationIteratorResponseHandler::_duplicate (_tao_rh
);
233 this->list_i (start
, count
);
234 return this->first_
+ this->how_many_
;
238 AsyncListManager::list
239 (ImplementationRepository::AMH_AdministrationResponseHandler_ptr _tao_rh
,
243 ImplementationRepository::AMH_AdministrationResponseHandler::_duplicate (_tao_rh
);
244 this->list_i (0, count
);
248 AsyncListManager::list_i (CORBA::ULong start
, CORBA::ULong count
)
250 if (this->server_list_
.length () == 0)
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 ();
272 AsyncListManager::evaluate_status (CORBA::ULong index
, LiveStatus status
, int pid
)
274 bool is_final
= true;
278 case LS_LAST_TRANSIENT
:
279 this->server_list_
[index
].activeStatus
=
280 ImplementationRepository::ACTIVE_YES
;
283 this->server_list_
[index
].activeStatus
=
284 ImplementationRepository::ACTIVE_MAYBE
;
287 this->server_list_
[index
].activeStatus
= (pid
== 0) ?
288 ImplementationRepository::ACTIVE_NO
: ImplementationRepository::ACTIVE_MAYBE
;
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 ();
316 AsyncListManager::_add_ref ()
323 AsyncListManager::_remove_ref ()
325 int const count
= --this->refcount_
;
333 //---------------------------------------------------------------------------
334 //---------------------------------------------------------------------------
336 ListLiveListener::ListLiveListener (const char *server
,
339 AsyncListManager
*owner
,
341 :LiveListener (server
),
342 owner_ (owner
->_add_ref ()),
344 status_ (LS_UNKNOWN
),
351 ListLiveListener::~ListLiveListener ()
356 ListLiveListener::start ()
358 bool const rtn
= this->pinger_
.add_poll_listener (this);
359 this->started_
= true;
364 ListLiveListener::status ()
366 return this->status_
;
370 ListLiveListener::cancel ()
372 this->pinger_
.remove_listener (this);
376 ListLiveListener::status_changed (LiveStatus status
)
378 this->status_
= status
;
379 if (status
== LS_TRANSIENT
)
387 this->owner_
->ping_replied (this->index_
, status
, this->pid_
);