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/DisableWarnings.h>
11 #include <Ice/Instance.h>
12 #include <Ice/TraceLevels.h>
13 #include <Ice/DefaultsAndOverrides.h>
14 #include <Ice/RouterInfo.h>
15 #include <Ice/Router.h>
16 #include <Ice/LocatorInfo.h>
17 #include <Ice/Locator.h>
18 #include <Ice/ReferenceFactory.h>
19 #include <Ice/ProxyFactory.h>
20 #include <Ice/ThreadPool.h>
21 #include <Ice/ConnectionFactory.h>
22 #include <Ice/ConnectionMonitor.h>
23 #include <Ice/ObjectFactoryManager.h>
24 #include <Ice/LocalException.h>
25 #include <Ice/ObjectAdapterFactory.h>
26 #include <Ice/Exception.h>
27 #include <Ice/PropertiesI.h>
28 #include <Ice/LoggerI.h>
29 #include <Ice/Network.h>
30 #include <Ice/EndpointFactoryManager.h>
31 #include <Ice/RetryQueue.h>
32 #include <Ice/TcpEndpointI.h>
33 #include <Ice/UdpEndpointI.h>
34 #include <Ice/DynamicLibrary.h>
35 #include <Ice/PluginManagerI.h>
36 #include <Ice/Initialize.h>
37 #include <Ice/LoggerUtil.h>
38 #include <IceUtil/StringUtil.h>
39 #include <Ice/PropertiesI.h>
40 #include <IceUtil/UUID.h>
41 #include <Ice/Communicator.h>
42 #include <IceUtil/Mutex.h>
43 #include <IceUtil/MutexPtrLock.h>
48 # include <Ice/SysLoggerI.h>
53 # include <sys/types.h>
58 using namespace IceInternal
;
60 namespace IceUtilInternal
63 extern bool ICE_DECLSPEC_IMPORT nullHandleAbort
;
64 extern bool ICE_DECLSPEC_IMPORT printStackTraces
;
71 IceUtil::Mutex
* staticMutex
= 0;
72 bool oneOffDone
= false;
73 int instanceCount
= 0;
75 struct sigaction oldAction
;
77 bool printProcessIdDone
= false;
78 string identForOpenlog
;
86 staticMutex
= new IceUtil::Mutex
;
100 IceUtil::Shared
* IceInternal::upCast(Instance
* p
) { return p
; }
103 IceInternal::Instance::destroyed() const
105 IceUtil::RecMutex::Lock
sync(*this);
106 return _state
== StateDestroyed
;
110 IceInternal::Instance::traceLevels() const
112 // No mutex lock, immutable.
113 assert(_traceLevels
);
117 DefaultsAndOverridesPtr
118 IceInternal::Instance::defaultsAndOverrides() const
120 // No mutex lock, immutable.
121 assert(_defaultsAndOverrides
);
122 return _defaultsAndOverrides
;
126 IceInternal::Instance::routerManager() const
128 IceUtil::RecMutex::Lock
sync(*this);
130 if(_state
== StateDestroyed
)
132 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
135 assert(_routerManager
);
136 return _routerManager
;
140 IceInternal::Instance::locatorManager() const
142 IceUtil::RecMutex::Lock
sync(*this);
144 if(_state
== StateDestroyed
)
146 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
149 assert(_locatorManager
);
150 return _locatorManager
;
154 IceInternal::Instance::referenceFactory() const
156 IceUtil::RecMutex::Lock
sync(*this);
158 if(_state
== StateDestroyed
)
160 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
163 assert(_referenceFactory
);
164 return _referenceFactory
;
168 IceInternal::Instance::proxyFactory() const
170 IceUtil::RecMutex::Lock
sync(*this);
172 if(_state
== StateDestroyed
)
174 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
177 assert(_proxyFactory
);
178 return _proxyFactory
;
181 OutgoingConnectionFactoryPtr
182 IceInternal::Instance::outgoingConnectionFactory() const
184 IceUtil::RecMutex::Lock
sync(*this);
186 if(_state
== StateDestroyed
)
188 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
191 assert(_outgoingConnectionFactory
);
192 return _outgoingConnectionFactory
;
196 IceInternal::Instance::connectionMonitor() const
198 IceUtil::RecMutex::Lock
sync(*this);
200 if(_state
== StateDestroyed
)
202 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
205 assert(_connectionMonitor
);
206 return _connectionMonitor
;
209 ObjectFactoryManagerPtr
210 IceInternal::Instance::servantFactoryManager() const
212 IceUtil::RecMutex::Lock
sync(*this);
214 if(_state
== StateDestroyed
)
216 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
219 assert(_servantFactoryManager
);
220 return _servantFactoryManager
;
223 ObjectAdapterFactoryPtr
224 IceInternal::Instance::objectAdapterFactory() const
226 IceUtil::RecMutex::Lock
sync(*this);
228 if(_state
== StateDestroyed
)
230 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
233 assert(_objectAdapterFactory
);
234 return _objectAdapterFactory
;
238 IceInternal::Instance::protocolSupport() const
240 IceUtil::RecMutex::Lock
sync(*this);
242 if(_state
== StateDestroyed
)
244 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
247 return _protocolSupport
;
251 IceInternal::Instance::clientThreadPool()
253 IceUtil::RecMutex::Lock
sync(*this);
255 if(_state
== StateDestroyed
)
257 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
260 assert(_clientThreadPool
);
261 return _clientThreadPool
;
265 IceInternal::Instance::serverThreadPool()
267 IceUtil::RecMutex::Lock
sync(*this);
269 if(_state
== StateDestroyed
)
271 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
274 if(!_serverThreadPool
) // Lazy initialization.
276 int timeout
= _initData
.properties
->getPropertyAsInt("Ice.ServerIdleTime");
277 _serverThreadPool
= new ThreadPool(this, "Ice.ThreadPool.Server", timeout
);
280 return _serverThreadPool
;
283 EndpointHostResolverPtr
284 IceInternal::Instance::endpointHostResolver()
286 IceUtil::RecMutex::Lock
sync(*this);
288 if(_state
== StateDestroyed
)
290 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
293 assert(_endpointHostResolver
);
294 return _endpointHostResolver
;
298 IceInternal::Instance::retryQueue()
300 IceUtil::RecMutex::Lock
sync(*this);
302 if(_state
== StateDestroyed
)
304 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
312 IceInternal::Instance::timer()
314 IceUtil::RecMutex::Lock
sync(*this);
316 if(_state
== StateDestroyed
)
318 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
324 EndpointFactoryManagerPtr
325 IceInternal::Instance::endpointFactoryManager() const
327 IceUtil::RecMutex::Lock
sync(*this);
329 if(_state
== StateDestroyed
)
331 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
334 assert(_endpointFactoryManager
);
335 return _endpointFactoryManager
;
338 DynamicLibraryListPtr
339 IceInternal::Instance::dynamicLibraryList() const
341 IceUtil::RecMutex::Lock
sync(*this);
343 if(_state
== StateDestroyed
)
345 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
348 assert(_dynamicLibraryList
);
349 return _dynamicLibraryList
;
353 IceInternal::Instance::pluginManager() const
355 IceUtil::RecMutex::Lock
sync(*this);
357 if(_state
== StateDestroyed
)
359 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
362 assert(_pluginManager
);
363 return _pluginManager
;
367 IceInternal::Instance::clientACM() const
369 // No mutex lock, immutable.
374 IceInternal::Instance::serverACM() const
376 // No mutex lock, immutable.
381 IceInternal::Instance::stringToIdentity(const string
& s
) const
384 // This method only accepts printable ascii. Since printable ascii is a subset
385 // of all narrow string encodings, it is not necessary to convert the string
386 // from the native string encoding. Any characters other than printable-ASCII
387 // will cause an IllegalArgumentException. Note that it can contain Unicode
388 // encoded in the escaped form which is the reason why we call fromUTF8 after
389 // unespcaping the printable ASCII string.
395 // Find unescaped separator.
397 string::size_type slash
= string::npos
, pos
= 0;
398 while((pos
= s
.find('/', pos
)) != string::npos
)
400 if(pos
== 0 || s
[pos
- 1] != '\\')
402 if(slash
== string::npos
)
409 // Extra unescaped slash found.
411 IdentityParseException
ex(__FILE__
, __LINE__
);
412 ex
.str
= "unescaped backslash in identity `" + s
+ "'";
419 if(slash
== string::npos
)
423 ident
.name
= IceUtilInternal::unescapeString(s
, 0, s
.size());
425 catch(const IceUtil::IllegalArgumentException
& e
)
427 IdentityParseException
ex(__FILE__
, __LINE__
);
428 ex
.str
= "invalid identity name `" + s
+ "': " + e
.reason();
436 ident
.category
= IceUtilInternal::unescapeString(s
, 0, slash
);
438 catch(const IceUtil::IllegalArgumentException
& e
)
440 IdentityParseException
ex(__FILE__
, __LINE__
);
441 ex
.str
= "invalid category in identity `" + s
+ "': " + e
.reason();
444 if(slash
+ 1 < s
.size())
448 ident
.name
= IceUtilInternal::unescapeString(s
, slash
+ 1, s
.size());
450 catch(const IceUtil::IllegalArgumentException
& e
)
452 IdentityParseException
ex(__FILE__
, __LINE__
);
453 ex
.str
= "invalid name in identity `" + s
+ "': " + e
.reason();
459 ident
.name
= Ice::UTF8ToNative(_initData
.stringConverter
, ident
.name
);
460 ident
.category
= Ice::UTF8ToNative(_initData
.stringConverter
, ident
.category
);
466 IceInternal::Instance::identityToString(const Identity
& ident
) const
469 // This method returns the stringified identity. The returned string only
470 // contains printable ascii. It can contain UTF8 in the escaped form.
472 string name
= Ice::nativeToUTF8(_initData
.stringConverter
, ident
.name
);
473 string category
= Ice::nativeToUTF8(_initData
.stringConverter
, ident
.category
);
477 return IceUtilInternal::escapeString(name
, "/");
481 return IceUtilInternal::escapeString(category
, "/") + '/' + IceUtilInternal::escapeString(name
, "/");
486 IceInternal::Instance::getAdmin()
488 IceUtil::RecMutex::Lock
sync(*this);
490 if(_state
== StateDestroyed
)
492 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
495 const string adminOA
= "Ice.Admin";
497 if(_adminAdapter
!= 0)
499 return _adminAdapter
->createProxy(_adminIdentity
);
501 else if(_initData
.properties
->getProperty(adminOA
+ ".Endpoints") == "")
507 string serverId
= _initData
.properties
->getProperty("Ice.Admin.ServerId");
508 string instanceName
= _initData
.properties
->getProperty("Ice.Admin.InstanceName");
510 Ice::LocatorPrx defaultLocator
= _referenceFactory
->getDefaultLocator();
512 if((defaultLocator
!= 0 && serverId
!= "") || instanceName
!= "")
514 if(_adminIdentity
.name
== "")
516 _adminIdentity
.name
= "admin";
517 if(instanceName
== "")
519 instanceName
= IceUtil::generateUUID();
521 _adminIdentity
.category
= instanceName
;
524 // Afterwards, _adminIdentity is read-only
531 _adminAdapter
= _objectAdapterFactory
->createObjectAdapter(adminOA
, 0);
534 // Add all facets to OA
536 FacetMap filteredFacets
;
538 for(FacetMap::iterator p
= _adminFacets
.begin(); p
!= _adminFacets
.end(); ++p
)
540 if(_adminFacetFilter
.empty() || _adminFacetFilter
.find(p
->first
) != _adminFacetFilter
.end())
542 _adminAdapter
->addFacet(p
->second
, _adminIdentity
, p
->first
);
546 filteredFacets
[p
->first
] = p
->second
;
549 _adminFacets
.swap(filteredFacets
);
551 ObjectAdapterPtr adapter
= _adminAdapter
;
564 // We cleanup _adminAdapter, however this error is not recoverable
565 // (can't call again getAdmin() after fixing the problem)
566 // since all the facets (servants) in the adapter are lost
574 Ice::ObjectPrx admin
= adapter
->createProxy(_adminIdentity
);
575 if(defaultLocator
!= 0 && serverId
!= "")
577 ProcessPrx process
= ProcessPrx::uncheckedCast(admin
->ice_facet("Process"));
581 // Note that as soon as the process proxy is registered, the communicator might be
582 // shutdown by a remote client and admin facets might start receiving calls.
584 defaultLocator
->getRegistry()->setServerProcessProxy(serverId
, process
);
586 catch(const ServerNotFoundException
&)
588 if(_traceLevels
->location
>= 1)
590 Trace
out(_initData
.logger
, _traceLevels
->locationCat
);
591 out
<< "couldn't register server `" + serverId
+ "' with the locator registry:\n";
592 out
<< "the server is not known to the locator registry";
595 throw InitializationException(__FILE__
, __LINE__
, "Locator knows nothing about server '" +
598 catch(const LocalException
& ex
)
600 if(_traceLevels
->location
>= 1)
602 Trace
out(_initData
.logger
, _traceLevels
->locationCat
);
603 out
<< "couldn't register server `" + serverId
+ "' with the locator registry:\n" << ex
;
609 if(_traceLevels
->location
>= 1)
611 Trace
out(_initData
.logger
, _traceLevels
->locationCat
);
612 out
<< "registered server `" + serverId
+ "' with the locator registry";
625 IceInternal::Instance::addAdminFacet(const Ice::ObjectPtr
& servant
, const string
& facet
)
627 IceUtil::RecMutex::Lock
sync(*this);
629 if(_state
== StateDestroyed
)
631 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
634 if(_adminAdapter
== 0 || (!_adminFacetFilter
.empty() && _adminFacetFilter
.find(facet
) == _adminFacetFilter
.end()))
636 if(_adminFacets
.insert(FacetMap::value_type(facet
, servant
)).second
== false)
638 throw AlreadyRegisteredException(__FILE__
, __LINE__
, "facet", facet
);
643 _adminAdapter
->addFacet(servant
, _adminIdentity
, facet
);
648 IceInternal::Instance::removeAdminFacet(const string
& facet
)
650 IceUtil::RecMutex::Lock
sync(*this);
652 if(_state
== StateDestroyed
)
654 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
659 if(_adminAdapter
== 0 || (!_adminFacetFilter
.empty() && _adminFacetFilter
.find(facet
) == _adminFacetFilter
.end()))
661 FacetMap::iterator p
= _adminFacets
.find(facet
);
662 if(p
== _adminFacets
.end())
664 throw NotRegisteredException(__FILE__
, __LINE__
, "facet", facet
);
669 _adminFacets
.erase(p
);
674 result
= _adminAdapter
->removeFacet(_adminIdentity
, facet
);
680 IceInternal::Instance::setDefaultLocator(const Ice::LocatorPrx
& defaultLocator
)
682 IceUtil::RecMutex::Lock
sync(*this);
684 if(_state
== StateDestroyed
)
686 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
689 _referenceFactory
= _referenceFactory
->setDefaultLocator(defaultLocator
);
693 IceInternal::Instance::setDefaultRouter(const Ice::RouterPrx
& defaultRouter
)
695 IceUtil::RecMutex::Lock
sync(*this);
697 if(_state
== StateDestroyed
)
699 throw CommunicatorDestroyedException(__FILE__
, __LINE__
);
702 _referenceFactory
= _referenceFactory
->setDefaultRouter(defaultRouter
);
706 IceInternal::Instance::setStringConverter(const Ice::StringConverterPtr
& stringConverter
)
709 // No locking, as it can only be called during plug-in loading
711 _initData
.stringConverter
= stringConverter
;
715 IceInternal::Instance::setWstringConverter(const Ice::WstringConverterPtr
& wstringConverter
)
718 // No locking, as it can only be called during plug-in loading
720 _initData
.wstringConverter
= wstringConverter
;
724 IceInternal::Instance::setLogger(const Ice::LoggerPtr
& logger
)
727 // No locking, as it can only be called during plug-in loading
729 _initData
.logger
= logger
;
733 IceInternal::Instance::setThreadHook(const Ice::ThreadNotificationPtr
& threadHook
)
736 // No locking, as it can only be called during plug-in loading
738 _initData
.threadHook
= threadHook
;
741 IceInternal::Instance::Instance(const CommunicatorPtr
& communicator
, const InitializationData
& initData
) :
753 IceUtilInternal::MutexPtrLock
<IceUtil::Mutex
> sync(staticMutex
);
756 if(!_initData
.properties
)
758 _initData
.properties
= createProperties();
764 // StdOut and StdErr redirection
766 string stdOutFilename
= _initData
.properties
->getProperty("Ice.StdOut");
767 string stdErrFilename
= _initData
.properties
->getProperty("Ice.StdErr");
769 if(stdOutFilename
!= "")
771 #ifdef _LARGEFILE64_SOURCE
772 FILE* file
= freopen64(stdOutFilename
.c_str(), "a", stdout
);
775 FILE* file
= _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData
.stringConverter
,
776 stdOutFilename
)).c_str(),
779 FILE* file
= freopen(stdOutFilename
.c_str(), "a", stdout
);
784 FileException
ex(__FILE__
, __LINE__
);
785 ex
.path
= stdOutFilename
;
786 ex
.error
= getSystemErrno();
791 if(stdErrFilename
!= "")
793 #ifdef _LARGEFILE64_SOURCE
794 FILE* file
= freopen64(stdErrFilename
.c_str(), "a", stderr
);
797 FILE* file
= _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData
.stringConverter
,
798 stdErrFilename
)).c_str(),
801 FILE* file
= freopen(stdErrFilename
.c_str(), "a", stderr
);
806 FileException
ex(__FILE__
, __LINE__
);
807 ex
.path
= stdErrFilename
;
808 ex
.error
= getSystemErrno();
813 if(_initData
.properties
->getPropertyAsInt("Ice.NullHandleAbort") > 0)
815 IceUtilInternal::nullHandleAbort
= true;
819 if(_initData
.properties
->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 0) > 0)
821 if(_initData
.properties
->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1) > 0)
824 IceUtilInternal::printStackTraces
= true;
828 string newUser
= _initData
.properties
->getProperty("Ice.ChangeUser");
831 struct passwd
* pw
= getpwnam(newUser
.c_str());
834 SyscallException
ex(__FILE__
, __LINE__
);
835 ex
.error
= getSystemErrno();
839 if(setgid(pw
->pw_gid
) == -1)
841 SyscallException
ex(__FILE__
, __LINE__
);
842 ex
.error
= getSystemErrno();
846 if(setuid(pw
->pw_uid
) == -1)
848 SyscallException
ex(__FILE__
, __LINE__
);
849 ex
.error
= getSystemErrno();
857 if(instanceCount
== 1)
861 WORD version
= MAKEWORD(1, 1);
863 if(WSAStartup(version
, &data
) != 0)
865 SocketException
ex(__FILE__
, __LINE__
);
866 ex
.error
= getSocketErrno();
872 struct sigaction action
;
873 action
.sa_handler
= SIG_IGN
;
874 sigemptyset(&action
.sa_mask
);
876 sigaction(SIGPIPE
, &action
, &oldAction
);
877 if(_initData
.properties
->getPropertyAsInt("Ice.UseSyslog") > 0)
879 identForOpenlog
= _initData
.properties
->getProperty("Ice.ProgramName");
880 if(identForOpenlog
.empty())
882 identForOpenlog
= "<Unknown Ice Program>";
884 openlog(identForOpenlog
.c_str(), LOG_PID
, LOG_USER
);
891 if(!_initData
.logger
)
893 string logfile
= _initData
.properties
->getProperty("Ice.LogFile");
895 if(_initData
.properties
->getPropertyAsInt("Ice.UseSyslog") > 0)
899 throw InitializationException(__FILE__
, __LINE__
, "Both syslog and file logger cannot be enabled.");
903 new SysLoggerI(_initData
.properties
->getProperty("Ice.ProgramName"),
904 _initData
.properties
->getPropertyWithDefault("Ice.SyslogFacility", "LOG_USER"));
910 _initData
.logger
= new LoggerI(_initData
.properties
->getProperty("Ice.ProgramName"),
911 nativeToUTF8(_initData
.stringConverter
, logfile
));
915 _initData
.logger
= getProcessLogger();
919 const_cast<TraceLevelsPtr
&>(_traceLevels
) = new TraceLevels(_initData
.properties
);
921 const_cast<DefaultsAndOverridesPtr
&>(_defaultsAndOverrides
) = new DefaultsAndOverrides(_initData
.properties
);
924 static const int defaultMessageSizeMax
= 1024;
925 Int num
= _initData
.properties
->getPropertyAsIntWithDefault("Ice.MessageSizeMax", defaultMessageSizeMax
);
928 const_cast<size_t&>(_messageSizeMax
) = defaultMessageSizeMax
* 1024; // Ignore non-sensical values.
930 else if(static_cast<size_t>(num
) > (size_t)(0x7fffffff / 1024))
932 const_cast<size_t&>(_messageSizeMax
) = static_cast<size_t>(0x7fffffff);
936 // Property is in kilobytes, _messageSizeMax in bytes.
937 const_cast<size_t&>(_messageSizeMax
) = static_cast<size_t>(num
) * 1024;
942 // Client ACM enabled by default. Server ACM disabled by default.
944 const_cast<Int
&>(_clientACM
) = _initData
.properties
->getPropertyAsIntWithDefault("Ice.ACM.Client", 60);
945 const_cast<Int
&>(_serverACM
) = _initData
.properties
->getPropertyAsInt("Ice.ACM.Server");
946 const_cast<ImplicitContextIPtr
&>(_implicitContext
) =
947 ImplicitContextI::create(_initData
.properties
->getProperty("Ice.ImplicitContext"));
949 _routerManager
= new RouterManager
;
951 _locatorManager
= new LocatorManager(_initData
.properties
);
953 _referenceFactory
= new ReferenceFactory(this, communicator
);
955 _proxyFactory
= new ProxyFactory(this);
957 bool ipv4
= _initData
.properties
->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0;
958 bool ipv6
= _initData
.properties
->getPropertyAsIntWithDefault("Ice.IPv6", 0) > 0;
961 throw InitializationException(__FILE__
, __LINE__
, "Both IPV4 and IPv6 support cannot be disabled.");
963 else if(ipv4
&& ipv6
)
965 _protocolSupport
= EnableBoth
;
969 _protocolSupport
= EnableIPv4
;
973 _protocolSupport
= EnableIPv6
;
975 _endpointFactoryManager
= new EndpointFactoryManager(this);
976 EndpointFactoryPtr tcpEndpointFactory
= new TcpEndpointFactory(this);
977 _endpointFactoryManager
->add(tcpEndpointFactory
);
978 EndpointFactoryPtr udpEndpointFactory
= new UdpEndpointFactory(this);
979 _endpointFactoryManager
->add(udpEndpointFactory
);
981 _dynamicLibraryList
= new DynamicLibraryList
;
983 _pluginManager
= new PluginManagerI(communicator
, _dynamicLibraryList
);
985 _outgoingConnectionFactory
= new OutgoingConnectionFactory(this);
987 _servantFactoryManager
= new ObjectFactoryManager();
989 _objectAdapterFactory
= new ObjectAdapterFactory(this, communicator
);
991 _retryQueue
= new RetryQueue(this);
994 if(_initData
.wstringConverter
== 0)
996 _initData
.wstringConverter
= new UnicodeWstringConverter();
1000 // Add Process and Properties facets
1003 StringSeq facetSeq
= _initData
.properties
->getPropertyAsList("Ice.Admin.Facets");
1005 if(!facetSeq
.empty())
1007 _adminFacetFilter
.insert(facetSeq
.begin(), facetSeq
.end());
1010 _adminFacets
.insert(FacetMap::value_type("Properties", new PropertiesAdminI(_initData
.properties
)));
1011 _adminFacets
.insert(FacetMap::value_type("Process", new ProcessI(communicator
)));
1013 __setNoDelete(false);
1018 IceUtilInternal::MutexPtrLock
<IceUtil::Mutex
> sync(staticMutex
);
1022 __setNoDelete(false);
1027 IceInternal::Instance::~Instance()
1029 assert(_state
== StateDestroyed
);
1030 assert(!_referenceFactory
);
1031 assert(!_proxyFactory
);
1032 assert(!_outgoingConnectionFactory
);
1034 assert(!_connectionMonitor
);
1035 assert(!_servantFactoryManager
);
1036 assert(!_objectAdapterFactory
);
1037 assert(!_clientThreadPool
);
1038 assert(!_serverThreadPool
);
1039 assert(!_endpointHostResolver
);
1040 assert(!_retryQueue
);
1042 assert(!_routerManager
);
1043 assert(!_locatorManager
);
1044 assert(!_endpointFactoryManager
);
1045 assert(!_dynamicLibraryList
);
1046 assert(!_pluginManager
);
1048 IceUtilInternal::MutexPtrLock
<IceUtil::Mutex
> sync(staticMutex
);
1049 if(--instanceCount
== 0)
1056 sigaction(SIGPIPE
, &oldAction
, 0);
1058 if(!identForOpenlog
.empty())
1061 identForOpenlog
.clear();
1068 IceInternal::Instance::finishSetup(int& argc
, char* argv
[])
1073 assert(!_serverThreadPool
);
1074 PluginManagerI
* pluginManagerImpl
= dynamic_cast<PluginManagerI
*>(_pluginManager
.get());
1075 assert(pluginManagerImpl
);
1076 pluginManagerImpl
->loadPlugins(argc
, argv
);
1084 bool hasPriority
= _initData
.properties
->getProperty("Ice.ThreadPriority") != "";
1085 int priority
= _initData
.properties
->getPropertyAsInt("Ice.ThreadPriority");
1088 _timer
= new IceUtil::Timer(priority
);
1092 _timer
= new IceUtil::Timer
;
1095 catch(const IceUtil::Exception
& ex
)
1097 Error
out(_initData
.logger
);
1098 out
<< "cannot create thread for timer:\n" << ex
;
1104 _endpointHostResolver
= new EndpointHostResolver(this);
1106 catch(const IceUtil::Exception
& ex
)
1108 Error
out(_initData
.logger
);
1109 out
<< "cannot create thread for endpoint host resolver:\n" << ex
;
1113 _clientThreadPool
= new ThreadPool(this, "Ice.ThreadPool.Client", 0);
1116 // Get default router and locator proxies. Don't move this
1117 // initialization before the plug-in initialization!!! The proxies
1118 // might depend on endpoint factories to be installed by plug-ins.
1120 RouterPrx router
= RouterPrx::uncheckedCast(_proxyFactory
->propertyToProxy("Ice.Default.Router"));
1123 _referenceFactory
= _referenceFactory
->setDefaultRouter(router
);
1126 LocatorPrx locator
= LocatorPrx::uncheckedCast(_proxyFactory
->propertyToProxy("Ice.Default.Locator"));
1129 _referenceFactory
= _referenceFactory
->setDefaultLocator(locator
);
1133 // Show process id if requested (but only once).
1135 bool printProcessId
= false;
1136 if(!printProcessIdDone
&& _initData
.properties
->getPropertyAsInt("Ice.PrintProcessId") > 0)
1139 // Safe double-check locking (no dependent variable!)
1141 IceUtilInternal::MutexPtrLock
<IceUtil::Mutex
> sync(staticMutex
);
1142 printProcessId
= !printProcessIdDone
;
1145 // We anticipate: we want to print it once, and we don't care when.
1147 printProcessIdDone
= true;
1153 cout
<< _getpid() << endl
;
1155 cout
<< getpid() << endl
;
1160 // Create the connection monitor and ensure the interval for
1161 // monitoring connections is appropriate for client & server
1164 _connectionMonitor
= new ConnectionMonitor(this, _initData
.properties
->getPropertyAsInt("Ice.MonitorConnections"));
1165 _connectionMonitor
->checkIntervalForACM(_clientACM
);
1166 _connectionMonitor
->checkIntervalForACM(_serverACM
);
1169 // Server thread pool initialization is lazy in serverThreadPool().
1173 // An application can set Ice.InitPlugins=0 if it wants to postpone
1174 // initialization until after it has interacted directly with the
1177 if(_initData
.properties
->getPropertyAsIntWithDefault("Ice.InitPlugins", 1) > 0)
1179 pluginManagerImpl
->initializePlugins();
1183 // This must be done last as this call creates the Ice.Admin object adapter
1184 // and eventually register a process proxy with the Ice locator (allowing
1185 // remote clients to invoke on Ice.Admin facets as soon as it's registered).
1187 if(_initData
.properties
->getPropertyAsIntWithDefault("Ice.Admin.DelayCreation", 0) <= 0)
1194 IceInternal::Instance::destroy()
1197 IceUtil::RecMutex::Lock
sync(*this);
1200 // If the _state is not StateActive then the instance is
1201 // either being destroyed, or has already been destroyed.
1203 if(_state
!= StateActive
)
1209 // We cannot set state to StateDestroyed otherwise instance
1210 // methods called during the destroy process (such as
1211 // outgoingConnectionFactory() from
1212 // ObjectAdapterI::deactivate() will cause an exception.
1214 _state
= StateDestroyInProgress
;
1217 if(_objectAdapterFactory
)
1219 _objectAdapterFactory
->shutdown();
1222 if(_outgoingConnectionFactory
)
1224 _outgoingConnectionFactory
->destroy();
1227 if(_objectAdapterFactory
)
1229 _objectAdapterFactory
->destroy();
1232 if(_outgoingConnectionFactory
)
1234 _outgoingConnectionFactory
->waitUntilFinished();
1239 _retryQueue
->destroy();
1242 ThreadPoolPtr serverThreadPool
;
1243 ThreadPoolPtr clientThreadPool
;
1244 EndpointHostResolverPtr endpointHostResolver
;
1247 IceUtil::RecMutex::Lock
sync(*this);
1249 _objectAdapterFactory
= 0;
1250 _outgoingConnectionFactory
= 0;
1253 if(_connectionMonitor
)
1255 _connectionMonitor
->destroy();
1256 _connectionMonitor
= 0;
1259 if(_serverThreadPool
)
1261 _serverThreadPool
->destroy();
1262 std::swap(_serverThreadPool
, serverThreadPool
);
1265 if(_clientThreadPool
)
1267 _clientThreadPool
->destroy();
1268 std::swap(_clientThreadPool
, clientThreadPool
);
1271 if(_endpointHostResolver
)
1273 _endpointHostResolver
->destroy();
1274 std::swap(endpointHostResolver
, _endpointHostResolver
);
1283 if(_servantFactoryManager
)
1285 _servantFactoryManager
->destroy();
1286 _servantFactoryManager
= 0;
1289 //_referenceFactory->destroy(); // No destroy function defined.
1290 _referenceFactory
= 0;
1292 // _proxyFactory->destroy(); // No destroy function defined.
1297 _routerManager
->destroy();
1303 _locatorManager
->destroy();
1304 _locatorManager
= 0;
1307 if(_endpointFactoryManager
)
1309 _endpointFactoryManager
->destroy();
1310 _endpointFactoryManager
= 0;
1315 _pluginManager
->destroy();
1319 // No destroy function defined.
1320 // _dynamicLibraryList->destroy();
1321 _dynamicLibraryList
= 0;
1324 _adminFacets
.clear();
1326 _state
= StateDestroyed
;
1330 // Join with the thread pool threads outside the synchronization.
1332 if(clientThreadPool
)
1334 clientThreadPool
->joinWithAllThreads();
1336 if(serverThreadPool
)
1338 serverThreadPool
->joinWithAllThreads();
1340 if(endpointHostResolver
)
1342 endpointHostResolver
->getThreadControl().join();
1345 if(_initData
.properties
->getPropertyAsInt("Ice.Warn.UnusedProperties") > 0)
1347 set
<string
> unusedProperties
= static_cast<PropertiesI
*>(_initData
.properties
.get())->getUnusedProperties();
1348 if(unusedProperties
.size() != 0)
1350 Warning
out(_initData
.logger
);
1351 out
<< "The following properties were set but never read:";
1352 for(set
<string
>::const_iterator p
= unusedProperties
.begin(); p
!= unusedProperties
.end(); ++p
)
1361 IceInternal::UTF8BufferI::UTF8BufferI() :
1367 IceInternal::UTF8BufferI::~UTF8BufferI()
1373 IceInternal::UTF8BufferI::getMoreBytes(size_t howMany
, Byte
* firstUnused
)
1377 _buffer
= (Byte
*)malloc(howMany
);
1381 assert(firstUnused
!= 0);
1382 _offset
= firstUnused
- _buffer
;
1383 _buffer
= (Byte
*)realloc(_buffer
, _offset
+ howMany
);
1386 return _buffer
+ _offset
;
1390 IceInternal::UTF8BufferI::getBuffer()
1396 IceInternal::UTF8BufferI::reset()
1404 IceInternal::ProcessI::ProcessI(const CommunicatorPtr
& communicator
) :
1405 _communicator(communicator
)
1410 IceInternal::ProcessI::shutdown(const Current
&)
1412 _communicator
->shutdown();
1416 IceInternal::ProcessI::writeMessage(const string
& message
, Int fd
, const Current
&)
1422 cout
<< message
<< endl
;
1427 cerr
<< message
<< endl
;