diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/demo/Glacier2/callback/Client.cpp | 118 | ||||
-rwxr-xr-x | cpp/demo/Glacier2/callback/expect.py | 4 | ||||
-rw-r--r-- | cpp/include/Glacier2/Application.h | 222 | ||||
-rw-r--r-- | cpp/include/Ice/Application.h | 36 | ||||
-rw-r--r-- | cpp/src/Glacier2/Application.cpp | 426 | ||||
-rw-r--r-- | cpp/src/Glacier2/Makefile | 3 | ||||
-rw-r--r-- | cpp/src/Glacier2/Makefile.mak | 5 | ||||
-rw-r--r-- | cpp/src/Ice/Application.cpp | 194 |
8 files changed, 820 insertions, 188 deletions
diff --git a/cpp/demo/Glacier2/callback/Client.cpp b/cpp/demo/Glacier2/callback/Client.cpp index 4c1416db640..4c744819014 100644 --- a/cpp/demo/Glacier2/callback/Client.cpp +++ b/cpp/demo/Glacier2/callback/Client.cpp @@ -10,44 +10,20 @@ #include <IceUtil/IceUtil.h> #include <Ice/Ice.h> #include <Glacier2/Router.h> +#include <Glacier2/Application.h> #include <CallbackI.h> using namespace std; using namespace Demo; -class PingTask : public IceUtil::TimerTask -{ -public: - - PingTask(const Glacier2::RouterPrx& router) : - _router(router) - { - } - - virtual void runTimerTask() - { - try - { - _router->refreshSession(); - } - catch(const Ice::Exception&) - { - // Ignore - } - } - -private: - - const Glacier2::RouterPrx _router; -}; - -class CallbackClient : public Ice::Application +class CallbackClient : public Glacier2::Application { public: CallbackClient(); - - virtual int run(int, char*[]); + + virtual int runWithSession(int, char**); + virtual Glacier2::SessionPrx createSession(); }; int @@ -78,34 +54,15 @@ CallbackClient::CallbackClient() : // Since this is an interactive demo we don't want any signal // handling. // - Ice::Application(Ice::NoSignalHandling) + Glacier2::Application(Ice::NoSignalHandling) { } -int -CallbackClient::run(int argc, char* argv[]) +Glacier2::SessionPrx +CallbackClient::createSession() { - if(argc > 1) - { - cerr << appName() << ": too many arguments" << endl; - return EXIT_FAILURE; - } - - Ice::RouterPrx defaultRouter = communicator()->getDefaultRouter(); - if(!defaultRouter) - { - cerr << argv[0] << ": no default router set" << endl; - return EXIT_FAILURE; - } - - Glacier2::RouterPrx router = Glacier2::RouterPrx::checkedCast(defaultRouter); - if(!router) - { - cerr << argv[0] << ": configured router is not a Glacier2 router" << endl; - return EXIT_FAILURE; - } - - while(true) + Glacier2::SessionPrx session; + while(true) { cout << "This demo accepts any user-id / password combination.\n"; @@ -122,21 +79,32 @@ CallbackClient::run(int argc, char* argv[]) #if defined(__BCPLUSPLUS__) && (__BCPLUSPLUS__ >= 0x0600) IceUtil::DummyBCC dummy; #endif - router->createSession(id, pw); + router()->createSession(id, pw); break; } catch(const Glacier2::PermissionDeniedException& ex) { cout << "permission denied:\n" << ex.reason << endl; } + catch(const Glacier2::CannotCreateSessionException ex) + { + cout << "cannot create session:\n" << ex.reason << endl; + } } + return session; +} - IceUtil::TimerPtr timer = new IceUtil::Timer(); - timer->scheduleRepeated(new PingTask(router), IceUtil::Time::milliSeconds(router->getSessionTimeout() * 500)); +int +CallbackClient::runWithSession(int argc, char* argv[]) +{ + if(argc > 1) + { + cerr << appName() << ": too many arguments" << endl; + return EXIT_FAILURE; + } - Ice::Identity callbackReceiverIdent; - callbackReceiverIdent.name = "callbackReceiver"; - callbackReceiverIdent.category = router->getCategoryForClient(); + Ice::Identity callbackReceiverIdent = createCallbackIdentity("callbackReceiver"); + Ice::Identity callbackReceiverFakeIdent; callbackReceiverFakeIdent.name = "callbackReceiver"; callbackReceiverFakeIdent.category = "fake"; @@ -146,12 +114,13 @@ CallbackClient::run(int argc, char* argv[]) CallbackPrx oneway = CallbackPrx::uncheckedCast(twoway->ice_oneway()); CallbackPrx batchOneway = CallbackPrx::uncheckedCast(twoway->ice_batchOneway()); - Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapterWithRouter("Callback.Client", defaultRouter); - adapter->add(new CallbackReceiverI, callbackReceiverIdent); - adapter->add(new CallbackReceiverI, callbackReceiverFakeIdent); // Should never be called for the fake identity. - adapter->activate(); + objectAdapter()->add(new CallbackReceiverI, callbackReceiverIdent); + + // Should never be called for the fake identity. + objectAdapter()->add(new CallbackReceiverI, callbackReceiverFakeIdent); - CallbackReceiverPrx twowayR = CallbackReceiverPrx::uncheckedCast(adapter->createProxy(callbackReceiverIdent)); + CallbackReceiverPrx twowayR = CallbackReceiverPrx::uncheckedCast( + objectAdapter()->createProxy(callbackReceiverIdent)); CallbackReceiverPrx onewayR = CallbackReceiverPrx::uncheckedCast(twowayR->ice_oneway()); string override; @@ -256,27 +225,6 @@ CallbackClient::run(int argc, char* argv[]) } while(cin.good() && c != 'x'); - // - // Destroy the timer before the router session is destroyed, - // otherwise it might get a spurious ObjectNotExistException. - // - timer->destroy(); - - try - { - router->destroySession(); - } - catch(const Glacier2::SessionNotExistException& ex) - { - cerr << ex << endl; - } - catch(const Ice::ConnectionLostException&) - { - // - // Expected: the router closed the connection. - // - } - return EXIT_SUCCESS; } diff --git a/cpp/demo/Glacier2/callback/expect.py b/cpp/demo/Glacier2/callback/expect.py index 7085c18ada9..bebd86b2115 100755 --- a/cpp/demo/Glacier2/callback/expect.py +++ b/cpp/demo/Glacier2/callback/expect.py @@ -24,8 +24,6 @@ from demoscript.Glacier2 import callback server = Util.spawn('./server --Ice.PrintAdapterReady') server.expect('.* ready') -sessionserver = Util.spawn('./sessionserver --Ice.PrintAdapterReady') -sessionserver.expect('.* ready') glacier2 = Util.spawn('glacier2router --Ice.Config=config.glacier2 --Ice.PrintAdapterReady --Glacier2.SessionTimeout=5') glacier2.expect('Glacier2.Client ready') @@ -33,4 +31,4 @@ glacier2.expect('Glacier2.Server ready') client = Util.spawn('./client') -callback.run(client, server, sessionserver, glacier2) +callback.run(client, server, glacier2) diff --git a/cpp/include/Glacier2/Application.h b/cpp/include/Glacier2/Application.h new file mode 100644 index 00000000000..6519ce7cc88 --- /dev/null +++ b/cpp/include/Glacier2/Application.h @@ -0,0 +1,222 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <exception> + +#include <Ice/Application.h> + +#include <Glacier2/Session.h> +#include <Glacier2/Router.h> + +namespace Glacier2 +{ + +/** + * + * This exception is raised if the session should be restarted. + * + **/ +class GLACIER2_API RestartSessionException : public IceUtil::Exception +{ +public: + + virtual std::string ice_name() const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; +}; + +/** + * An extension of Ice.Application that makes it easy to write + * Glacier2 applications. + * + * <p> Applications must create a derived class that implements the + * {@link #createSession} and {@link #runWithSession} methods.<p> + * + * The base class invokes {@link #createSession} to create a new + * Glacier2 session and then invokes {@link #runWithSession} in + * which the subclass performs its application logic. The base class + * automatically destroys the session when {@link #runWithSession} + * returns. + * + * If {@link #runWithSession} calls {@link #restart} or raises any of + * the exceptions Ice.ConnectionRefusedException, + * Ice.ConnectionLostException, Ice.UnknownLocalException, + * Ice.RequestFailedException, or Ice.TimeoutException, the base + * class destroys the current session and restarts the application + * with another call to {@link #createSession} followed by + * {@link #runWithSession}. + * + * The application can optionally override the {@link #sessionDestroyed} + * callback method if it needs to take action when connectivity with + * the Glacier2 router is lost. + * + * A program can contain only one instance of this class. + * + * @see Ice.Application + * @see Glacier2.Router + * @see Glacier2.Session + * @see Ice.Communicator + * @see Ice.Logger + * @see #runWithSession + **/ + +class GLACIER2_API Application : public Ice::Application +{ + /** + * Initializes an instance that calls {@link Communicator#shutdown} if + * a signal is received. + **/ +public: + + Application() + { + } + + /** + * Initializes an instance that handles signals according to the signal + * policy. + * + * @param signalPolicy Determines how to respond to signals. + * + * @see SignalPolicy + **/ + Application(Ice::SignalPolicy signalPolicy) : Ice::Application(signalPolicy) + { + } + + + /** + * Called once the communicator has been initialized and the Glacier2 session + * has been established. A derived class must implement <code>runWithSession</code>, + * which is the application's starting method. + * + * @param argc The number of elements in argv. + * + * @param argv The argument vector for the application. <code>Application</code> + * scans the argument vector passed to <code>main</code> for options that are + * specific to the Ice run time and removes them; therefore, the vector passed + * to <code>run</code> is free from Ice-related options and contains only options + * and arguments that are application-specific. + * + * @return The <code>runWithSession</code> method should return zero for successful + * termination, and non-zero otherwise. <code>Application.main</code> returns the + * value returned by <code>runWithSession</code>. + **/ + virtual int runWithSession(int argc, char* argv[]) = 0; + + + /** + * Creates a new Glacier2 session. A call to + * <code>createSession</code> always precedes a call to + * <code>runWithSession</code>. If <code>Ice.LocalException</code> + * is thrown from this method, the application is terminated. + + * @return The Glacier2 session. + **/ + virtual Glacier2::SessionPrx createSession() = 0; + + /** + * Called to restart the application's Glacier2 session. This + * method never returns. + * + * @throws RestartSessionException This exception is always thrown. + **/ + void restart() + { + RestartSessionException ex; + throw ex; + } + + /** + * Called when the base class detects that the session has been destroyed. + * A subclass can override this method to take action after the loss of + * connectivity with the Glacier2 router. + **/ + virtual void sessionDestroyed() + { + } + + /** + * Returns the Glacier2 router proxy + * @return The router proxy. + **/ + static Glacier2::RouterPrx router() + { + return _router; + } + + /** + * Returns the Glacier2 session proxy + * @return The session proxy. + **/ + static Glacier2::SessionPrx session() + { + return _session; + } + + /** + * Returns the category to be used in the identities of all of the client's + * callback objects. Clients must use this category for the router to + * forward callback requests to the intended client. + * @return The category. + * @throws SessionNotExistException No session exists. + **/ + std::string categoryForClient(); + + + /** + * Create a new Ice identity for callback objects with the given + * identity name field. + * @return The identity. + **/ + Ice::Identity createCallbackIdentity(const std::string&); + + /** + * Adds a servant to the callback object adapter's Active Servant Map with a UUID. + * @param servant The servant to add. + * @return The proxy for the servant. + **/ + Ice::ObjectPrx addWithUUID(const Ice::ObjectPtr& servant); + + /** + * Creates an object adapter for callback objects. + * @return The object adapter. + */ + Ice::ObjectAdapterPtr objectAdapter(); + +protected: + + virtual int + doMain(int, char*[], const Ice::InitializationData& initData); + +private: + + bool + doMain(Ice::StringSeq&, const Ice::InitializationData&, int&); + + /** + * Run should not be overridden for Glacier2.Application. Instead + * <code>runWithSession</code> should be used. + */ + int run(int, char**) + { + // This shouldn't be called. + assert(false); + return 0; + } + + + static Ice::ObjectAdapterPtr _adapter; + static Glacier2::RouterPrx _router; + static Glacier2::SessionPrx _session; + static bool _createdSession; +}; + +} + diff --git a/cpp/include/Ice/Application.h b/cpp/include/Ice/Application.h index 1ffc86572e4..f8ac4ebae9b 100644 --- a/cpp/include/Ice/Application.h +++ b/cpp/include/Ice/Application.h @@ -12,10 +12,40 @@ #include <Ice/Ice.h> +#include <IceUtil/Mutex.h> + + namespace Ice { + enum SignalPolicy { HandleSignals, NoSignalHandling } ; + class Application; +} -enum SignalPolicy { HandleSignals, NoSignalHandling } ; +namespace IceInternal +{ + extern ICE_API IceUtil::Mutex* mutex; + extern ICE_API std::auto_ptr<IceUtil::Cond> _condVar; + + // + // Variables than can change while run() and communicator->destroy() are running! + // + extern ICE_API bool _callbackInProgress; + extern ICE_API bool _destroyed; + extern ICE_API bool _interrupted; + + // + // Variables that are immutable during run() and until communicator->destroy() has returned; + // before and after run(), and once communicator->destroy() has returned, we assume that + // only the main thread and CtrlCHandler threads are running. + // + extern ICE_API std::string _appName; + extern ICE_API Ice::CommunicatorPtr _communicator; + extern ICE_API Ice::SignalPolicy _signalPolicy; + extern ICE_API Ice::Application* _application; +} + +namespace Ice +{ class ICE_API Application : private IceUtil::noncopyable { @@ -96,9 +126,9 @@ public: // static bool interrupted(); -private: +protected: - int mainInternal(int, char*[], const Ice::InitializationData&); + virtual int doMain(int, char*[], const Ice::InitializationData&); #if defined(__SUNPRO_CC) // diff --git a/cpp/src/Glacier2/Application.cpp b/cpp/src/Glacier2/Application.cpp new file mode 100644 index 00000000000..ac5b1dd9f8a --- /dev/null +++ b/cpp/src/Glacier2/Application.cpp @@ -0,0 +1,426 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Glacier2/Application.h> +#include <IceUtil/IceUtil.h> +#include <IceUtil/ArgVector.h> + +using namespace std; +using namespace Ice; + +Ice::ObjectAdapterPtr Glacier2::Application::_adapter; +Glacier2::RouterPrx Glacier2::Application::_router; +Glacier2::SessionPrx Glacier2::Application::_session; +bool Glacier2::Application::_createdSession = false; + +namespace +{ + +class SessionPingThread : virtual public IceUtil::Shared +{ + +public: + + virtual void done() = 0; +}; +typedef IceUtil::Handle<SessionPingThread> SessionPingThreadPtr; + +class AMI_Router_refreshSessionI : public Glacier2::AMI_Router_refreshSession +{ + +public: + + AMI_Router_refreshSessionI(Glacier2::Application* app, const SessionPingThreadPtr& pinger) : + _app(app), + _pinger(pinger) + { + } + + void + ice_response() + { + } + + void + ice_exception(const Ice::Exception& ex) + { + // Here the session has gone. The thread + // terminates, and we notify the + // application that the session has been + // destroyed. + _pinger->done(); + _app->sessionDestroyed(); + } + +private: + + Glacier2::Application* _app; + SessionPingThreadPtr _pinger; +}; + +class SessionPingThreadI : virtual public IceUtil::Thread, virtual public SessionPingThread +{ + +public: + + SessionPingThreadI(Glacier2::Application* app, const Glacier2::RouterPrx& router, long period) : + _app(app), + _router(router), + _period(period), + _done(false) + { + } + + void + run() + { + IceUtil::Monitor<IceUtil::Mutex>::Lock lock(_monitor); + while(true) + { + _router->refreshSession_async(new AMI_Router_refreshSessionI(_app, this)); + + if(!_done) + { + _monitor.timedWait(IceUtil::Time::seconds((int)_period)); + } + if(_done) + { + break; + } + } + } + + void + done() + { + IceUtil::Monitor<IceUtil::Mutex>::Lock lock(_monitor); + if(!_done) + { + _done = true; + _monitor.notify(); + } + } + +private: + + Glacier2::Application* _app; + Glacier2::RouterPrx _router; + long _period; + bool _done; + IceUtil::Monitor<IceUtil::Mutex> _monitor; +}; +typedef IceUtil::Handle<SessionPingThreadI> SessionPingThreadIPtr; + +} + +string +Glacier2::RestartSessionException::ice_name() const +{ + return "RestartSessionException"; +} + +Exception* +Glacier2::RestartSessionException::ice_clone() const +{ + return new RestartSessionException(*this); +} + +void +Glacier2::RestartSessionException::ice_throw() const +{ + throw *this; +} + +Ice::ObjectAdapterPtr +Glacier2::Application::objectAdapter() +{ + if(!_adapter) + { + // TODO: Depending on the resolution of + // http://bugzilla/bugzilla/show_bug.cgi?id=4264 the OA + // name could be an empty string. + _adapter = communicator()->createObjectAdapterWithRouter(IceUtil::generateUUID(), router()); + _adapter->activate(); + } + return _adapter; +} + +Ice::ObjectPrx +Glacier2::Application::addWithUUID(const Ice::ObjectPtr& servant) +{ + return objectAdapter()->add(servant, createCallbackIdentity(IceUtil::generateUUID())); +} + +Ice::Identity +Glacier2::Application::createCallbackIdentity(const string& name) +{ + Ice::Identity id; + id.name = name; + id.category = categoryForClient(); + return id; +} + +std::string +Glacier2::Application::categoryForClient() +{ + if(!_router) + { + SessionNotExistException ex; + throw ex; + } + return router()->getCategoryForClient(); +} + +int +Glacier2::Application::doMain(int argc, char* argv[], const Ice::InitializationData& initData) +{ + // Set the default properties for all Glacier2 applications. + initData.properties->setProperty("Ice.ACM.Client", "0"); + initData.properties->setProperty("Ice.RetryIntervals", "-1"); + + bool restart; + int ret = 0; + do + { + // A copy of the initialization data and the string seq + // needs to be passed to doMainInternal, as these can be + // changed by the application. + Ice::InitializationData id(initData); + id.properties = id.properties->clone(); + Ice::StringSeq args = Ice::argsToStringSeq(argc, argv); + + restart = doMain(args, id, ret); + } + while(restart); + return ret; +} + +bool +Glacier2::Application::doMain(Ice::StringSeq& args, const Ice::InitializationData& initData, int& status) +{ + // Reset internal state variables from Ice.Application. The + // remainder are reset at the end of this method. + IceInternal::_callbackInProgress = false; + IceInternal::_destroyed = false; + IceInternal::_interrupted = false; + + bool restart = false; + status = 0; + + SessionPingThreadIPtr ping; + try + { + IceInternal::_communicator = Ice::initialize(args, initData); + _router = Glacier2::RouterPrx::uncheckedCast(communicator()->getDefaultRouter()); + + if(!_router) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": no glacier2 router configured"; + status = 1; + } + else + { + // + // The default is to destroy when a signal is received. + // + if(IceInternal::_signalPolicy == Ice::HandleSignals) + { + destroyOnInterrupt(); + } + + // If createSession throws, we're done. + try + { + _session = createSession(); + _createdSession = true; + } + catch(const Ice::LocalException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + status = 1; + } + + if(_createdSession) + { + ping = new SessionPingThreadI(this, _router, (long)_router->getSessionTimeout() / 2); + ping->start(); + IceUtilInternal::ArgVector a(args); + status = runWithSession(a.argc, a.argv); + } + } + } + // We want to restart on those exceptions which indicate a + // break down in communications, but not those exceptions that + // indicate a programming logic error (ie: marshal, protocol + // failure, etc). + catch(const RestartSessionException&) + { + restart = true; + } + catch(const Ice::ConnectionRefusedException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + restart = true; + } + catch(const Ice::ConnectionLostException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + restart = true; + } + catch(const Ice::UnknownLocalException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + restart = true; + } + catch(const Ice::RequestFailedException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + restart = true; + } + catch(const Ice::TimeoutException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + restart = true; + } + catch(const Ice::LocalException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + status = 1; + } + catch(const std::exception& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": std::exception " << ex; + status = 1; + } + catch(const std::string& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": c++ exception " << ex; + status = 1; + } + catch(const char* ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": char* exception " << ex; + status = 1; + } + catch(...) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": unknow exception "; + status = 1; + } + + // + // Don't want any new interrupt and at this point (post-run), + // it would not make sense to release a held signal to run + // shutdown or destroy. + // + if(IceInternal::_signalPolicy == HandleSignals) + { + ignoreInterrupt(); + } + + { + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + while(IceInternal::_callbackInProgress) + { + IceInternal::_condVar->wait(lock); + } + if(IceInternal::_destroyed) + { + IceInternal::_communicator = 0; + } + else + { + IceInternal::_destroyed = true; + // + // And _communicator != 0, meaning will be destroyed + // next, _destroyed = true also ensures that any + // remaining callback won't do anything + // + } + IceInternal::_application = 0; + } + + if(!ping) + { + ping->done(); + while(true) + { + ping->getThreadControl().join(); + break; + } + ping = 0; + } + + if(_createdSession && _router) + { + try + { + _router->destroySession(); + } + catch(const Ice::ConnectionLostException&) + { + // Expected: the router closed the connection. + } + catch(const Glacier2::SessionNotExistException&) + { + // This can also occur. + } + catch(const exception& ex) + { + // Not expected. + Error out(getProcessLogger()); + out << "unexpected exception when destroying the session " << ex; + } + _router = 0; + } + + if(IceInternal::_communicator) + { + try + { + IceInternal::_communicator->destroy(); + } + catch(const Ice::LocalException& ex) + { + Error out(getProcessLogger()); + out << IceInternal::_appName << ": " << ex; + status = 1; + } + catch(const exception& ex) + { + Error out(getProcessLogger()); + out << "unknown exception " << ex; + status = 1; + } + IceInternal::_communicator = 0; + } + + + // Reset internal state. We cannot reset the Application state + // here, since _destroyed must remain true until we re-run + // this method. + _adapter = 0; + _router = 0; + _session = 0; + _createdSession = false; + + return restart; +} diff --git a/cpp/src/Glacier2/Makefile b/cpp/src/Glacier2/Makefile index f936fc95556..db08d6d3dda 100644 --- a/cpp/src/Glacier2/Makefile +++ b/cpp/src/Glacier2/Makefile @@ -21,7 +21,8 @@ TARGETS = $(LIBTARGETS) $(ROUTER) OBJS = PermissionsVerifier.o \ Router.o \ SSLInfo.o \ - Session.o + Session.o \ + Application.o ROBJS = Blobject.o \ ClientBlobject.o \ diff --git a/cpp/src/Glacier2/Makefile.mak b/cpp/src/Glacier2/Makefile.mak index 4d6b204ed0b..1243667d97a 100644 --- a/cpp/src/Glacier2/Makefile.mak +++ b/cpp/src/Glacier2/Makefile.mak @@ -19,7 +19,8 @@ TARGETS = $(LIBNAME) $(DLLNAME) $(ROUTER) OBJS = PermissionsVerifier.obj \
Router.obj \
SSLInfo.obj \
- Session.obj
+ Session.obj \
+ Application.obj
ROBJS = Blobject.obj \
ClientBlobject.obj \
@@ -43,7 +44,7 @@ SDIR = $(slicedir)\Glacier2 !include $(top_srcdir)\config\Make.rules.mak
-CPPFLAGS = -I.. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+CPPFLAGS = -I.. $(CPPFLAGS) -DGLACIER2_API_EXPORTS -DWIN32_LEAN_AND_MEAN
LINKWITH = $(LIBS) $(OPENSSL_LIBS) glacier2$(LIBSUFFIX).lib icessl$(LIBSUFFIX).lib
!if "$(BCPLUSPLUS)" != "yes"
LINKWITH = $(LINKWITH) ws2_32.lib
diff --git a/cpp/src/Ice/Application.cpp b/cpp/src/Ice/Application.cpp index bf256c66f27..c7e41882fee 100644 --- a/cpp/src/Ice/Application.cpp +++ b/cpp/src/Ice/Application.cpp @@ -21,6 +21,21 @@ using namespace Ice; using namespace IceUtil; using namespace IceUtilInternal; + +// +// static initializations. +// +Mutex* IceInternal::mutex = 0; + +bool IceInternal::_callbackInProgress = false; +bool IceInternal::_destroyed = false; +bool IceInternal::_interrupted = false; + +string IceInternal::_appName; +CommunicatorPtr IceInternal::_communicator; +SignalPolicy IceInternal::_signalPolicy = HandleSignals; +auto_ptr<Cond> IceInternal::_condVar; +Ice::Application* IceInternal::_application; // // _mutex and _condVar are used to synchronize the main thread and // the CtrlCHandler thread @@ -29,34 +44,29 @@ using namespace IceUtilInternal; namespace { -Mutex* mutex = 0; - class Init { public: Init() { - mutex = new IceUtil::Mutex; + IceInternal::mutex = new IceUtil::Mutex; } ~Init() { - delete mutex; - mutex = 0; + delete IceInternal::mutex; + IceInternal::mutex = 0; } }; Init init; -auto_ptr<Cond> _condVar; + // // Variables than can change while run() and communicator->destroy() are running! // -bool _callbackInProgress = false; -bool _destroyed = false; -bool _interrupted = false; bool _released = false; CtrlCHandlerCallback _previousCallback = 0; @@ -65,12 +75,8 @@ CtrlCHandlerCallback _previousCallback = 0; // before and after run(), and once communicator->destroy() has returned, we assume that // only the main thread and CtrlCHandler threads are running. // -string _appName; -Application* _application; -CommunicatorPtr _communicator; CtrlCHandler* _ctrlCHandler = 0; bool _nohup = false; -SignalPolicy _signalPolicy = HandleSignals; } @@ -97,13 +103,13 @@ holdInterruptCallback(int signal) { CtrlCHandlerCallback callback = 0; { - IceUtil::Mutex::Lock lock(*mutex); + IceUtil::Mutex::Lock lock(*IceInternal::mutex); while(!_released) { - _condVar->wait(lock); + IceInternal::_condVar->wait(lock); } - if(_destroyed) + if(IceInternal::_destroyed) { // // Being destroyed by main thread @@ -124,8 +130,8 @@ static void destroyOnInterruptCallback(int signal) { { - IceUtil::Mutex::Lock lock(*mutex); - if(_destroyed) + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + if(IceInternal::_destroyed) { // // Being destroyed by main thread @@ -137,16 +143,16 @@ destroyOnInterruptCallback(int signal) return; } - assert(!_callbackInProgress); - _callbackInProgress = true; - _interrupted = true; - _destroyed = true; + assert(!IceInternal::_callbackInProgress); + IceInternal::_callbackInProgress = true; + IceInternal::_interrupted = true; + IceInternal::_destroyed = true; } try { - assert(_communicator != 0); - _communicator->destroy(); + assert(IceInternal::_communicator != 0); + IceInternal::_communicator->destroy(); } catch(const std::exception& ex) { @@ -170,18 +176,18 @@ destroyOnInterruptCallback(int signal) } { - IceUtil::Mutex::Lock lock(*mutex); - _callbackInProgress = false; + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + IceInternal::_callbackInProgress = false; } - _condVar->signal(); + IceInternal::_condVar->signal(); } static void shutdownOnInterruptCallback(int signal) { { - IceUtil::Mutex::Lock lock(*mutex); - if(_destroyed) + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + if(IceInternal::_destroyed) { // // Being destroyed by main thread @@ -193,15 +199,15 @@ shutdownOnInterruptCallback(int signal) return; } - assert(!_callbackInProgress); - _callbackInProgress = true; - _interrupted = true; + assert(!IceInternal::_callbackInProgress); + IceInternal::_callbackInProgress = true; + IceInternal::_interrupted = true; } try { - assert(_communicator != 0); - _communicator->shutdown(); + assert(IceInternal::_communicator != 0); + IceInternal::_communicator->shutdown(); } catch(const std::exception& ex) { @@ -225,18 +231,18 @@ shutdownOnInterruptCallback(int signal) } { - IceUtil::Mutex::Lock lock(*mutex); - _callbackInProgress = false; + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + IceInternal::_callbackInProgress = false; } - _condVar->signal(); + IceInternal::_condVar->signal(); } static void callbackOnInterruptCallback(int signal) { { - IceUtil::Mutex::Lock lock(*mutex); - if(_destroyed) + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + if(IceInternal::_destroyed) { // // Being destroyed by main thread @@ -245,15 +251,15 @@ callbackOnInterruptCallback(int signal) } // For SIGHUP the user callback is always called. It can // decide what to do. - assert(!_callbackInProgress); - _callbackInProgress = true; - _interrupted = true; + assert(!IceInternal::_callbackInProgress); + IceInternal::_callbackInProgress = true; + IceInternal::_interrupted = true; } try { - assert(_application != 0); - _application->interruptCallback(signal); + assert(IceInternal::_application != 0); + IceInternal::_application->interruptCallback(signal); } catch(const std::exception& ex) { @@ -277,15 +283,15 @@ callbackOnInterruptCallback(int signal) } { - IceUtil::Mutex::Lock lock(*mutex); - _callbackInProgress = false; + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + IceInternal::_callbackInProgress = false; } - _condVar->signal(); + IceInternal::_condVar->signal(); } Ice::Application::Application(SignalPolicy signalPolicy) { - _signalPolicy = signalPolicy; + IceInternal::_signalPolicy = signalPolicy; } Ice::Application::~Application() @@ -342,7 +348,7 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initDat setProcessLogger(new LoggerI(argv[0], "")); } - if(_communicator != 0) + if(IceInternal::_communicator != 0) { Error out(getProcessLogger()); out << "only one instance of the Application class can be used"; @@ -350,7 +356,7 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initDat } int status; - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { try { @@ -361,7 +367,7 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initDat CtrlCHandler ctrCHandler; _ctrlCHandler = &ctrCHandler; - status = mainInternal(argc, argv, initData); + status = doMain(argc, argv, initData); // // Set _ctrlCHandler to 0 only once communicator->destroy() has completed. @@ -377,7 +383,7 @@ Ice::Application::main(int argc, char* argv[], const InitializationData& initDat } else { - status = mainInternal(argc, argv, initData); + status = doMain(argc, argv, initData); } return status; @@ -412,27 +418,27 @@ Ice::Application::interruptCallback(int) const char* Ice::Application::appName() { - return _appName.c_str(); + return IceInternal::_appName.c_str(); } CommunicatorPtr Ice::Application::communicator() { - return _communicator; + return IceInternal::_communicator; } void Ice::Application::destroyOnInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() == holdInterruptCallback) { _released = true; - _condVar->signal(); + IceInternal::_condVar->signal(); } _ctrlCHandler->setCallback(destroyOnInterruptCallback); } @@ -447,15 +453,15 @@ Ice::Application::destroyOnInterrupt() void Ice::Application::shutdownOnInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() == holdInterruptCallback) { _released = true; - _condVar->signal(); + IceInternal::_condVar->signal(); } _ctrlCHandler->setCallback(shutdownOnInterruptCallback); } @@ -470,15 +476,15 @@ Ice::Application::shutdownOnInterrupt() void Ice::Application::ignoreInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() == holdInterruptCallback) { _released = true; - _condVar->signal(); + IceInternal::_condVar->signal(); } _ctrlCHandler->setCallback(0); } @@ -493,15 +499,15 @@ Ice::Application::ignoreInterrupt() void Ice::Application::callbackOnInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() == holdInterruptCallback) { _released = true; - _condVar->signal(); + IceInternal::_condVar->signal(); } _ctrlCHandler->setCallback(callbackOnInterruptCallback); } @@ -516,11 +522,11 @@ Ice::Application::callbackOnInterrupt() void Ice::Application::holdInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() != holdInterruptCallback) { _previousCallback = _ctrlCHandler->getCallback(); @@ -540,11 +546,11 @@ Ice::Application::holdInterrupt() void Ice::Application::releaseInterrupt() { - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { if(_ctrlCHandler != 0) { - IceUtil::Mutex::Lock lock(*mutex); // we serialize all the interrupt-setting + IceUtil::Mutex::Lock lock(*IceInternal::mutex); // we serialize all the interrupt-setting if(_ctrlCHandler->getCallback() == holdInterruptCallback) { // @@ -556,7 +562,7 @@ Ice::Application::releaseInterrupt() _released = true; _ctrlCHandler->setCallback(_previousCallback); - _condVar->signal(); + IceInternal::_condVar->signal(); } // Else nothing to release. } @@ -571,24 +577,24 @@ Ice::Application::releaseInterrupt() bool Ice::Application::interrupted() { - IceUtil::Mutex::Lock lock(*mutex); - return _interrupted; + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + return IceInternal::_interrupted; } int -Ice::Application::mainInternal(int argc, char* argv[], const InitializationData& initializationData) +Ice::Application::doMain(int argc, char* argv[], const InitializationData& initializationData) { int status; try { - if(_condVar.get() == 0) + if(IceInternal::_condVar.get() == 0) { - _condVar.reset(new Cond); + IceInternal::_condVar.reset(new Cond); } - _interrupted = false; - _appName = argv[0] ? argv[0] : ""; + IceInternal::_interrupted = false; + IceInternal::_appName = argv[0] ? argv[0] : ""; // // We parse the properties here to extract Ice.ProgramName. @@ -605,19 +611,19 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData& setProcessLogger(new LoggerI(initData.properties->getProperty("Ice.ProgramName"), "")); } - _application = this; - _communicator = initialize(argc, argv, initData); - _destroyed = false; + IceInternal::_application = this; + IceInternal::_communicator = initialize(argc, argv, initData); + IceInternal::_destroyed = false; // // Used by destroyOnInterruptCallback and shutdownOnInterruptCallback. // - _nohup = (_communicator->getProperties()->getPropertyAsInt("Ice.Nohup") > 0); + _nohup = (IceInternal::_communicator->getProperties()->getPropertyAsInt("Ice.Nohup") > 0); // // The default is to destroy when a signal is received. // - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { destroyOnInterrupt(); } @@ -654,38 +660,38 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData& // it would not make sense to release a held signal to run // shutdown or destroy. // - if(_signalPolicy == HandleSignals) + if(IceInternal::_signalPolicy == HandleSignals) { ignoreInterrupt(); } { - IceUtil::Mutex::Lock lock(*mutex); - while(_callbackInProgress) + IceUtil::Mutex::Lock lock(*IceInternal::mutex); + while(IceInternal::_callbackInProgress) { - _condVar->wait(lock); + IceInternal::_condVar->wait(lock); } - if(_destroyed) + if(IceInternal::_destroyed) { - _communicator = 0; + IceInternal::_communicator = 0; } else { - _destroyed = true; + IceInternal::_destroyed = true; // // And _communicator != 0, meaning will be destroyed // next, _destroyed = true also ensures that any // remaining callback won't do anything // } - _application = 0; + IceInternal::_application = 0; } - if(_communicator != 0) + if(IceInternal::_communicator != 0) { try { - _communicator->destroy(); + IceInternal::_communicator->destroy(); } catch(const std::exception& ex) { @@ -699,7 +705,7 @@ Ice::Application::mainInternal(int argc, char* argv[], const InitializationData& out << "unknown exception"; status = EXIT_FAILURE; } - _communicator = 0; + IceInternal::_communicator = 0; } return status; |