// ********************************************************************** // // Copyright (c) 2001 // MutableRealms, Inc. // Huntsville, AL, USA // // All Rights Reserved // // ********************************************************************** #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WIN32 # include #endif #ifndef WIN32 # include # include # include #else # include #endif using namespace std; using namespace Ice; using namespace IceInternal; int Instance::_globalStateCounter = 0; IceUtil::Mutex* Instance::_globalStateMutex = new IceUtil::Mutex; #ifndef WIN32 string Instance::_identForOpenlog; #endif namespace IceInternal { class GlobalStateMutexDestroyer { public: ~GlobalStateMutexDestroyer() { delete Instance::_globalStateMutex; Instance::_globalStateMutex = 0; } }; static GlobalStateMutexDestroyer destroyer; } void IceInternal::incRef(Instance* p) { p->__incRef(); } void IceInternal::decRef(Instance* p) { p->__decRef(); } ::Ice::CommunicatorPtr IceInternal::Instance::communicator() { IceUtil::Mutex::Lock sync(*this); return _communicator; } ::Ice::PropertiesPtr IceInternal::Instance::properties() { IceUtil::Mutex::Lock sync(*this); return _properties; } ::Ice::LoggerPtr IceInternal::Instance::logger() { IceUtil::Mutex::Lock sync(*this); return _logger; } void IceInternal::Instance::logger(const ::Ice::LoggerPtr& logger) { IceUtil::Mutex::Lock sync(*this); _logger = logger; } TraceLevelsPtr IceInternal::Instance::traceLevels() { IceUtil::Mutex::Lock sync(*this); return _traceLevels; } ProxyFactoryPtr IceInternal::Instance::proxyFactory() { IceUtil::Mutex::Lock sync(*this); return _proxyFactory; } OutgoingConnectionFactoryPtr IceInternal::Instance::outgoingConnectionFactory() { IceUtil::Mutex::Lock sync(*this); return _outgoingConnectionFactory; } ObjectFactoryManagerPtr IceInternal::Instance::servantFactoryManager() { IceUtil::Mutex::Lock sync(*this); return _servantFactoryManager; } UserExceptionFactoryManagerPtr IceInternal::Instance::userExceptionFactoryManager() { IceUtil::Mutex::Lock sync(*this); return _userExceptionFactoryManager; } ObjectAdapterFactoryPtr IceInternal::Instance::objectAdapterFactory() { IceUtil::Mutex::Lock sync(*this); return _objectAdapterFactory; } ThreadPoolPtr IceInternal::Instance::threadPool() { IceUtil::Mutex::Lock sync(*this); return _threadPool; } string IceInternal::Instance::defaultProtocol() { // No synchronization necessary // IceUtil::Mutex::Lock sync(*this); return _defaultProtocol; } string IceInternal::Instance::defaultHost() { // No synchronization necessary // IceUtil::Mutex::Lock sync(*this); return _defaultHost; } IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const PropertiesPtr& properties) : _communicator(communicator), _properties(properties) { _globalStateMutex->lock(); if (++_globalStateCounter == 1) // Only on first call { string value; // Must be done before "Ice.Daemon" is checked value = _properties->getProperty("Ice.PrintProcessId"); if (atoi(value.c_str()) >= 1) { #ifdef WIN32 cout << _getpid() << endl; #else cout << getpid() << endl; #endif } #ifndef WIN32 value = _properties->getProperty("Ice.Daemon"); if (atoi(value.c_str()) >= 1) { value = _properties->getProperty("Ice.DaemonNoClose"); int noclose = atoi(value.c_str()); value = _properties->getProperty("Ice.DaemonNoChdir"); int nochdir = atoi(value.c_str()); if (daemon(nochdir, noclose) == -1) { --_globalStateCounter; _globalStateMutex->unlock(); SystemException ex(__FILE__, __LINE__); ex.error = getSystemErrno(); throw ex; } } #endif #ifndef WIN32 value = _properties->getProperty("Ice.UseSyslog"); if (atoi(value.c_str()) >= 1) { _identForOpenlog = _properties->getProperty("Ice.ProgramName"); if (_identForOpenlog.empty()) { _identForOpenlog = ""; } openlog(_identForOpenlog.c_str(), LOG_PID, LOG_USER); } #endif #ifdef WIN32 WORD version = MAKEWORD(1, 1); WSADATA data; if (WSAStartup(version, &data) != 0) { _globalStateMutex->unlock(); SocketException ex(__FILE__, __LINE__); ex.error = getSocketErrno(); throw ex; } #endif #ifndef WIN32 struct sigaction action; action.sa_handler = SIG_IGN; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGPIPE, &action, 0); #endif #ifdef WIN32 struct _timeb tb; _ftime(&tb); srand(tb.millitm); #else timeval tv; gettimeofday(&tv, 0); srand(tv.tv_usec); #endif } _globalStateMutex->unlock(); try { #ifndef WIN32 string value = _properties->getProperty("Ice.UseSyslog"); if (atoi(value.c_str()) >= 1) { _logger = new SysLoggerI; } else { _logger = new LoggerI; } #else _logger = new LoggerI; #endif _traceLevels = new TraceLevels(_properties); _proxyFactory = new ProxyFactory(this); _outgoingConnectionFactory = new OutgoingConnectionFactory(this); _servantFactoryManager = new ObjectFactoryManager(); _userExceptionFactoryManager = new UserExceptionFactoryManager(); _objectAdapterFactory = new ObjectAdapterFactory(this); _threadPool = new ThreadPool(this); _defaultProtocol = _properties->getProperty("Ice.DefaultProtocol"); if (_defaultProtocol.empty()) { _defaultProtocol = "tcp"; } _defaultHost = _properties->getProperty("Ice.DefaultHost"); if (_defaultHost.empty()) { _defaultHost = getLocalHost(true); } } catch(...) { destroy(); throw; } } IceInternal::Instance::~Instance() { assert(!_communicator); assert(!_properties); assert(!_logger); assert(!_traceLevels); assert(!_proxyFactory); assert(!_outgoingConnectionFactory); assert(!_servantFactoryManager); assert(!_userExceptionFactoryManager); assert(!_objectAdapterFactory); assert(!_threadPool); if (_globalStateMutex != 0) { _globalStateMutex->lock(); } assert(_globalStateCounter > 0); if (--_globalStateCounter == 0) // Only on last call { #ifdef WIN32 WSACleanup(); #endif #ifndef WIN32 struct sigaction action; action.sa_handler = SIG_DFL; sigemptyset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGPIPE, &action, 0); #endif #ifndef WIN32 if (!_identForOpenlog.empty()) { closelog(); _identForOpenlog.clear(); } #endif } if (_globalStateMutex != 0) { _globalStateMutex->unlock(); } } void IceInternal::Instance::destroy() { IceUtil::Mutex::Lock sync(*this); // // Destroy all contained objects. Then set all references to null, // to avoid cyclic object dependencies. // if(_communicator) { // Don't destroy the communicator -- the communicator destroys // this object, not the other way _communicator = 0; } if(_properties) { // No destroy function defined // _properties->destroy(); _properties = 0; } if(_logger) { _logger->destroy(); _logger = 0; } if(_traceLevels) { // No destroy function defined // _traceLevels->destroy(); _traceLevels = 0; } if(_proxyFactory) { // No destroy function defined // _proxyFactory->destroy(); _proxyFactory = 0; } if(_outgoingConnectionFactory) { _outgoingConnectionFactory->destroy(); _outgoingConnectionFactory = 0; } if(_servantFactoryManager) { _servantFactoryManager->destroy(); _servantFactoryManager = 0; } if(_userExceptionFactoryManager) { _userExceptionFactoryManager->destroy(); _userExceptionFactoryManager = 0; } if(_objectAdapterFactory) { _objectAdapterFactory->shutdown(); // ObjectAdapterFactory has shutdown(), not destroy() _objectAdapterFactory = 0; } if(_threadPool) { _threadPool->waitUntilFinished(); _threadPool->destroy(); _threadPool->joinWithAllThreads(); _threadPool = 0; } }