// -*- C++ -*- // // $Id$ #include "AsyncStartupWaiter_i.h" #include "ImR_Locator_i.h" using namespace ImplementationRepository; AsyncStartupWaiter_i::PendingData::PendingData (const char* p, const char* i) : partial_ior (p) , ior( i) { } AsyncStartupWaiter_i::PendingData::PendingData () { } void AsyncStartupWaiter_i::debug (bool dbg) { debug_ = dbg; } void AsyncStartupWaiter_i::wait_for_startup (AMH_AsyncStartupWaiterResponseHandler_ptr rh, const char* name ACE_ENV_ARG_DECL_NOT_USED) ACE_THROW_SPEC ((CORBA::SystemException)) { PendingListPtr plst; pending_.find(name, plst); if (! plst.null () && plst->size () > 0) { PendingList& tmp = *plst; PendingData& pd = tmp[tmp.size () - 1]; tmp.pop_back (); if (debug_) ACE_DEBUG ((LM_DEBUG, "ImR: Skipping wait due to queued startup info for <%s>.\n", name)); send_response (*rh, name, pd.partial_ior.c_str(), pd.ior.c_str()); } else { RHListPtr lst; waiting_.find (name, lst); if (lst.null ()) { lst = RHListPtr (new RHList); int err = waiting_.bind (name, lst); ACE_ASSERT (err == 0); ACE_UNUSED_ARG (err); } lst->push_back (AMH_AsyncStartupWaiterResponseHandler::_duplicate (rh)); } } void AsyncStartupWaiter_i::send_response (ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler& rh, const char* name, const char* partial_ior, const char* ior) { StartupInfo_var si = new StartupInfo(); si->name = name; si->partial_ior = partial_ior; si->ior = ior; ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { rh.wait_for_startup (si.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY { if (debug_) ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AsyncStartupWaiter_i::send_response ()"); } ACE_ENDTRY; } void AsyncStartupWaiter_i::unblock_one (const char* name, const char* partial_ior, const char* ior, bool queue) { ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var rh = get_one_waiter(name); if (! CORBA::is_nil(rh.in ())) { send_response (*rh.in (), name, partial_ior, ior); } else if (queue) { if (debug_) ACE_DEBUG((LM_DEBUG, "ImR: Queuing startup info.\n")); PendingListPtr lst; pending_.find (name, lst); if (lst.null ()) { lst = PendingListPtr (new PendingList); int err = pending_.bind (name, lst); ACE_ASSERT (err == 0); ACE_UNUSED_ARG (err); } lst->push_back (PendingData (partial_ior, ior)); } } void AsyncStartupWaiter_i::unblock_all (const char* name) { RHList tmp; get_all_waiters (name, tmp); // This startup info should be ignored when unblocking all, because we // don't know the ior or partial_ior at this point. StartupInfo_var si = new StartupInfo (); si->name = name; // Note : This method may be called when there are no waiters. for (size_t i = 0; i < tmp.size(); ++i) { ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var& rh = tmp[i]; rh->wait_for_startup (si.in () ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY { if (debug_) ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "AsyncStartupWaiter_i::unblock_all ()"); } ACE_ENDTRY; } } ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr AsyncStartupWaiter_i::get_one_waiter (const char* name) { RHListPtr lst; waiting_.find (name, lst); if (! lst.null() && lst->size () > 0) { RHList& rhlst = *lst; ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_var& tmp = rhlst[rhlst.size () - 1]; ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler_ptr ret = tmp._retn (); rhlst.pop_back (); return ret; } return ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler::_nil (); } void AsyncStartupWaiter_i::get_all_waiters (const char* name, RHList& ret) { RHListPtr lst; waiting_.find (name, lst); if (! lst.null ()) { for (size_t i = 0; i < lst->size (); ++i) { RHList& tmp = *lst; ret.push_back (tmp[i]); // The ACE_Vector will not destruct the elements when cleared, so we must // make sure to do so here. tmp[i] = ImplementationRepository::AMH_AsyncStartupWaiterResponseHandler::_nil (); } lst->clear (); } }