ICE 3.4.2
[php5-ice-freebsdport.git] / cpp / src / Ice / Instance.cpp
blob220da4c0d25a1e07ba61990182319870d8f36cea
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/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>
45 #include <stdio.h>
47 #ifndef _WIN32
48 # include <Ice/SysLoggerI.h>
50 # include <signal.h>
51 # include <syslog.h>
52 # include <pwd.h>
53 # include <sys/types.h>
54 #endif
56 using namespace std;
57 using namespace Ice;
58 using namespace IceInternal;
60 namespace IceUtilInternal
63 extern bool ICE_DECLSPEC_IMPORT nullHandleAbort;
64 extern bool ICE_DECLSPEC_IMPORT printStackTraces;
68 namespace
71 IceUtil::Mutex* staticMutex = 0;
72 bool oneOffDone = false;
73 int instanceCount = 0;
74 #ifndef _WIN32
75 struct sigaction oldAction;
76 #endif
77 bool printProcessIdDone = false;
78 string identForOpenlog;
80 class Init
82 public:
84 Init()
86 staticMutex = new IceUtil::Mutex;
89 ~Init()
91 delete staticMutex;
92 staticMutex = 0;
96 Init init;
100 IceUtil::Shared* IceInternal::upCast(Instance* p) { return p; }
102 bool
103 IceInternal::Instance::destroyed() const
105 IceUtil::RecMutex::Lock sync(*this);
106 return _state == StateDestroyed;
109 TraceLevelsPtr
110 IceInternal::Instance::traceLevels() const
112 // No mutex lock, immutable.
113 assert(_traceLevels);
114 return _traceLevels;
117 DefaultsAndOverridesPtr
118 IceInternal::Instance::defaultsAndOverrides() const
120 // No mutex lock, immutable.
121 assert(_defaultsAndOverrides);
122 return _defaultsAndOverrides;
125 RouterManagerPtr
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;
139 LocatorManagerPtr
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;
153 ReferenceFactoryPtr
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;
167 ProxyFactoryPtr
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;
195 ConnectionMonitorPtr
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;
237 ProtocolSupport
238 IceInternal::Instance::protocolSupport() const
240 IceUtil::RecMutex::Lock sync(*this);
242 if(_state == StateDestroyed)
244 throw CommunicatorDestroyedException(__FILE__, __LINE__);
247 return _protocolSupport;
250 ThreadPoolPtr
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;
264 ThreadPoolPtr
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;
297 RetryQueuePtr
298 IceInternal::Instance::retryQueue()
300 IceUtil::RecMutex::Lock sync(*this);
302 if(_state == StateDestroyed)
304 throw CommunicatorDestroyedException(__FILE__, __LINE__);
307 assert(_retryQueue);
308 return _retryQueue;
311 IceUtil::TimerPtr
312 IceInternal::Instance::timer()
314 IceUtil::RecMutex::Lock sync(*this);
316 if(_state == StateDestroyed)
318 throw CommunicatorDestroyedException(__FILE__, __LINE__);
320 assert(_timer);
321 return _timer;
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;
352 PluginManagerPtr
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.
370 return _clientACM;
374 IceInternal::Instance::serverACM() const
376 // No mutex lock, immutable.
377 return _serverACM;
380 Identity
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.
392 Identity ident;
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)
404 slash = pos;
406 else
409 // Extra unescaped slash found.
411 IdentityParseException ex(__FILE__, __LINE__);
412 ex.str = "unescaped backslash in identity `" + s + "'";
413 throw ex;
416 pos++;
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();
429 throw ex;
432 else
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();
442 throw ex;
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();
454 throw ex;
459 ident.name = Ice::UTF8ToNative(_initData.stringConverter, ident.name);
460 ident.category = Ice::UTF8ToNative(_initData.stringConverter, ident.category);
462 return ident;
465 string
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);
475 if(category.empty())
477 return IceUtilInternal::escapeString(name, "/");
479 else
481 return IceUtilInternal::escapeString(category, "/") + '/' + IceUtilInternal::escapeString(name, "/");
485 Ice::ObjectPrx
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") == "")
503 return 0;
505 else
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
529 // Create OA
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);
544 else
546 filteredFacets[p->first] = p->second;
549 _adminFacets.swap(filteredFacets);
551 ObjectAdapterPtr adapter = _adminAdapter;
552 sync.release();
555 // Activate OA
559 adapter->activate();
561 catch(...)
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
568 adapter->destroy();
569 sync.acquire();
570 _adminAdapter = 0;
571 throw;
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 '" +
596 serverId + "'");
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;
605 throw;
609 if(_traceLevels->location >= 1)
611 Trace out(_initData.logger, _traceLevels->locationCat);
612 out << "registered server `" + serverId + "' with the locator registry";
615 return admin;
617 else
619 return 0;
624 void
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);
641 else
643 _adminAdapter->addFacet(servant, _adminIdentity, facet);
647 Ice::ObjectPtr
648 IceInternal::Instance::removeAdminFacet(const string& facet)
650 IceUtil::RecMutex::Lock sync(*this);
652 if(_state == StateDestroyed)
654 throw CommunicatorDestroyedException(__FILE__, __LINE__);
657 ObjectPtr result;
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);
666 else
668 result = p->second;
669 _adminFacets.erase(p);
672 else
674 result = _adminAdapter->removeFacet(_adminIdentity, facet);
676 return result;
679 void
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);
692 void
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);
705 void
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;
714 void
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;
723 void
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;
732 void
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) :
742 _state(StateActive),
743 _initData(initData),
744 _messageSizeMax(0),
745 _clientACM(0),
746 _serverACM(0),
747 _implicitContext(0)
751 __setNoDelete(true);
753 IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(staticMutex);
754 instanceCount++;
756 if(!_initData.properties)
758 _initData.properties = createProperties();
761 if(!oneOffDone)
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);
773 #else
774 #ifdef _WIN32
775 FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter,
776 stdOutFilename)).c_str(),
777 L"a", stdout);
778 #else
779 FILE* file = freopen(stdOutFilename.c_str(), "a", stdout);
780 #endif
781 #endif
782 if(file == 0)
784 FileException ex(__FILE__, __LINE__);
785 ex.path = stdOutFilename;
786 ex.error = getSystemErrno();
787 throw ex;
791 if(stdErrFilename != "")
793 #ifdef _LARGEFILE64_SOURCE
794 FILE* file = freopen64(stdErrFilename.c_str(), "a", stderr);
795 #else
796 #ifdef _WIN32
797 FILE* file = _wfreopen(IceUtil::stringToWstring(nativeToUTF8(_initData.stringConverter,
798 stdErrFilename)).c_str(),
799 L"a", stderr);
800 #else
801 FILE* file = freopen(stdErrFilename.c_str(), "a", stderr);
802 #endif
803 #endif
804 if(file == 0)
806 FileException ex(__FILE__, __LINE__);
807 ex.path = stdErrFilename;
808 ex.error = getSystemErrno();
809 throw ex;
813 if(_initData.properties->getPropertyAsInt("Ice.NullHandleAbort") > 0)
815 IceUtilInternal::nullHandleAbort = true;
818 #ifdef NDEBUG
819 if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 0) > 0)
820 #else
821 if(_initData.properties->getPropertyAsIntWithDefault("Ice.PrintStackTraces", 1) > 0)
822 #endif
824 IceUtilInternal::printStackTraces = true;
827 #ifndef _WIN32
828 string newUser = _initData.properties->getProperty("Ice.ChangeUser");
829 if(!newUser.empty())
831 struct passwd* pw = getpwnam(newUser.c_str());
832 if(!pw)
834 SyscallException ex(__FILE__, __LINE__);
835 ex.error = getSystemErrno();
836 throw ex;
839 if(setgid(pw->pw_gid) == -1)
841 SyscallException ex(__FILE__, __LINE__);
842 ex.error = getSystemErrno();
843 throw ex;
846 if(setuid(pw->pw_uid) == -1)
848 SyscallException ex(__FILE__, __LINE__);
849 ex.error = getSystemErrno();
850 throw ex;
853 #endif
854 oneOffDone = true;
857 if(instanceCount == 1)
860 #ifdef _WIN32
861 WORD version = MAKEWORD(1, 1);
862 WSADATA data;
863 if(WSAStartup(version, &data) != 0)
865 SocketException ex(__FILE__, __LINE__);
866 ex.error = getSocketErrno();
867 throw ex;
869 #endif
871 #ifndef _WIN32
872 struct sigaction action;
873 action.sa_handler = SIG_IGN;
874 sigemptyset(&action.sa_mask);
875 action.sa_flags = 0;
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);
886 #endif
891 if(!_initData.logger)
893 string logfile = _initData.properties->getProperty("Ice.LogFile");
894 #ifndef _WIN32
895 if(_initData.properties->getPropertyAsInt("Ice.UseSyslog") > 0)
897 if(!logfile.empty())
899 throw InitializationException(__FILE__, __LINE__, "Both syslog and file logger cannot be enabled.");
902 _initData.logger =
903 new SysLoggerI(_initData.properties->getProperty("Ice.ProgramName"),
904 _initData.properties->getPropertyWithDefault("Ice.SyslogFacility", "LOG_USER"));
906 else
907 #endif
908 if(!logfile.empty())
910 _initData.logger = new LoggerI(_initData.properties->getProperty("Ice.ProgramName"),
911 nativeToUTF8(_initData.stringConverter, logfile));
913 else
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);
926 if(num < 1)
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);
934 else
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;
959 if(!ipv4 && !ipv6)
961 throw InitializationException(__FILE__, __LINE__, "Both IPV4 and IPv6 support cannot be disabled.");
963 else if(ipv4 && ipv6)
965 _protocolSupport = EnableBoth;
967 else if(ipv4)
969 _protocolSupport = EnableIPv4;
971 else
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);
1015 catch(...)
1018 IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(staticMutex);
1019 --instanceCount;
1021 destroy();
1022 __setNoDelete(false);
1023 throw;
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);
1041 assert(!_timer);
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)
1051 #ifdef _WIN32
1052 WSACleanup();
1053 #endif
1055 #ifndef _WIN32
1056 sigaction(SIGPIPE, &oldAction, 0);
1058 if(!identForOpenlog.empty())
1060 closelog();
1061 identForOpenlog.clear();
1063 #endif
1067 void
1068 IceInternal::Instance::finishSetup(int& argc, char* argv[])
1071 // Load plug-ins.
1073 assert(!_serverThreadPool);
1074 PluginManagerI* pluginManagerImpl = dynamic_cast<PluginManagerI*>(_pluginManager.get());
1075 assert(pluginManagerImpl);
1076 pluginManagerImpl->loadPlugins(argc, argv);
1080 // Create threads.
1084 bool hasPriority = _initData.properties->getProperty("Ice.ThreadPriority") != "";
1085 int priority = _initData.properties->getPropertyAsInt("Ice.ThreadPriority");
1086 if(hasPriority)
1088 _timer = new IceUtil::Timer(priority);
1090 else
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;
1099 throw;
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;
1110 throw;
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"));
1121 if(router)
1123 _referenceFactory = _referenceFactory->setDefaultRouter(router);
1126 LocatorPrx locator = LocatorPrx::uncheckedCast(_proxyFactory->propertyToProxy("Ice.Default.Locator"));
1127 if(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;
1150 if(printProcessId)
1152 #ifdef _MSC_VER
1153 cout << _getpid() << endl;
1154 #else
1155 cout << getpid() << endl;
1156 #endif
1160 // Create the connection monitor and ensure the interval for
1161 // monitoring connections is appropriate for client & server
1162 // ACM.
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
1175 // plug-ins.
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)
1189 getAdmin();
1193 bool
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)
1205 return false;
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();
1237 if(_retryQueue)
1239 _retryQueue->destroy();
1242 ThreadPoolPtr serverThreadPool;
1243 ThreadPoolPtr clientThreadPool;
1244 EndpointHostResolverPtr endpointHostResolver;
1247 IceUtil::RecMutex::Lock sync(*this);
1249 _objectAdapterFactory = 0;
1250 _outgoingConnectionFactory = 0;
1251 _retryQueue = 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);
1277 if(_timer)
1279 _timer->destroy();
1280 _timer = 0;
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.
1293 _proxyFactory = 0;
1295 if(_routerManager)
1297 _routerManager->destroy();
1298 _routerManager = 0;
1301 if(_locatorManager)
1303 _locatorManager->destroy();
1304 _locatorManager = 0;
1307 if(_endpointFactoryManager)
1309 _endpointFactoryManager->destroy();
1310 _endpointFactoryManager = 0;
1313 if(_pluginManager)
1315 _pluginManager->destroy();
1316 _pluginManager = 0;
1319 // No destroy function defined.
1320 // _dynamicLibraryList->destroy();
1321 _dynamicLibraryList = 0;
1323 _adminAdapter = 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)
1354 out << "\n " << *p;
1358 return true;
1361 IceInternal::UTF8BufferI::UTF8BufferI() :
1362 _buffer(0),
1363 _offset(0)
1367 IceInternal::UTF8BufferI::~UTF8BufferI()
1369 free(_buffer);
1372 Byte*
1373 IceInternal::UTF8BufferI::getMoreBytes(size_t howMany, Byte* firstUnused)
1375 if(_buffer == 0)
1377 _buffer = (Byte*)malloc(howMany);
1379 else
1381 assert(firstUnused != 0);
1382 _offset = firstUnused - _buffer;
1383 _buffer = (Byte*)realloc(_buffer, _offset + howMany);
1386 return _buffer + _offset;
1389 Byte*
1390 IceInternal::UTF8BufferI::getBuffer()
1392 return _buffer;
1395 void
1396 IceInternal::UTF8BufferI::reset()
1398 free(_buffer);
1399 _buffer = 0;
1400 _offset = 0;
1404 IceInternal::ProcessI::ProcessI(const CommunicatorPtr& communicator) :
1405 _communicator(communicator)
1409 void
1410 IceInternal::ProcessI::shutdown(const Current&)
1412 _communicator->shutdown();
1415 void
1416 IceInternal::ProcessI::writeMessage(const string& message, Int fd, const Current&)
1418 switch(fd)
1420 case 1:
1422 cout << message << endl;
1423 break;
1425 case 2:
1427 cerr << message << endl;
1428 break;