// // Copyright (c) ZeroC, Inc. All rights reserved. // #include #include #include #include #include #include using namespace std; using namespace Ice; using namespace IceInternal; #ifndef ICE_CPP11_MAPPING IceUtil::Shared* IceInternal::upCast(ObjectAdapterFactory* p) { return p; } #endif void IceInternal::ObjectAdapterFactory::shutdown() { list adapters; { IceUtil::Monitor::Lock sync(*this); // // Ignore shutdown requests if the object adapter factory has // already been shut down. // if(!_instance) { return; } adapters = _adapters; _instance = ICE_NULLPTR; _communicator = ICE_NULLPTR; notifyAll(); } // // Deactivate outside the thread synchronization, to avoid // deadlocks. // #ifdef ICE_CPP11_MAPPING for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->deactivate(); }); #else for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::deactivate)); #endif } void IceInternal::ObjectAdapterFactory::waitForShutdown() { list adapters; { IceUtil::Monitor::Lock sync(*this); // // First we wait for the shutdown of the factory itself. // while(_instance) { wait(); } adapters = _adapters; } // // Now we wait for deactivation of each object adapter. // #ifdef ICE_CPP11_MAPPING for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->waitForDeactivate(); }); #else for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::waitForDeactivate)); #endif } bool IceInternal::ObjectAdapterFactory::isShutdown() const { IceUtil::Monitor::Lock sync(*this); return _instance == 0; } void IceInternal::ObjectAdapterFactory::destroy() { // // First wait for shutdown to finish. // waitForShutdown(); list adapters; { IceUtil::Monitor::Lock sync(*this); adapters = _adapters; } // // Now we destroy each object adapter. // #ifdef ICE_CPP11_MAPPING for_each(adapters.begin(), adapters.end(), [](const ObjectAdapterIPtr& adapter) { adapter->destroy(); }); #else for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(&ObjectAdapter::destroy)); #endif { IceUtil::Monitor::Lock sync(*this); _adapters.clear(); } } void IceInternal::ObjectAdapterFactory::updateObservers(void (ObjectAdapterI::*fn)()) { list adapters; { IceUtil::Monitor::Lock sync(*this); adapters = _adapters; } #ifdef ICE_CPP11_MAPPING for_each(adapters.begin(), adapters.end(), [fn](const ObjectAdapterIPtr& adapter) { (adapter.get() ->* fn)(); }); #else for_each(adapters.begin(), adapters.end(), IceUtil::voidMemFun(fn)); #endif } ObjectAdapterPtr IceInternal::ObjectAdapterFactory::createObjectAdapter(const string& name, const RouterPrxPtr& router) { ObjectAdapterIPtr adapter; { IceUtil::Monitor::Lock sync(*this); if(!_instance) { throw CommunicatorDestroyedException(__FILE__, __LINE__); } if(name.empty()) { string uuid = Ice::generateUUID(); adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true); } else { if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end()) { throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name); } adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false); _adapterNamesInUse.insert(name); } } // // Must be called outside the synchronization since initialize can make client invocations // on the router if it's set. // bool initialized = false; try { adapter->initialize(router); initialized = true; IceUtil::Monitor::Lock sync(*this); if(!_instance) { throw CommunicatorDestroyedException(__FILE__, __LINE__); } _adapters.push_back(adapter); } catch(const Ice::CommunicatorDestroyedException&) { if(initialized) { adapter->destroy(); } throw; } catch(const std::exception&) { if(!name.empty()) { IceUtil::Monitor::Lock sync(*this); _adapterNamesInUse.erase(name); } throw; } return adapter; } ObjectAdapterPtr IceInternal::ObjectAdapterFactory::findObjectAdapter(const ObjectPrxPtr& proxy) { list adapters; { IceUtil::Monitor::Lock sync(*this); if(!_instance) { return ICE_NULLPTR; } adapters = _adapters; } for(list::iterator p = adapters.begin(); p != adapters.end(); ++p) { try { if((*p)->isLocal(proxy)) { return *p; } } catch(const ObjectAdapterDeactivatedException&) { // Ignore. } } return ICE_NULLPTR; } void IceInternal::ObjectAdapterFactory::removeObjectAdapter(const ObjectAdapterPtr& adapter) { IceUtil::Monitor::Lock sync(*this); if(!_instance) { return; } for(list::iterator p = _adapters.begin(); p != _adapters.end(); ++p) { if(*p == adapter) { _adapters.erase(p); break; } } _adapterNamesInUse.erase(adapter->getName()); } void IceInternal::ObjectAdapterFactory::flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr& outAsync, CompressBatch compressBatch) const { list adapters; { IceUtil::Monitor::Lock sync(*this); adapters = _adapters; } for(list::const_iterator p = adapters.begin(); p != adapters.end(); ++p) { (*p)->flushAsyncBatchRequests(outAsync, compressBatch); } } IceInternal::ObjectAdapterFactory::ObjectAdapterFactory(const InstancePtr& instance, const CommunicatorPtr& communicator) : _instance(instance), _communicator(communicator) { } IceInternal::ObjectAdapterFactory::~ObjectAdapterFactory() { assert(!_instance); assert(!_communicator); assert(_adapters.empty()); }