1 // **********************************************************************
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
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>
37 # include <sys/timeb.h>
39 # include <sys/time.h>
46 using namespace IceInternal
;
49 Ice::ObjectAdapterI::getName() const
52 // No mutex lock necessary, _name is immutable.
54 return _noConfig
? string("") : _name
;
58 Ice::ObjectAdapterI::getCommunicator() const
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
));
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
;
105 PropertiesPtr properties
= _instance
->initializationData().properties
;
106 printAdapterReady
= properties
->getPropertyAsInt("Ice.PrintAdapterReady") > 0;
107 registerProcess
= properties
->getPropertyAsInt(_name
+ ".RegisterProcess") > 0;
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
126 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
127 _waitForActivate
= false;
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;
148 _activateOneOffDone
= true;
150 for_each(_incomingConnectionFactories
.begin(), _incomingConnectionFactories
.end(),
151 Ice::voidMemFun(&IncomingConnectionFactory::activate
));
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
));
167 Ice::ObjectAdapterI::waitForHold()
171 vector
<IncomingConnectionFactoryPtr
> incomingConnectionFactories
;
173 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
175 checkForDeactivation();
177 incomingConnectionFactories
= _incomingConnectionFactories
;
182 for_each(incomingConnectionFactories
.begin(), incomingConnectionFactories
.end(),
183 Ice::constVoidMemFun(&IncomingConnectionFactory::waitUntilHolding
));
186 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
187 if(--_waitForHold
== 0)
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
)
206 while(_waitForHold
> 0)
208 checkForDeactivation();
211 _waitForHoldRetry
= false;
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
236 // Wait for activation to complete. This is necessary to not
237 // get out of order locator updates.
239 while(_waitForActivate
)
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
;
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
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);
295 Ice::ObjectAdapterI::waitForDeactivate()
297 vector
<IceInternal::IncomingConnectionFactoryPtr
> incomingConnectionFactories
;
300 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
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)
315 incomingConnectionFactories
= _incomingConnectionFactories
;
319 // Now we wait until all incoming connection factories are
322 for_each(incomingConnectionFactories
.begin(), incomingConnectionFactories
.end(),
323 Ice::voidMemFun(&IncomingConnectionFactory::waitUntilFinished
));
327 Ice::ObjectAdapterI::isDeactivated() const
329 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
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.
350 // Object adapter is already destroyed.
361 // Deactivate and wait for completion.
367 // Now it's also time to clean up our servants and servant
370 _servantManager
->destroy();
373 // Destroy the thread pool.
377 _threadPool
->destroy();
378 _threadPool
->joinWithAllThreads();
381 ObjectAdapterFactoryPtr objectAdapterFactory
;
384 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
387 // Signal that destroy is complete.
394 // We're done, now we can throw away all incoming connection
397 _incomingConnectionFactories
.clear();
400 // Remove object references (some of them cyclic).
404 _routerEndpoints
.clear();
406 _publishedEndpoints
.clear();
410 objectAdapterFactory
= _objectAdapterFactory
;
411 _objectAdapterFactory
= 0;
414 if(objectAdapterFactory
)
416 objectAdapterFactory
->removeObjectAdapter(this);
421 Ice::ObjectAdapterI::add(const ObjectPtr
& object
, const Identity
& ident
)
423 return addFacet(object
, ident
, "");
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
);
440 Ice::ObjectAdapterI::addWithUUID(const ObjectPtr
& object
)
442 return addFacetWithUUID(object
, "");
446 Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr
& object
, const string
& facet
)
449 ident
.name
= IceUtil::generateUUID();
450 return addFacet(object
, ident
, facet
);
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
);
464 Ice::ObjectAdapterI::remove(const Identity
& ident
)
466 return removeFacet(ident
, "");
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
);
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
);
492 Ice::ObjectAdapterI::removeDefaultServant(const string
& category
)
494 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
496 checkForDeactivation();
498 return _servantManager
->removeDefaultServant(category
);
502 Ice::ObjectAdapterI::find(const Identity
& ident
) const
504 return findFacet(ident
, "");
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
);
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
);
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());
541 Ice::ObjectAdapterI::findDefaultServant(const string
& category
) const
543 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
545 checkForDeactivation();
547 return _servantManager
->findDefaultServant(category
);
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
);
561 Ice::ObjectAdapterI::removeServantLocator(const string
& prefix
)
563 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
565 checkForDeactivation();
567 return _servantManager
->removeServantLocator(prefix
);
571 Ice::ObjectAdapterI::findServantLocator(const string
& prefix
) const
573 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
575 checkForDeactivation();
577 return _servantManager
->findServantLocator(prefix
);
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
, "");
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
, "");
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
);
614 Ice::ObjectAdapterI::setLocator(const LocatorPrx
& locator
)
616 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
618 checkForDeactivation();
620 _locatorInfo
= _instance
->locatorManager()->get(locator
);
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
;
642 _instance
->initializationData().properties
->getPropertyAsInt(_name
+ ".RegisterProcess") > 0;
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
;
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
));
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
));
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
;
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()))
732 vector
<EndpointIPtr
>::const_iterator r
;
733 for(r
= _publishedEndpoints
.begin(); r
!= _publishedEndpoints
.end(); ++r
)
735 if((*p
)->equivalent(*r
))
743 // Proxies which have at least one endpoint in common with the
744 // router's server proxy endpoints (if any), are also considered
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
))
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
);
782 Ice::ObjectAdapterI::incDirectCount()
784 IceUtil::Monitor
<IceUtil::RecMutex
>::Lock
sync(*this);
786 checkForDeactivation();
788 assert(_directCount
>= 0);
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)
809 Ice::ObjectAdapterI::getThreadPool() const
811 // No mutex lock necessary, _threadPool and _instance are
812 // immutable after creation until they are removed in
815 // Not check for deactivation here!
817 assert(_instance
); // Must not be called after destroy().
825 return _instance
->serverThreadPool();
830 Ice::ObjectAdapterI::getServantManager() const
833 // No mutex lock necessary, _servantManager is immutable.
835 return _servantManager
;
839 Ice::ObjectAdapterI::getACM() const
841 // Not check for deactivation here!
843 assert(_instance
); // Must not be called after destroy().
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
) :
865 _communicator(communicator
),
866 _objectAdapterFactory(objectAdapterFactory
),
867 _hasAcmTimeout(false),
869 _servantManager(new ServantManager(instance
, name
)),
870 _activateOneOffDone(false),
873 _waitForActivate(false),
875 _waitForHoldRetry(false),
883 Ice::ObjectAdapterI::initialize(const RouterPrx
& router
)
887 _reference
= _instance
->referenceFactory()->create("dummy -t", "");
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";
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
+ "'";
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") != "";
955 _acmTimeout
= properties
->getPropertyAsInt(_name
+ ".ACM");
956 _instance
->connectionMonitor()->checkIntervalForACM(_acmTimeout
);
961 const_cast<RouterPrx
&>(router
) = RouterPrx::uncheckedCast(
962 _instance
->proxyFactory()->propertyToProxy(_name
+ ".Router"));
966 _routerInfo
= _instance
->routerManager()->get(router
);
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
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
1000 _instance
->outgoingConnectionFactory()->setRouterInfo(_routerInfo
);
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")));
1041 setLocator(_instance
->referenceFactory()->getDefaultLocator());
1051 Ice::ObjectAdapterI::~ObjectAdapterI()
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";
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
);
1074 Ice::ObjectAdapterI::newProxy(const Identity
& ident
, const string
& facet
) const
1078 return newDirectProxy(ident
, facet
);
1080 else if(_replicaGroupId
.empty())
1082 return newIndirectProxy(ident
, facet
, _id
);
1086 return newIndirectProxy(ident
, facet
, _replicaGroupId
);
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
);
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
);
1124 Ice::ObjectAdapterI::checkForDeactivation() const
1128 ObjectAdapterDeactivatedException
ex(__FILE__
, __LINE__
);
1129 ex
.name
= getName();
1135 Ice::ObjectAdapterI::checkIdentity(const Identity
& ident
)
1137 if(ident
.name
.size() == 0)
1139 IllegalIdentityException
e(__FILE__
, __LINE__
);
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
)
1165 end
= endpts
.find(':', end
);
1166 if(end
== string::npos
)
1168 end
= endpts
.length();
1173 bool quoted
= false;
1174 string::size_type quote
= beg
;
1177 quote
= endpts
.find('\"', quote
);
1178 if(quote
== string::npos
|| end
< quote
)
1184 quote
= endpts
.find('\"', ++quote
);
1185 if(quote
== string::npos
)
1189 else if(end
< quote
)
1211 string s
= endpts
.substr(beg
, end
- beg
);
1212 EndpointIPtr endp
= _instance
->endpointFactoryManager()->create(s
, oaEndpoints
);
1215 EndpointParseException
ex(__FILE__
, __LINE__
);
1216 ex
.str
= "invalid object adapter endpoint `" + s
+ "'";
1219 endpoints
.push_back(endp
);
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
)
1260 out
<< endpoints
[i
]->toString();
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();
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
)
1309 if(_replicaGroupId
.empty())
1311 locatorRegistry
->setAdapterDirectProxy(_id
, proxy
);
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";
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
;
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__
);
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 = ";
1376 EndpointSeq endpts
= proxy
? proxy
->ice_getEndpoints() : EndpointSeq();
1378 transform(endpts
.begin(), endpts
.end(), ostream_iterator
<string
>(o
, endpts
.size() > 1 ? ":" : ""),
1379 Ice::constMemFun(&Endpoint::toString
));
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";
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";
1434 Ice::ObjectAdapterI::filterProperties(StringSeq
& unknownProps
)
1436 static const string suffixes
[] =
1442 "Locator.EndpointSelection",
1443 "Locator.ConnectionCached",
1444 "Locator.PreferSecure",
1445 "Locator.CollocationOptimized",
1447 "PublishedEndpoints",
1451 "Router.EndpointSelection",
1452 "Router.ConnectionCached",
1453 "Router.PreferSecure",
1454 "Router.CollocationOptimized",
1456 "Router.Locator.EndpointSelection",
1457 "Router.Locator.ConnectionCached",
1458 "Router.Locator.PreferSecure",
1459 "Router.Locator.CollocationOptimized",
1460 "Router.Locator.LocatorCacheTimeout",
1461 "Router.LocatorCacheTimeout",
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)
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
)
1492 for(unsigned int i
= 0; i
< sizeof(suffixes
)/sizeof(*suffixes
); ++i
)
1494 string prop
= prefix
+ suffixes
[i
];
1495 if(p
->first
== prop
)
1507 if(!valid
&& addUnknown
)
1509 unknownProps
.push_back(p
->first
);