ICE 3.4.2
[php5-ice-freebsdport.git] / cpp / src / Ice / ObjectAdapterI.cpp
bloba9ef07a6806c58c0534c2c64e7978e9db96afaf5
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 #include <IceUtil/UUID.h>
11 #include <Ice/ObjectAdapterI.h>
12 #include <Ice/ObjectAdapterFactory.h>
13 #include <Ice/Instance.h>
14 #include <Ice/ConnectionMonitor.h>
15 #include <Ice/Proxy.h>
16 #include <Ice/ProxyFactory.h>
17 #include <Ice/ReferenceFactory.h>
18 #include <Ice/EndpointI.h>
19 #include <Ice/EndpointFactoryManager.h>
20 #include <Ice/ConnectionFactory.h>
21 #include <Ice/ServantManager.h>
22 #include <Ice/RouterInfo.h>
23 #include <Ice/LocalException.h>
24 #include <Ice/Properties.h>
25 #include <Ice/Functional.h>
26 #include <Ice/LocatorInfo.h>
27 #include <Ice/Locator.h>
28 #include <Ice/LoggerUtil.h>
29 #include <Ice/ThreadPool.h>
30 #include <Ice/Communicator.h>
31 #include <Ice/Router.h>
32 #include <Ice/DefaultsAndOverrides.h>
33 #include <Ice/TraceLevels.h>
34 #include <Ice/PropertyNames.h>
36 #ifdef _WIN32
37 # include <sys/timeb.h>
38 #else
39 # include <sys/time.h>
40 #endif
42 #include <iterator>
44 using namespace std;
45 using namespace Ice;
46 using namespace IceInternal;
48 string
49 Ice::ObjectAdapterI::getName() const
52 // No mutex lock necessary, _name is immutable.
54 return _noConfig ? string("") : _name;
57 CommunicatorPtr
58 Ice::ObjectAdapterI::getCommunicator() const
60 return _communicator;
63 void
64 Ice::ObjectAdapterI::activate()
66 LocatorInfoPtr locatorInfo;
67 bool registerProcess = false;
68 bool printAdapterReady = false;
71 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
73 checkForDeactivation();
76 // If some threads are waiting on waitForHold(), we set this
77 // flag to ensure the threads will start again the wait for
78 // all the incoming connection factories.
80 _waitForHoldRetry = _waitForHold > 0;
83 // If the one off initializations of the adapter are already
84 // done, we just need to activate the incoming connection
85 // factories and we're done.
87 if(_activateOneOffDone)
89 for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
90 Ice::voidMemFun(&IncomingConnectionFactory::activate));
91 return;
95 // One off initializations of the adapter: update the locator
96 // registry and print the "adapter ready" message. We set the
97 // _waitForActivate flag to prevent deactivation from other
98 // threads while these one off initializations are done.
100 _waitForActivate = true;
102 locatorInfo = _locatorInfo;
103 if(!_noConfig)
105 PropertiesPtr properties = _instance->initializationData().properties;
106 printAdapterReady = properties->getPropertyAsInt("Ice.PrintAdapterReady") > 0;
107 registerProcess = properties->getPropertyAsInt(_name + ".RegisterProcess") > 0;
113 Ice::Identity dummy;
114 dummy.name = "dummy";
115 updateLocatorRegistry(locatorInfo, createDirectProxy(dummy), registerProcess);
117 catch(const Ice::LocalException&)
120 // If we couldn't update the locator registry, we let the
121 // exception go through and don't activate the adapter to
122 // allow to user code to retry activating the adapter
123 // later.
126 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
127 _waitForActivate = false;
128 notifyAll();
130 throw;
133 if(printAdapterReady)
135 cout << _name << " ready" << endl;
139 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
140 assert(!_deactivated); // Not possible if _waitForActivate = true;
143 // Signal threads waiting for the activation.
145 _waitForActivate = false;
146 notifyAll();
148 _activateOneOffDone = true;
150 for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
151 Ice::voidMemFun(&IncomingConnectionFactory::activate));
155 void
156 Ice::ObjectAdapterI::hold()
158 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
160 checkForDeactivation();
162 for_each(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
163 Ice::voidMemFun(&IncomingConnectionFactory::hold));
166 void
167 Ice::ObjectAdapterI::waitForHold()
169 while(true)
171 vector<IncomingConnectionFactoryPtr> incomingConnectionFactories;
173 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
175 checkForDeactivation();
177 incomingConnectionFactories = _incomingConnectionFactories;
179 ++_waitForHold;
182 for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(),
183 Ice::constVoidMemFun(&IncomingConnectionFactory::waitUntilHolding));
186 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
187 if(--_waitForHold == 0)
189 notifyAll();
193 // If we don't need to retry, we're done. Otherwise, we wait until
194 // all the waiters finish waiting on the connections and we try
195 // again waiting on all the conncetions. This is necessary in the
196 // case activate() is called by another thread while waitForHold()
197 // waits on the some connection, if we didn't retry, waitForHold()
198 // could return only after waiting on a subset of the connections.
200 if(!_waitForHoldRetry)
202 return;
204 else
206 while(_waitForHold > 0)
208 checkForDeactivation();
209 wait();
211 _waitForHoldRetry = false;
217 void
218 Ice::ObjectAdapterI::deactivate()
220 vector<IncomingConnectionFactoryPtr> incomingConnectionFactories;
221 OutgoingConnectionFactoryPtr outgoingConnectionFactory;
222 LocatorInfoPtr locatorInfo;
224 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
227 // Ignore deactivation requests if the object adapter has already
228 // been deactivated.
230 if(_deactivated)
232 return;
236 // Wait for activation to complete. This is necessary to not
237 // get out of order locator updates.
239 while(_waitForActivate)
241 wait();
244 if(_routerInfo)
247 // Remove entry from the router manager.
249 _instance->routerManager()->erase(_routerInfo->getRouter());
252 // Clear this object adapter with the router.
254 _routerInfo->setAdapter(0);
257 incomingConnectionFactories = _incomingConnectionFactories;
258 outgoingConnectionFactory = _instance->outgoingConnectionFactory();
259 locatorInfo = _locatorInfo;
261 _deactivated = true;
263 notifyAll();
268 updateLocatorRegistry(locatorInfo, 0, false);
270 catch(const Ice::LocalException&)
273 // We can't throw exceptions in deactivate so we ignore
274 // failures to update the locator registry.
279 // Must be called outside the thread synchronization, because
280 // Connection::destroy() might block when sending a CloseConnection
281 // message.
283 for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(),
284 Ice::voidMemFun(&IncomingConnectionFactory::destroy));
287 // Must be called outside the thread synchronization, because
288 // changing the object adapter might block if there are still
289 // requests being dispatched.
291 outgoingConnectionFactory->removeAdapter(this);
294 void
295 Ice::ObjectAdapterI::waitForDeactivate()
297 vector<IceInternal::IncomingConnectionFactoryPtr> incomingConnectionFactories;
300 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
301 if(_destroyed)
303 return;
307 // Wait for deactivation of the adapter itself, and for
308 // the return of all direct method calls using this adapter.
310 while(!_deactivated || _directCount > 0)
312 wait();
315 incomingConnectionFactories = _incomingConnectionFactories;
319 // Now we wait until all incoming connection factories are
320 // finished.
322 for_each(incomingConnectionFactories.begin(), incomingConnectionFactories.end(),
323 Ice::voidMemFun(&IncomingConnectionFactory::waitUntilFinished));
326 bool
327 Ice::ObjectAdapterI::isDeactivated() const
329 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
331 return _deactivated;
334 void
335 Ice::ObjectAdapterI::destroy()
338 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
341 // Another thread is in the process of destroying the object
342 // adapter. Wait for it to finish.
344 while(_destroying)
346 wait();
350 // Object adapter is already destroyed.
352 if(_destroyed)
354 return;
357 _destroying = true;
361 // Deactivate and wait for completion.
363 deactivate();
364 waitForDeactivate();
367 // Now it's also time to clean up our servants and servant
368 // locators.
370 _servantManager->destroy();
373 // Destroy the thread pool.
375 if(_threadPool)
377 _threadPool->destroy();
378 _threadPool->joinWithAllThreads();
381 ObjectAdapterFactoryPtr objectAdapterFactory;
384 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
387 // Signal that destroy is complete.
389 _destroying = false;
390 _destroyed = true;
391 notifyAll();
394 // We're done, now we can throw away all incoming connection
395 // factories.
397 _incomingConnectionFactories.clear();
400 // Remove object references (some of them cyclic).
402 _instance = 0;
403 _threadPool = 0;
404 _routerEndpoints.clear();
405 _routerInfo = 0;
406 _publishedEndpoints.clear();
407 _locatorInfo = 0;
408 _reference = 0;
410 objectAdapterFactory = _objectAdapterFactory;
411 _objectAdapterFactory = 0;
414 if(objectAdapterFactory)
416 objectAdapterFactory->removeObjectAdapter(this);
420 ObjectPrx
421 Ice::ObjectAdapterI::add(const ObjectPtr& object, const Identity& ident)
423 return addFacet(object, ident, "");
426 ObjectPrx
427 Ice::ObjectAdapterI::addFacet(const ObjectPtr& object, const Identity& ident, const string& facet)
429 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
431 checkForDeactivation();
432 checkIdentity(ident);
434 _servantManager->addServant(object, ident, facet);
436 return newProxy(ident, facet);
439 ObjectPrx
440 Ice::ObjectAdapterI::addWithUUID(const ObjectPtr& object)
442 return addFacetWithUUID(object, "");
445 ObjectPrx
446 Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr& object, const string& facet)
448 Identity ident;
449 ident.name = IceUtil::generateUUID();
450 return addFacet(object, ident, facet);
453 void
454 Ice::ObjectAdapterI::addDefaultServant(const ObjectPtr& servant, const string& category)
456 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
458 checkForDeactivation();
460 _servantManager->addDefaultServant(servant, category);
463 ObjectPtr
464 Ice::ObjectAdapterI::remove(const Identity& ident)
466 return removeFacet(ident, "");
469 ObjectPtr
470 Ice::ObjectAdapterI::removeFacet(const Identity& ident, const string& facet)
472 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
474 checkForDeactivation();
475 checkIdentity(ident);
477 return _servantManager->removeServant(ident, facet);
480 FacetMap
481 Ice::ObjectAdapterI::removeAllFacets(const Identity& ident)
483 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
485 checkForDeactivation();
486 checkIdentity(ident);
488 return _servantManager->removeAllFacets(ident);
491 ObjectPtr
492 Ice::ObjectAdapterI::removeDefaultServant(const string& category)
494 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
496 checkForDeactivation();
498 return _servantManager->removeDefaultServant(category);
501 ObjectPtr
502 Ice::ObjectAdapterI::find(const Identity& ident) const
504 return findFacet(ident, "");
507 ObjectPtr
508 Ice::ObjectAdapterI::findFacet(const Identity& ident, const string& facet) const
510 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
512 checkForDeactivation();
513 checkIdentity(ident);
515 return _servantManager->findServant(ident, facet);
518 FacetMap
519 Ice::ObjectAdapterI::findAllFacets(const Identity& ident) const
521 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
523 checkForDeactivation();
524 checkIdentity(ident);
526 return _servantManager->findAllFacets(ident);
529 ObjectPtr
530 Ice::ObjectAdapterI::findByProxy(const ObjectPrx& proxy) const
532 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
534 checkForDeactivation();
536 ReferencePtr ref = proxy->__reference();
537 return findFacet(ref->getIdentity(), ref->getFacet());
540 ObjectPtr
541 Ice::ObjectAdapterI::findDefaultServant(const string& category) const
543 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
545 checkForDeactivation();
547 return _servantManager->findDefaultServant(category);
550 void
551 Ice::ObjectAdapterI::addServantLocator(const ServantLocatorPtr& locator, const string& prefix)
553 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
555 checkForDeactivation();
557 _servantManager->addServantLocator(locator, prefix);
560 ServantLocatorPtr
561 Ice::ObjectAdapterI::removeServantLocator(const string& prefix)
563 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
565 checkForDeactivation();
567 return _servantManager->removeServantLocator(prefix);
570 ServantLocatorPtr
571 Ice::ObjectAdapterI::findServantLocator(const string& prefix) const
573 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
575 checkForDeactivation();
577 return _servantManager->findServantLocator(prefix);
580 ObjectPrx
581 Ice::ObjectAdapterI::createProxy(const Identity& ident) const
583 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
585 checkForDeactivation();
586 checkIdentity(ident);
588 return newProxy(ident, "");
591 ObjectPrx
592 Ice::ObjectAdapterI::createDirectProxy(const Identity& ident) const
594 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
596 checkForDeactivation();
597 checkIdentity(ident);
599 return newDirectProxy(ident, "");
602 ObjectPrx
603 Ice::ObjectAdapterI::createIndirectProxy(const Identity& ident) const
605 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
607 checkForDeactivation();
608 checkIdentity(ident);
610 return newIndirectProxy(ident, "", _id);
613 void
614 Ice::ObjectAdapterI::setLocator(const LocatorPrx& locator)
616 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
618 checkForDeactivation();
620 _locatorInfo = _instance->locatorManager()->get(locator);
623 void
624 Ice::ObjectAdapterI::refreshPublishedEndpoints()
626 LocatorInfoPtr locatorInfo;
627 bool registerProcess = false;
628 vector<EndpointIPtr> oldPublishedEndpoints;
631 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
633 checkForDeactivation();
635 oldPublishedEndpoints = _publishedEndpoints;
636 _publishedEndpoints = parsePublishedEndpoints();
638 locatorInfo = _locatorInfo;
639 if(!_noConfig)
641 registerProcess =
642 _instance->initializationData().properties->getPropertyAsInt(_name + ".RegisterProcess") > 0;
648 Ice::Identity dummy;
649 dummy.name = "dummy";
650 updateLocatorRegistry(locatorInfo, createDirectProxy(dummy), registerProcess);
652 catch(const Ice::LocalException&)
654 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
657 // Restore the old published endpoints.
659 _publishedEndpoints = oldPublishedEndpoints;
660 throw;
664 EndpointSeq
665 Ice::ObjectAdapterI::getEndpoints() const
667 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
669 EndpointSeq endpoints;
670 transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(),
671 back_inserter(endpoints), Ice::constMemFun(&IncomingConnectionFactory::endpoint));
672 return endpoints;
675 EndpointSeq
676 Ice::ObjectAdapterI::getPublishedEndpoints() const
678 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
680 EndpointSeq endpoints;
681 copy(_publishedEndpoints.begin(), _publishedEndpoints.end(), back_inserter(endpoints));
682 return endpoints;
685 bool
686 Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const
689 // NOTE: it's important that isLocal() doesn't perform any blocking operations as
690 // it can be called for AMI invocations if the proxy has no delegate set yet.
693 ReferencePtr ref = proxy->__reference();
694 if(ref->isWellKnown())
697 // Check the active servant map to see if the well-known
698 // proxy is for a local object.
700 return _servantManager->hasServant(ref->getIdentity());
702 else if(ref->isIndirect())
705 // Proxy is local if the reference adapter id matches this
706 // adapter id or replica group id.
708 return ref->getAdapterId() == _id || ref->getAdapterId() == _replicaGroupId;
710 else
712 vector<EndpointIPtr> endpoints = ref->getEndpoints();
714 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
715 checkForDeactivation();
718 // Proxies which have at least one endpoint in common with the
719 // endpoints used by this object adapter are considered local.
721 vector<EndpointIPtr>::const_iterator p;
722 for(p = endpoints.begin(); p != endpoints.end(); ++p)
724 vector<IncomingConnectionFactoryPtr>::const_iterator q;
725 for(q = _incomingConnectionFactories.begin(); q != _incomingConnectionFactories.end(); ++q)
727 if((*p)->equivalent((*q)->endpoint()))
729 return true;
732 vector<EndpointIPtr>::const_iterator r;
733 for(r = _publishedEndpoints.begin(); r != _publishedEndpoints.end(); ++r)
735 if((*p)->equivalent(*r))
737 return true;
743 // Proxies which have at least one endpoint in common with the
744 // router's server proxy endpoints (if any), are also considered
745 // local.
747 if(_routerInfo && _routerInfo->getRouter() == proxy->ice_getRouter())
749 for(p = endpoints.begin(); p != endpoints.end(); ++p)
751 vector<EndpointIPtr>::const_iterator r;
752 for(r = _routerEndpoints.begin(); r != _routerEndpoints.end(); ++r)
754 if((*p)->equivalent(*r))
756 return true;
763 return false;
766 void
767 Ice::ObjectAdapterI::flushAsyncBatchRequests(const CommunicatorBatchOutgoingAsyncPtr& outAsync)
769 vector<IncomingConnectionFactoryPtr> f;
771 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
772 f = _incomingConnectionFactories;
775 for(vector<IncomingConnectionFactoryPtr>::const_iterator p = f.begin(); p != f.end(); ++p)
777 (*p)->flushAsyncBatchRequests(outAsync);
781 void
782 Ice::ObjectAdapterI::incDirectCount()
784 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
786 checkForDeactivation();
788 assert(_directCount >= 0);
789 ++_directCount;
792 void
793 Ice::ObjectAdapterI::decDirectCount()
795 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
797 // Not check for deactivation here!
799 assert(_instance); // Must not be called after destroy().
801 assert(_directCount > 0);
802 if(--_directCount == 0)
804 notifyAll();
808 ThreadPoolPtr
809 Ice::ObjectAdapterI::getThreadPool() const
811 // No mutex lock necessary, _threadPool and _instance are
812 // immutable after creation until they are removed in
813 // destroy().
815 // Not check for deactivation here!
817 assert(_instance); // Must not be called after destroy().
819 if(_threadPool)
821 return _threadPool;
823 else
825 return _instance->serverThreadPool();
829 ServantManagerPtr
830 Ice::ObjectAdapterI::getServantManager() const
833 // No mutex lock necessary, _servantManager is immutable.
835 return _servantManager;
838 Ice::Int
839 Ice::ObjectAdapterI::getACM() const
841 // Not check for deactivation here!
843 assert(_instance); // Must not be called after destroy().
845 if(_hasAcmTimeout)
847 return _acmTimeout;
849 else
851 return _instance->serverACM();
856 // COMPILERFIX: The ObjectAdapterI setup is broken out into a separate initialize
857 // function because when it was part of the constructor C++Builder 2010 apps would
858 // crash if an execption was thrown from any calls within the constructor.
860 Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const CommunicatorPtr& communicator,
861 const ObjectAdapterFactoryPtr& objectAdapterFactory, const string& name,
862 /*const RouterPrx& router,*/ bool noConfig) :
863 _deactivated(false),
864 _instance(instance),
865 _communicator(communicator),
866 _objectAdapterFactory(objectAdapterFactory),
867 _hasAcmTimeout(false),
868 _acmTimeout(0),
869 _servantManager(new ServantManager(instance, name)),
870 _activateOneOffDone(false),
871 _name(name),
872 _directCount(0),
873 _waitForActivate(false),
874 _waitForHold(0),
875 _waitForHoldRetry(false),
876 _destroying(false),
877 _destroyed(false),
878 _noConfig(noConfig)
882 void
883 Ice::ObjectAdapterI::initialize(const RouterPrx& router)
885 if(_noConfig)
887 _reference = _instance->referenceFactory()->create("dummy -t", "");
888 return;
891 PropertiesPtr properties = _instance->initializationData().properties;
892 StringSeq unknownProps;
893 bool noProps = filterProperties(unknownProps);
896 // Warn about unknown object adapter properties.
898 if(unknownProps.size() != 0 && properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0)
900 Warning out(_instance->initializationData().logger);
901 out << "found unknown properties for object adapter `" << _name << "':";
902 for(unsigned int i = 0; i < unknownProps.size(); ++i)
904 out << "\n " << unknownProps[i];
911 // Make sure named adapter has some configuration
913 if(router == 0 && noProps)
915 InitializationException ex(__FILE__, __LINE__);
916 ex.reason = "object adapter `" + _name + "' requires configuration";
917 throw ex;
920 const_cast<string&>(_id) = properties->getProperty(_name + ".AdapterId");
921 const_cast<string&>(_replicaGroupId) = properties->getProperty(_name + ".ReplicaGroupId");
924 // Setup a reference to be used to get the default proxy options
925 // when creating new proxies. By default, create twoway proxies.
927 string proxyOptions = properties->getPropertyWithDefault(_name + ".ProxyOptions", "-t");
930 _reference = _instance->referenceFactory()->create("dummy " + proxyOptions, "");
932 catch(const ProxyParseException&)
934 InitializationException ex(__FILE__, __LINE__);
935 ex.reason = "invalid proxy options `" + proxyOptions + "' for object adapter `" + _name + "'";
936 throw ex;
939 int threadPoolSize = properties->getPropertyAsInt(_name + ".ThreadPool.Size");
940 int threadPoolSizeMax = properties->getPropertyAsInt(_name + ".ThreadPool.SizeMax");
941 bool hasPriority = properties->getProperty(_name + ".ThreadPool.ThreadPriority") != "";
944 // Create the per-adapter thread pool, if necessary. This is done before the creation of the incoming
945 // connection factory as the thread pool is needed during creation for the call to incFdsInUse.
947 if(threadPoolSize > 0 || threadPoolSizeMax > 0 || hasPriority)
949 _threadPool = new ThreadPool(_instance, _name + ".ThreadPool", 0);
952 _hasAcmTimeout = properties->getProperty(_name + ".ACM") != "";
953 if(_hasAcmTimeout)
955 _acmTimeout = properties->getPropertyAsInt(_name + ".ACM");
956 _instance->connectionMonitor()->checkIntervalForACM(_acmTimeout);
959 if(!router)
961 const_cast<RouterPrx&>(router) = RouterPrx::uncheckedCast(
962 _instance->proxyFactory()->propertyToProxy(_name + ".Router"));
964 if(router)
966 _routerInfo = _instance->routerManager()->get(router);
967 if(_routerInfo)
970 // Make sure this router is not already registered with another adapter.
972 if(_routerInfo->getAdapter())
974 throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter with router",
975 _instance->identityToString(router->ice_getIdentity()));
979 // Add the router's server proxy endpoints to this object
980 // adapter.
982 vector<EndpointIPtr> endpoints = _routerInfo->getServerEndpoints();
983 copy(endpoints.begin(), endpoints.end(), back_inserter(_routerEndpoints));
984 sort(_routerEndpoints.begin(), _routerEndpoints.end()); // Must be sorted.
985 _routerEndpoints.erase(unique(_routerEndpoints.begin(), _routerEndpoints.end()),
986 _routerEndpoints.end());
989 // Associate this object adapter with the router. This way,
990 // new outgoing connections to the router's client proxy will
991 // use this object adapter for callbacks.
993 _routerInfo->setAdapter(this);
996 // Also modify all existing outgoing connections to the
997 // router's client proxy to use this object adapter for
998 // callbacks.
1000 _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo);
1003 else
1006 // Parse the endpoints, but don't store them in the adapter.
1007 // The connection factory might change it, for example, to
1008 // fill in the real port number.
1010 vector<EndpointIPtr> endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"), true);
1011 for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p)
1014 IncomingConnectionFactoryPtr factory = new IncomingConnectionFactory(_instance, *p, this);
1015 factory->initialize(_name);
1016 _incomingConnectionFactories.push_back(factory);
1019 if(endpoints.empty())
1021 TraceLevelsPtr tl = _instance->traceLevels();
1022 if(tl->network >= 2)
1024 Trace out(_instance->initializationData().logger, tl->networkCat);
1025 out << "created adapter `" << _name << "' without endpoints";
1030 // Parse the published endpoints.
1032 _publishedEndpoints = parsePublishedEndpoints();
1035 if(!properties->getProperty(_name + ".Locator").empty())
1037 setLocator(LocatorPrx::uncheckedCast(_instance->proxyFactory()->propertyToProxy(_name + ".Locator")));
1039 else
1041 setLocator(_instance->referenceFactory()->getDefaultLocator());
1044 catch(...)
1046 destroy();
1047 throw;
1051 Ice::ObjectAdapterI::~ObjectAdapterI()
1053 if(!_deactivated)
1055 Warning out(_instance->initializationData().logger);
1056 out << "object adapter `" << getName() << "' has not been deactivated";
1058 else if(!_destroyed)
1060 Warning out(_instance->initializationData().logger);
1061 out << "object adapter `" << getName() << "' has not been destroyed";
1063 else
1065 //assert(!_servantManager); // We don't clear this reference, it needs to be immutable.
1066 assert(!_threadPool);
1067 assert(_incomingConnectionFactories.empty());
1068 assert(_directCount == 0);
1069 assert(!_waitForActivate);
1073 ObjectPrx
1074 Ice::ObjectAdapterI::newProxy(const Identity& ident, const string& facet) const
1076 if(_id.empty())
1078 return newDirectProxy(ident, facet);
1080 else if(_replicaGroupId.empty())
1082 return newIndirectProxy(ident, facet, _id);
1084 else
1086 return newIndirectProxy(ident, facet, _replicaGroupId);
1090 ObjectPrx
1091 Ice::ObjectAdapterI::newDirectProxy(const Identity& ident, const string& facet) const
1093 vector<EndpointIPtr> endpoints = _publishedEndpoints;
1096 // Now we also add the endpoints of the router's server proxy, if
1097 // any. This way, object references created by this object adapter
1098 // will also point to the router's server proxy endpoints.
1100 copy(_routerEndpoints.begin(), _routerEndpoints.end(), back_inserter(endpoints));
1103 // Create a reference and return a proxy for this reference.
1105 ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, endpoints);
1106 return _instance->proxyFactory()->referenceToProxy(ref);
1109 ObjectPrx
1110 Ice::ObjectAdapterI::newIndirectProxy(const Identity& ident, const string& facet, const string& id) const
1113 // Create an indirect reference with the given adapter id.
1115 ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, id);
1118 // Return a proxy for the reference.
1120 return _instance->proxyFactory()->referenceToProxy(ref);
1123 void
1124 Ice::ObjectAdapterI::checkForDeactivation() const
1126 if(_deactivated)
1128 ObjectAdapterDeactivatedException ex(__FILE__, __LINE__);
1129 ex.name = getName();
1130 throw ex;
1134 void
1135 Ice::ObjectAdapterI::checkIdentity(const Identity& ident)
1137 if(ident.name.size() == 0)
1139 IllegalIdentityException e(__FILE__, __LINE__);
1140 e.id = ident;
1141 throw e;
1145 vector<EndpointIPtr>
1146 Ice::ObjectAdapterI::parseEndpoints(const string& endpts, bool oaEndpoints) const
1148 string::size_type beg;
1149 string::size_type end = 0;
1151 vector<EndpointIPtr> endpoints;
1152 while(end < endpts.length())
1154 const string delim = " \t\n\r";
1156 beg = endpts.find_first_not_of(delim, end);
1157 if(beg == string::npos)
1159 break;
1162 end = beg;
1163 while(true)
1165 end = endpts.find(':', end);
1166 if(end == string::npos)
1168 end = endpts.length();
1169 break;
1171 else
1173 bool quoted = false;
1174 string::size_type quote = beg;
1175 while(true)
1177 quote = endpts.find('\"', quote);
1178 if(quote == string::npos || end < quote)
1180 break;
1182 else
1184 quote = endpts.find('\"', ++quote);
1185 if(quote == string::npos)
1187 break;
1189 else if(end < quote)
1191 quoted = true;
1192 break;
1194 ++quote;
1197 if(!quoted)
1199 break;
1201 ++end;
1205 if(end == beg)
1207 ++end;
1208 continue;
1211 string s = endpts.substr(beg, end - beg);
1212 EndpointIPtr endp = _instance->endpointFactoryManager()->create(s, oaEndpoints);
1213 if(endp == 0)
1215 EndpointParseException ex(__FILE__, __LINE__);
1216 ex.str = "invalid object adapter endpoint `" + s + "'";
1217 throw ex;
1219 endpoints.push_back(endp);
1221 ++end;
1224 return endpoints;
1227 std::vector<EndpointIPtr>
1228 ObjectAdapterI::parsePublishedEndpoints()
1231 // Parse published endpoints. If set, these are used in proxies
1232 // instead of the connection factory endpoints.
1234 string endpts = _communicator->getProperties()->getProperty(_name + ".PublishedEndpoints");
1235 vector<EndpointIPtr> endpoints = parseEndpoints(endpts, false);
1236 if(endpoints.empty())
1239 // If the PublishedEndpoints property isn't set, we compute the published enpdoints
1240 // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
1241 // to include actual addresses in the published endpoints.
1243 for(unsigned int i = 0; i < _incomingConnectionFactories.size(); ++i)
1245 vector<EndpointIPtr> endps = _incomingConnectionFactories[i]->endpoint()->expand();
1246 endpoints.insert(endpoints.end(), endps.begin(), endps.end());
1250 if(_instance->traceLevels()->network >= 1)
1252 Trace out(_instance->initializationData().logger, _instance->traceLevels()->networkCat);
1253 out << "published endpoints for object adapter `" << getName() << "':\n";
1254 for(unsigned int i = 0; i < endpoints.size(); ++i)
1256 if(i > 0)
1258 out << ":";
1260 out << endpoints[i]->toString();
1264 return endpoints;
1267 void
1268 ObjectAdapterI::updateLocatorRegistry(const IceInternal::LocatorInfoPtr& locatorInfo,
1269 const Ice::ObjectPrx& proxy,
1270 bool registerProcess)
1272 if(!registerProcess && _id.empty())
1274 return; // Nothing to update.
1278 // Call on the locator registry outside the synchronization to
1279 // blocking other threads that need to lock this OA.
1281 LocatorRegistryPrx locatorRegistry = locatorInfo ? locatorInfo->getLocatorRegistry() : LocatorRegistryPrx();
1282 string serverId;
1283 if(registerProcess)
1285 assert(_instance);
1286 serverId = _instance->initializationData().properties->getProperty("Ice.ServerId");
1288 if(!locatorRegistry)
1290 Warning out(_instance->initializationData().logger);
1291 out << "object adapter `" << getName() << "' cannot register the process without a locator registry";
1293 else if(serverId.empty())
1295 Warning out(_instance->initializationData().logger);
1296 out << "object adapter `" << getName() << "' cannot register the process without a value for Ice.ServerId";
1300 if(!locatorRegistry)
1302 return;
1305 if(!_id.empty())
1309 if(_replicaGroupId.empty())
1311 locatorRegistry->setAdapterDirectProxy(_id, proxy);
1313 else
1315 locatorRegistry->setReplicatedAdapterDirectProxy(_id, _replicaGroupId, proxy);
1318 catch(const AdapterNotFoundException&)
1320 if(_instance->traceLevels()->location >= 1)
1322 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1323 out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n";
1324 out << "the object adapter is not known to the locator registry";
1327 NotRegisteredException ex(__FILE__, __LINE__);
1328 ex.kindOfObject = "object adapter";
1329 ex.id = _id;
1330 throw ex;
1332 catch(const InvalidReplicaGroupIdException&)
1334 if(_instance->traceLevels()->location >= 1)
1336 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1337 out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n";
1338 out << "the replica group `" << _replicaGroupId << "' is not known to the locator registry";
1341 NotRegisteredException ex(__FILE__, __LINE__);
1342 ex.kindOfObject = "replica group";
1343 ex.id = _replicaGroupId;
1344 throw ex;
1346 catch(const AdapterAlreadyActiveException&)
1348 if(_instance->traceLevels()->location >= 1)
1350 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1351 out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n";
1352 out << "the object adapter endpoints are already set";
1355 ObjectAdapterIdInUseException ex(__FILE__, __LINE__);
1356 ex.id = _id;
1357 throw ex;
1359 catch(const LocalException& ex)
1361 if(_instance->traceLevels()->location >= 1)
1363 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1364 out << "couldn't update object adapter `" + _id + "' endpoints with the locator registry:\n" << ex;
1366 throw; // TODO: Shall we raise a special exception instead of a non obvious local exception?
1369 if(_instance->traceLevels()->location >= 1)
1371 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1372 out << "updated object adapter `" + _id + "' endpoints with the locator registry\n";
1373 out << "endpoints = ";
1374 if(proxy)
1376 EndpointSeq endpts = proxy ? proxy->ice_getEndpoints() : EndpointSeq();
1377 ostringstream o;
1378 transform(endpts.begin(), endpts.end(), ostream_iterator<string>(o, endpts.size() > 1 ? ":" : ""),
1379 Ice::constMemFun(&Endpoint::toString));
1380 out << o.str();
1385 if(registerProcess && !serverId.empty())
1388 IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
1390 if(_processId.name == "")
1392 ProcessPtr servant = new ProcessI(_communicator);
1393 _processId = addWithUUID(servant)->ice_getIdentity();
1399 locatorRegistry->setServerProcessProxy(serverId, ProcessPrx::uncheckedCast(createDirectProxy(_processId)));
1401 catch(const ServerNotFoundException&)
1403 if(_instance->traceLevels()->location >= 1)
1405 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1406 out << "couldn't register server `" + serverId + "' with the locator registry:\n";
1407 out << "the server is not known to the locator registry";
1410 NotRegisteredException ex(__FILE__, __LINE__);
1411 ex.kindOfObject = "server";
1412 ex.id = serverId;
1413 throw ex;
1415 catch(const Ice::LocalException& ex)
1417 if(_instance->traceLevels()->location >= 1)
1419 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1420 out << "couldn't register server `" + serverId + "' with the locator registry:\n" << ex;
1422 throw; // TODO: Shall we raise a special exception instead of a non obvious local exception?
1425 if(_instance->traceLevels()->location >= 1)
1427 Trace out(_instance->initializationData().logger, _instance->traceLevels()->locationCat);
1428 out << "registered server `" + serverId + "' with the locator registry";
1433 bool
1434 Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps)
1436 static const string suffixes[] =
1438 "ACM",
1439 "AdapterId",
1440 "Endpoints",
1441 "Locator",
1442 "Locator.EndpointSelection",
1443 "Locator.ConnectionCached",
1444 "Locator.PreferSecure",
1445 "Locator.CollocationOptimized",
1446 "Locator.Router",
1447 "PublishedEndpoints",
1448 "RegisterProcess",
1449 "ReplicaGroupId",
1450 "Router",
1451 "Router.EndpointSelection",
1452 "Router.ConnectionCached",
1453 "Router.PreferSecure",
1454 "Router.CollocationOptimized",
1455 "Router.Locator",
1456 "Router.Locator.EndpointSelection",
1457 "Router.Locator.ConnectionCached",
1458 "Router.Locator.PreferSecure",
1459 "Router.Locator.CollocationOptimized",
1460 "Router.Locator.LocatorCacheTimeout",
1461 "Router.LocatorCacheTimeout",
1462 "ProxyOptions",
1463 "ThreadPool.Size",
1464 "ThreadPool.SizeMax",
1465 "ThreadPool.SizeWarn",
1466 "ThreadPool.StackSize",
1467 "ThreadPool.Serialize",
1468 "ThreadPool.ThreadPriority"
1472 // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc
1474 bool addUnknown = true;
1475 string prefix = _name + ".";
1476 for(const char** i = IceInternal::PropertyNames::clPropNames; *i != 0; ++i)
1478 string icePrefix = string(*i) + ".";
1479 if(prefix.find(icePrefix) == 0)
1481 addUnknown = false;
1482 break;
1486 bool noProps = true;
1487 PropertyDict props = _instance->initializationData().properties->getPropertiesForPrefix(prefix);
1488 PropertyDict::const_iterator p;
1489 for(p = props.begin(); p != props.end(); ++p)
1491 bool valid = false;
1492 for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i)
1494 string prop = prefix + suffixes[i];
1495 if(p->first == prop)
1497 noProps = false;
1498 valid = true;
1499 break;
1501 else
1507 if(!valid && addUnknown)
1509 unknownProps.push_back(p->first);
1513 return noProps;