summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/include/Glacier2/SessionHelper.h4
-rw-r--r--cpp/src/Glacier2Lib/Application.cpp66
-rw-r--r--cpp/src/Glacier2Lib/SessionHelper.cpp121
-rw-r--r--cs/src/Glacier2/Application.cs63
-rw-r--r--cs/src/Glacier2/SessionFactoryHelper.cs35
-rw-r--r--cs/src/Glacier2/SessionHelper.cs91
-rw-r--r--distribution/src/windows/docs/thirdparty/README.txt2
-rw-r--r--java/src/Glacier2/src/main/java/Glacier2/Application.java60
-rw-r--r--java/src/Glacier2/src/main/java/Glacier2/SessionFactoryHelper.java29
-rw-r--r--java/src/Glacier2/src/main/java/Glacier2/SessionHelper.java83
-rw-r--r--py/python/Glacier2.py55
11 files changed, 210 insertions, 399 deletions
diff --git a/cpp/include/Glacier2/SessionHelper.h b/cpp/include/Glacier2/SessionHelper.h
index 077801194b4..eeea0f53d5c 100644
--- a/cpp/include/Glacier2/SessionHelper.h
+++ b/cpp/include/Glacier2/SessionHelper.h
@@ -96,6 +96,9 @@ public:
void setConnectContext(std::map<std::string, std::string> context);
+ void setUseCallbacks(bool);
+ bool getUseCallbacks() const;
+
SessionHelperPtr connect();
SessionHelperPtr connect(const std::string&, const std::string&);
@@ -116,6 +119,7 @@ private:
Ice::InitializationData _initData;
SessionCallbackPtr _callback;
std::map< std::string, std::string> _context;
+ bool _useCallbacks;
};
typedef IceUtil::Handle<SessionFactoryHelper> SessionFactoryHelperPtr;
diff --git a/cpp/src/Glacier2Lib/Application.cpp b/cpp/src/Glacier2Lib/Application.cpp
index 637032959ea..2d6d28e4474 100644
--- a/cpp/src/Glacier2Lib/Application.cpp
+++ b/cpp/src/Glacier2Lib/Application.cpp
@@ -23,50 +23,6 @@ string Glacier2::Application::_category;
namespace
{
-class SessionRefreshTask : public IceUtil::TimerTask
-{
-
-public:
-
- SessionRefreshTask(Glacier2::Application* app, const Glacier2::RouterPrx& router) :
- _app(app),
- _router(router)
- {
- _callback = Glacier2::newCallback_Router_refreshSession(this, &SessionRefreshTask::exception);
- }
-
- void
- exception(const Ice::Exception&)
- {
- //
- // Here the session has been destroyed. Notify the application that the
- // session has been destroyed.
- //
- _app->sessionDestroyed();
- }
-
- virtual void
- runTimerTask()
- {
- try
- {
- _router->begin_refreshSession(_callback);
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- //
- // AMI requests can raise CommunicatorDestroyedException directly.
- //
- }
- }
-
-private:
-
- Glacier2::Application* _app;
- Glacier2::RouterPrx _router;
- Glacier2::Callback_Router_refreshSessionPtr _callback;
-};
-
class ConnectionCallbackI : public Ice::ConnectionCallback
{
public:
@@ -230,7 +186,7 @@ Glacier2::Application::doMain(Ice::StringSeq& args, const Ice::InitializationDat
if(_createdSession)
{
- int acmTimeout = 0;
+ Ice::Int acmTimeout = 0;
try
{
acmTimeout = _router->getACMTimeout();
@@ -238,6 +194,11 @@ Glacier2::Application::doMain(Ice::StringSeq& args, const Ice::InitializationDat
catch(const Ice::OperationNotExistException&)
{
}
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = static_cast<Ice::Int>(_router->getSessionTimeout());
+ }
+
if(acmTimeout > 0)
{
Ice::ConnectionPtr connection = _router->ice_getCachedConnection();
@@ -245,21 +206,6 @@ Glacier2::Application::doMain(Ice::StringSeq& args, const Ice::InitializationDat
connection->setACM(acmTimeout, IceUtil::None, Ice::HeartbeatAlways);
connection->setCallback(new ConnectionCallbackI(this));
}
- else
- {
- IceUtil::Int64 sessionTimeout = _router->getSessionTimeout();
- if(sessionTimeout > 0)
- {
- //
- // Create a ping timer task. The task itself doesn't
- // need to be canceled as the communicator is destroyed
- // at the end.
- //
- IceUtil::TimerPtr timer = IceInternal::getInstanceTimer(communicator());
- timer->scheduleRepeated(new SessionRefreshTask(this, _router),
- IceUtil::Time::seconds(sessionTimeout/2));
- }
- }
_category = _router->getCategoryForClient();
IceUtilInternal::ArgVector a(args);
diff --git a/cpp/src/Glacier2Lib/SessionHelper.cpp b/cpp/src/Glacier2Lib/SessionHelper.cpp
index efbb681194e..dbfb72afba5 100644
--- a/cpp/src/Glacier2Lib/SessionHelper.cpp
+++ b/cpp/src/Glacier2Lib/SessionHelper.cpp
@@ -59,7 +59,7 @@ class SessionHelperI : public Glacier2::SessionHelper
public:
- SessionHelperI(const Glacier2::SessionCallbackPtr&, const Ice::InitializationData&, const string&);
+ SessionHelperI(const Glacier2::SessionCallbackPtr&, const Ice::InitializationData&, const string&, bool);
void destroy();
Ice::CommunicatorPtr communicator() const;
std::string categoryForClient() const;
@@ -100,48 +100,10 @@ private:
const Ice::InitializationData _initData;
const Glacier2::SessionCallbackPtr _callback;
const string _finder;
+ const bool _useCallbacks;
};
typedef IceUtil::Handle<SessionHelperI> SessionHelperIPtr;
-class SessionRefreshTask : public IceUtil::TimerTask
-{
-public:
-
- SessionRefreshTask(const Glacier2::SessionHelperPtr& session, const Glacier2::RouterPrx& router) :
- _session(session),
- _router(router),
- _callback(Glacier2::newCallback_Router_refreshSession(this, &SessionRefreshTask::exception))
- {
- }
-
- virtual void
- runTimerTask()
- {
- try
- {
- _router->begin_refreshSession(_callback);
- }
- catch(const Ice::CommunicatorDestroyedException&)
- {
- //
- // AMI requests can raise CommunicatorDestroyedException directly.
- //
- }
- }
-
- void
- exception(const Ice::Exception&)
- {
- _session->destroy();
- }
-
-private:
-
- const Glacier2::SessionHelperPtr _session;
- const Glacier2::RouterPrx _router;
- const Glacier2::Callback_Router_refreshSessionPtr _callback;
-};
-
class DestroyInternal : public IceUtil::Thread
{
@@ -168,12 +130,14 @@ private:
SessionHelperI::SessionHelperI(const Glacier2::SessionCallbackPtr& callback,
const Ice::InitializationData& initData,
- const string& finderStr) :
+ const string& finderStr,
+ bool useCallbacks) :
_connected(false),
_destroy(false),
_initData(initData),
_callback(callback),
- _finder(finderStr)
+ _finder(finderStr),
+ _useCallbacks(useCallbacks)
{
}
@@ -207,8 +171,7 @@ SessionHelperI::destroy(const IceUtil::ThreadPtr& destroyInternal)
_connected = false;
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
destroyInternal->start().detach();
}
@@ -289,10 +252,10 @@ SessionHelperI::internalObjectAdapter()
{
throw Glacier2::SessionNotExistException();
}
- if(!_adapter)
+ if(!_useCallbacks)
{
- _adapter = _communicator->createObjectAdapterWithRouter("", _router);
- _adapter->activate();
+ throw Ice::InitializationException(__FILE__, __LINE__,
+ "Object adapter not available, call SessionFactoryHelper.setUseCallbacks(true)");
}
return _adapter;
}
@@ -677,13 +640,12 @@ void
SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::SessionPrx& session)
{
//
- // Remote invocation should be done without acquire a mutex lock.
+ // Remote invocation should be done without acquiring a mutex lock.
//
assert(router);
Ice::ConnectionPtr conn = router->ice_getCachedConnection();
string category = router->getCategoryForClient();
- Ice::Long sessionTimeout = router->getSessionTimeout();
- int acmTimeout = 0;
+ Ice::Int acmTimeout = 0;
try
{
acmTimeout = router->getACMTimeout();
@@ -692,6 +654,23 @@ SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::Ses
{
}
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = static_cast<Ice::Int>(router->getSessionTimeout());
+ }
+
+ //
+ // We create the callback object adapter here because createObjectAdapter internally
+ // makes synchronous RPCs to the router. We can't create the OA on-demand when the
+ // client calls objectAdapter() or addWithUUID() because they can be called from the
+ // GUI thread.
+ //
+ if(_useCallbacks)
+ {
+ _adapter = _communicator->createObjectAdapterWithRouter("", router);
+ _adapter->activate();
+ }
+
{
IceUtil::Mutex::Lock sync(_mutex);
_router = router;
@@ -699,8 +678,7 @@ SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::Ses
if(_destroy)
{
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
IceUtil::ThreadPtr thread = new DestroyInternal(this, _callback);
thread->start().detach();
@@ -725,16 +703,6 @@ SessionHelperI::connected(const Glacier2::RouterPrx& router, const Glacier2::Ses
connection->setACM(acmTimeout, IceUtil::None, Ice::HeartbeatAlways);
connection->setCallback(new ConnectionCallbackI(this));
}
- else if(sessionTimeout > 0)
- {
- //
- // Create a ping timer task. The task itself doesn't need to be
- // canceled as the communicator is destroyed at the end.
- //
- IceUtil::TimerPtr timer = IceInternal::getInstanceTimer(communicator());
- timer->scheduleRepeated(new SessionRefreshTask(this, _router),
- IceUtil::Time::seconds(sessionTimeout/2));
- }
}
dispatchCallback(new Connected(_callback, this), conn);
}
@@ -802,7 +770,8 @@ Glacier2::SessionFactoryHelper::SessionFactoryHelper(const SessionCallbackPtr& c
_protocol("ssl"),
_port(0),
_timeout(10000),
- _callback(callback)
+ _callback(callback),
+ _useCallbacks(true)
{
_initData.properties = Ice::createProperties();
setDefaultProperties();
@@ -815,7 +784,8 @@ Glacier2::SessionFactoryHelper::SessionFactoryHelper(const Ice::InitializationDa
_port(0),
_timeout(10000),
_initData(initData),
- _callback(callback)
+ _callback(callback),
+ _useCallbacks(true)
{
if(!initData.properties)
{
@@ -830,7 +800,8 @@ Glacier2::SessionFactoryHelper::SessionFactoryHelper(const Ice::PropertiesPtr& p
_protocol("ssl"),
_port(0),
_timeout(10000),
- _callback(callback)
+ _callback(callback),
+ _useCallbacks(true)
{
if(!properties)
{
@@ -890,7 +861,7 @@ Glacier2::SessionFactoryHelper::setProtocol(const string& protocol)
protocol != "ws" &&
protocol != "wss")
{
- throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Unknow protocol `" + protocol + "'");
+ throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Unknown protocol `" + protocol + "'");
}
_protocol = protocol;
}
@@ -951,11 +922,25 @@ Glacier2::SessionFactoryHelper::setConnectContext(map<string, string> context)
_context = context;
}
+void
+Glacier2::SessionFactoryHelper::setUseCallbacks(bool useCallbacks)
+{
+ IceUtil::Mutex::Lock sync(_mutex);
+ _useCallbacks = useCallbacks;
+}
+
+bool
+Glacier2::SessionFactoryHelper::getUseCallbacks() const
+{
+ IceUtil::Mutex::Lock sync(_mutex);
+ return _useCallbacks;
+}
+
Glacier2::SessionHelperPtr
Glacier2::SessionFactoryHelper::connect()
{
IceUtil::Mutex::Lock sync(_mutex);
- SessionHelperIPtr session = new SessionHelperI(_callback, createInitData(), getRouterFinderStr());
+ SessionHelperIPtr session = new SessionHelperI(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session->connect(_context);
return session;
}
@@ -964,7 +949,7 @@ Glacier2::SessionHelperPtr
Glacier2::SessionFactoryHelper::connect(const string& user, const string& password)
{
IceUtil::Mutex::Lock sync(_mutex);
- SessionHelperIPtr session = new SessionHelperI(_callback, createInitData(), getRouterFinderStr());
+ SessionHelperIPtr session = new SessionHelperI(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session->connect(user, password, _context);
return session;
}
diff --git a/cs/src/Glacier2/Application.cs b/cs/src/Glacier2/Application.cs
index fb7d6cb22d3..b5d4aa604c2 100644
--- a/cs/src/Glacier2/Application.cs
+++ b/cs/src/Glacier2/Application.cs
@@ -24,7 +24,7 @@ namespace Glacier2
/// error output.
///
/// Applications must create a derived class that implements the {@link #run} method.
-///
+///
/// A program can contain only one instance of this class.
/// </summary>
public abstract class Application : Ice.Application
@@ -49,7 +49,7 @@ public abstract class Application : Ice.Application
/// Initializes an instance that handles signals according to the signal
/// policy.
/// </summary>
- /// <param name="signalPolicy">@param signalPolicy Determines how to
+ /// <param name="signalPolicy">@param signalPolicy Determines how to
/// respond to signals.</param>
public
Application(Ice.SignalPolicy signalPolicy) : base(signalPolicy)
@@ -93,7 +93,7 @@ public abstract class Application : Ice.Application
/// method never returns. The exception produce an application restart
/// when called from the Application main thread.
/// </summary>
- /// <returns>throws RestartSessionException This exception is
+ /// <returns>throws RestartSessionException This exception is
/// always thrown.</returns>
///
public void
@@ -104,7 +104,7 @@ public abstract class Application : Ice.Application
/// <summary>
/// Creates a new Glacier2 session. A call to createSession always
- /// precedes a call to runWithSession. If Ice.LocalException is thrown
+ /// precedes a call to runWithSession. If Ice.LocalException is thrown
/// from this method, the application is terminated.
/// </summary>
/// <returns> The Glacier2 session.</returns>
@@ -205,42 +205,6 @@ public abstract class Application : Ice.Application
return _adapter;
}
- private class SessionRefreshTask : IceInternal.TimerTask
- {
- public SessionRefreshTask(Application app, Glacier2.RouterPrx router)
- {
- _app = app;
- _router = router;
- }
-
- public void
- runTimerTask()
- {
- try
- {
- _router.begin_refreshSession().whenCompleted(
- (Ice.Exception ex) =>
- {
- //
- // Here the session has been destroyed. Notify the
- // application that the session has been destroyed.
- //
- _app.sessionDestroyed();
- });
- }
- catch(Ice.CommunicatorDestroyedException)
- {
- //
- // AMI requests can raise CommunicatorDestroyedException
- // directly.
- //
- }
- }
-
- private Application _app;
- private Glacier2.RouterPrx _router;
- }
-
private class ConnectionCallbackI : Ice.ConnectionCallback
{
internal ConnectionCallbackI(Application application)
@@ -250,7 +214,7 @@ public abstract class Application : Ice.Application
public void heartbeat(Ice.Connection con)
{
-
+
}
public void closed(Ice.Connection con)
@@ -346,22 +310,17 @@ public abstract class Application : Ice.Application
catch(Ice.OperationNotExistException)
{
}
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = (int)_router.getSessionTimeout();
+ }
if(acmTimeout > 0)
{
Ice.Connection connection = _router.ice_getCachedConnection();
Debug.Assert(connection != null);
- connection.setACM(acmTimeout, Ice.Util.None, Ice.ACMHeartbeat.HeartbeatAlways);
+ connection.setACM((int)acmTimeout, Ice.Util.None, Ice.ACMHeartbeat.HeartbeatAlways);
connection.setCallback(new ConnectionCallbackI(this));
}
- else
- {
- long timeout = _router.getSessionTimeout();
- if(timeout > 0)
- {
- IceInternal.Timer timer = IceInternal.Util.getInstance(communicator()).timer();
- timer.scheduleRepeated(new SessionRefreshTask(this, _router), (timeout * 1000) / 2);
- }
- }
_category = _router.getCategoryForClient();
status = runWithSession(args);
}
@@ -468,7 +427,7 @@ public abstract class Application : Ice.Application
//
// Not expected.
//
- Ice.Util.getProcessLogger().error("unexpected exception when destroying the session:\n" +
+ Ice.Util.getProcessLogger().error("unexpected exception when destroying the session:\n" +
ex.ToString());
}
_router = null;
diff --git a/cs/src/Glacier2/SessionFactoryHelper.cs b/cs/src/Glacier2/SessionFactoryHelper.cs
index 7fc792d1633..c37aff27581 100644
--- a/cs/src/Glacier2/SessionFactoryHelper.cs
+++ b/cs/src/Glacier2/SessionFactoryHelper.cs
@@ -167,7 +167,7 @@ public class SessionFactoryHelper
!protocol.Equals("wss") &&
!protocol.Equals("ws"))
{
- throw new ArgumentException("Unknow protocol `" + protocol + "'");
+ throw new ArgumentException("Unknown protocol `" + protocol + "'");
}
_protocol = protocol;
}
@@ -276,6 +276,34 @@ public class SessionFactoryHelper
}
/// <summary>
+ /// Determines whether the session should create an object adapter that the client
+ /// can use for receiving callbacks.
+ /// </summary>
+ /// <param name="useCallbacks">True if the session should create an object adapter.</param>
+ public void
+ setUseCallbacks(bool useCallbacks)
+ {
+ lock(this)
+ {
+ _useCallbacks = useCallbacks;
+ }
+ }
+
+ /// <summary>
+ /// Indicates whether a newly-created session will also create an object adapter that
+ /// the client can use for receiving callbaks.
+ /// </summary>
+ /// <returns>True if the session will create an object adapter.</returns>
+ public bool
+ getUseCallbacks()
+ {
+ lock(this)
+ {
+ return _useCallbacks;
+ }
+ }
+
+ /// <summary>
/// Connects to the Glacier2 router using the associated SSL credentials.
///
/// Once the connection is established, SesssionCallback.connected is called on
@@ -288,7 +316,7 @@ public class SessionFactoryHelper
{
lock(this)
{
- SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr());
+ SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session.connect(_context);
return session;
}
@@ -309,7 +337,7 @@ public class SessionFactoryHelper
{
lock(this)
{
- SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr());
+ SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session.connect(username, password, _context);
return session;
}
@@ -384,6 +412,7 @@ public class SessionFactoryHelper
private int _port = 0;
private int _timeout = 10000;
private Dictionary<string, string> _context;
+ private bool _useCallbacks = true;
private static int GLACIER2_SSL_PORT = 4064;
private static int GLACIER2_TCP_PORT = 4063;
}
diff --git a/cs/src/Glacier2/SessionHelper.cs b/cs/src/Glacier2/SessionHelper.cs
index 873019b124a..f9432d6003f 100644
--- a/cs/src/Glacier2/SessionHelper.cs
+++ b/cs/src/Glacier2/SessionHelper.cs
@@ -20,37 +20,6 @@ namespace Glacier2
/// </summary>
public class SessionHelper
{
- private class SessionRefreshTask : IceInternal.TimerTask
- {
- public SessionRefreshTask(SessionHelper session, Glacier2.RouterPrx router)
- {
- _session = session;
- _router = router;
- }
-
- public void
- runTimerTask()
- {
- try
- {
- _router.begin_refreshSession().whenCompleted(
- (Ice.Exception ex) =>
- {
- _session.destroy();
- });
- }
- catch(Ice.CommunicatorDestroyedException)
- {
- //
- // AMI requests can raise CommunicatorDestroyedException directly.
- //
- }
- }
-
- private SessionHelper _session;
- private Glacier2.RouterPrx _router;
- }
-
private class ConnectionCallbackI : Ice.ConnectionCallback
{
internal ConnectionCallbackI(SessionHelper sessionHelper)
@@ -79,11 +48,13 @@ public class SessionHelper
/// <param name="initData">The Ice.InitializationData for initializing
/// the communicator.</param>
/// <param name="finderStr">The stringified Ice.RouterFinder proxy.</param>
- public SessionHelper(SessionCallback callback, Ice.InitializationData initData, string finderStr)
+ /// <param name="useCallbacks">True if the session should create an object adapter for receiving callbacks.</param>
+ public SessionHelper(SessionCallback callback, Ice.InitializationData initData, string finderStr, bool useCallbacks)
{
_callback = callback;
_initData = initData;
_finderStr = finderStr;
+ _useCallbacks = useCallbacks;
}
/// <summary>
@@ -115,8 +86,7 @@ public class SessionHelper
_session = null;
_connected = false;
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
Thread t = new Thread(new ThreadStart(destroyInternal));
t.Start();
@@ -215,7 +185,7 @@ public class SessionHelper
/// <summary>
/// Returns an object adapter for callback objects, creating it if necessary.
/// </summary>
- /// <return>The object adapter. throws SessionNotExistException
+ /// <return>The object adapter. Throws SessionNotExistException
/// if no session exists.</return>
public Ice.ObjectAdapter
objectAdapter()
@@ -223,9 +193,6 @@ public class SessionHelper
return internalObjectAdapter();
}
- //
- // Only call this method when the calling thread owns the lock
- //
private Ice.ObjectAdapter
internalObjectAdapter()
{
@@ -235,10 +202,10 @@ public class SessionHelper
{
throw new SessionNotExistException();
}
- if(_adapter == null)
+ if(!_useCallbacks)
{
- _adapter = _communicator.createObjectAdapterWithRouter("", _router);
- _adapter.activate();
+ throw new Ice.InitializationException(
+ "Object adapter not available, call SessionFactoryHelper.setUseCallbacks(true)");
}
return _adapter;
}
@@ -288,8 +255,12 @@ public class SessionHelper
private void
connected(RouterPrx router, SessionPrx session)
{
+ //
+ // Remote invocation should be done without acquiring a mutex lock.
+ //
+ Debug.Assert(router != null);
+ Ice.Connection conn = router.ice_getCachedConnection();
string category = router.getCategoryForClient();
- long sessionTimeout = router.getSessionTimeout();
int acmTimeout = 0;
try
{
@@ -298,7 +269,24 @@ public class SessionHelper
catch(Ice.OperationNotExistException)
{
}
- Ice.Connection conn = router.ice_getCachedConnection();
+
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = (int)router.getSessionTimeout();
+ }
+
+ //
+ // We create the callback object adapter here because createObjectAdapter internally
+ // makes synchronous RPCs to the router. We can't create the OA on-demand when the
+ // client calls objectAdapter() or addWithUUID() because they can be called from the
+ // GUI thread.
+ //
+ if(_useCallbacks)
+ {
+ Debug.Assert(_adapter == null);
+ _adapter = _communicator.createObjectAdapterWithRouter("", router);
+ _adapter.activate();
+ }
lock(this)
{
@@ -307,8 +295,7 @@ public class SessionHelper
if(_destroy)
{
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
Thread t = new Thread(new ThreadStart(destroyInternal));
t.Start();
@@ -333,11 +320,6 @@ public class SessionHelper
connection.setACM(acmTimeout, Ice.Util.None, Ice.ACMHeartbeat.HeartbeatAlways);
connection.setCallback(new ConnectionCallbackI(this));
}
- else if(sessionTimeout > 0)
- {
- IceInternal.Timer timer = IceInternal.Util.getInstance(communicator()).timer();
- timer.scheduleRepeated(new SessionRefreshTask(this, _router), (sessionTimeout * 1000)/2);
- }
}
dispatchCallback(() =>
@@ -397,7 +379,6 @@ public class SessionHelper
communicator.getLogger().warning("SessionHelper: unexpected exception when destroying the session:\n" + e);
}
-
try
{
communicator.destroy();
@@ -450,8 +431,8 @@ public class SessionHelper
}
catch(Exception)
{
- // In case of error getting router identity from RouterFinder use
- // default identity.
+ //
+ // In case of error getting router identity from RouterFinder use default identity.
//
Ice.Identity ident = new Ice.Identity("router", "Glacier2");
_communicator.setDefaultRouter(Ice.RouterPrxHelper.uncheckedCast(finder.ice_identity(ident)));
@@ -465,8 +446,7 @@ public class SessionHelper
_callback.createdCommunicator(this);
});
- Glacier2.RouterPrx routerPrx = Glacier2.RouterPrxHelper.uncheckedCast(
- _communicator.getDefaultRouter());
+ Glacier2.RouterPrx routerPrx = Glacier2.RouterPrxHelper.uncheckedCast(_communicator.getDefaultRouter());
Glacier2.SessionPrx session = factory(routerPrx);
connected(routerPrx, session);
}
@@ -537,6 +517,7 @@ public class SessionHelper
private bool _connected = false;
private string _category;
private string _finderStr;
+ private bool _useCallbacks;
private readonly SessionCallback _callback;
private bool _destroy = false;
diff --git a/distribution/src/windows/docs/thirdparty/README.txt b/distribution/src/windows/docs/thirdparty/README.txt
index aaf6b28f6f6..ef0b53ec4dc 100644
--- a/distribution/src/windows/docs/thirdparty/README.txt
+++ b/distribution/src/windows/docs/thirdparty/README.txt
@@ -1,5 +1,5 @@
Ice 3.6.0 Third Party Packages
------------------------------
+------------------------------
This distribution contains the development kit (including binaries)
for the open-source packages used by Ice 3.6.0 on Windows. Its primary
diff --git a/java/src/Glacier2/src/main/java/Glacier2/Application.java b/java/src/Glacier2/src/main/java/Glacier2/Application.java
index 8a1e2b62d9f..90a4ff21c30 100644
--- a/java/src/Glacier2/src/main/java/Glacier2/Application.java
+++ b/java/src/Glacier2/src/main/java/Glacier2/Application.java
@@ -291,7 +291,6 @@ public abstract class Application extends Ice.Application
boolean restart = false;
status.value = 0;
-
try
{
_communicator = Ice.Util.initialize(argHolder, initData);
@@ -336,6 +335,10 @@ public abstract class Application extends Ice.Application
catch(Ice.OperationNotExistException ex)
{
}
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = (int)_router.getSessionTimeout();
+ }
if(acmTimeout > 0)
{
Ice.Connection connection = _router.ice_getCachedConnection();
@@ -345,61 +348,6 @@ public abstract class Application extends Ice.Application
new Ice.Optional<Ice.ACMHeartbeat>(Ice.ACMHeartbeat.HeartbeatAlways));
connection.setCallback(new ConnectionCallbackI());
}
- else
- {
- long timeout = _router.getSessionTimeout();
- if(timeout > 0)
- {
- java.util.concurrent.ScheduledExecutorService timer =
- IceInternal.Util.getInstance(_communicator).timer();
- //
- // We don't need to cancel the task as the communicator is destroyed at the end and
- // ContinueExistingPeriodicTasksAfterShutdownPolicy is false.
- //
- timer.scheduleAtFixedRate(new Runnable()
- {
- @Override
- public void run()
- {
- _router.begin_refreshSession(new Glacier2.Callback_Router_refreshSession()
- {
- @Override
- public void
- response()
- {
- }
-
- @Override
- public void
- exception(Ice.LocalException ex)
- {
- //
- // Here the session has gone and we notify the application that
- // the session has been destroyed.
- //
- sessionDestroyed();
- }
-
- @Override
- public void
- exception(Ice.UserException ex)
- {
- //
- // Here the session has gone and we notify the application that
- // the session has been destroyed.
- //
- sessionDestroyed();
- }
- });
- //
- // AMI requests can raise CommunicatorDestroyedException directly. We let this
- // out of the task and terminate the timer.
- //
-
- }
- }, timeout / 2, timeout / 2, java.util.concurrent.TimeUnit.SECONDS);
- }
- }
_category = _router.getCategoryForClient();
status.value = runWithSession(argHolder.value);
}
diff --git a/java/src/Glacier2/src/main/java/Glacier2/SessionFactoryHelper.java b/java/src/Glacier2/src/main/java/Glacier2/SessionFactoryHelper.java
index eeb90412060..0899bb786cb 100644
--- a/java/src/Glacier2/src/main/java/Glacier2/SessionFactoryHelper.java
+++ b/java/src/Glacier2/src/main/java/Glacier2/SessionFactoryHelper.java
@@ -272,6 +272,30 @@ public class SessionFactoryHelper
}
/**
+ * Determines whether the session should create an object adapter that the client
+ * can use for receiving callbacks.
+ *
+ * @param useCallbacks True if the session should create an object adapter.
+ */
+ synchronized public void
+ setUseCallbacks(boolean useCallbacks)
+ {
+ _useCallbacks = useCallbacks;
+ }
+
+ /**
+ * Indicates whether a newly-created session will also create an object adapter that
+ * the client can use for receiving callbacks.
+ *
+ * @return True if the session will create an object adapter.
+ */
+ synchronized public boolean
+ getUseCallbacks()
+ {
+ return _useCallbacks;
+ }
+
+ /**
* Connects to the Glacier2 router using the associated SSL credentials.
*
* Once the connection is established, {@link SessionCallback#connected} is called on the callback object;
@@ -282,7 +306,7 @@ public class SessionFactoryHelper
synchronized public SessionHelper
connect()
{
- SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr());
+ SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session.connect(_context);
return session;
}
@@ -300,7 +324,7 @@ public class SessionFactoryHelper
synchronized public SessionHelper
connect(final String username, final String password)
{
- SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr());
+ SessionHelper session = new SessionHelper(_callback, createInitData(), getRouterFinderStr(), _useCallbacks);
session.connect(username, password, _context);
return session;
}
@@ -368,6 +392,7 @@ public class SessionFactoryHelper
private int _port = 0;
private int _timeout = 10000;
private java.util.Map<String, String> _context;
+ private boolean _useCallbacks = true;
private static final int GLACIER2_SSL_PORT = 4064;
private static final int GLACIER2_TCP_PORT = 4063;
}
diff --git a/java/src/Glacier2/src/main/java/Glacier2/SessionHelper.java b/java/src/Glacier2/src/main/java/Glacier2/SessionHelper.java
index f39223c3e10..3e3311bacb7 100644
--- a/java/src/Glacier2/src/main/java/Glacier2/SessionHelper.java
+++ b/java/src/Glacier2/src/main/java/Glacier2/SessionHelper.java
@@ -19,12 +19,16 @@ public class SessionHelper
*
* @param callback The callback for notifications about session establishment.
* @param initData The {@link Ice.InitializationData} for initializing the communicator.
+ * @param finderStr The stringified Ice.RouterFinder proxy.
+ * @param useCallbacks True if the session should create an object adapter for receiving callbacks.
*/
- public SessionHelper(SessionCallback callback, Ice.InitializationData initData, String finderStr)
+ public SessionHelper(SessionCallback callback, Ice.InitializationData initData, String finderStr,
+ boolean useCallbacks)
{
_callback = callback;
_initData = initData;
_finderStr = finderStr;
+ _useCallbacks = useCallbacks;
}
/**
@@ -71,8 +75,7 @@ public class SessionHelper
}
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
new Thread(new Runnable()
{
@@ -182,10 +185,10 @@ public class SessionHelper
{
throw new SessionNotExistException();
}
- if(_adapter == null)
+ if(!_useCallbacks)
{
- _adapter = _communicator.createObjectAdapterWithRouter("", _router);
- _adapter.activate();
+ throw new Ice.InitializationException(
+ "Object adapter not available, call SessionFactoryHelper.setUseCallbacks(true)");
}
return _adapter;
}
@@ -246,8 +249,12 @@ public class SessionHelper
private void
connected(RouterPrx router, SessionPrx session)
{
+ //
+ // Remote invocation should be done without acquiring a mutex lock.
+ //
+ assert(router != null);
+ Ice.Connection conn = router.ice_getCachedConnection();
String category = router.getCategoryForClient();
- long sessionTimeout = router.getSessionTimeout();
int acmTimeout = 0;
try
{
@@ -256,7 +263,24 @@ public class SessionHelper
catch(Ice.OperationNotExistException ex)
{
}
- Ice.Connection conn = router.ice_getCachedConnection();
+
+ if(acmTimeout <= 0)
+ {
+ acmTimeout = (int)router.getSessionTimeout();
+ }
+
+ //
+ // We create the callback object adapter here because createObjectAdapter internally
+ // makes synchronous RPCs to the router. We can't create the OA on-demand when the
+ // client calls objectAdapter() or addWithUUID() because they can be called from the
+ // GUI thread.
+ //
+ if(_useCallbacks)
+ {
+ assert(_adapter == null);
+ _adapter = _communicator.createObjectAdapterWithRouter("", router);
+ _adapter.activate();
+ }
synchronized(this)
{
@@ -265,8 +289,7 @@ public class SessionHelper
if(_destroy)
{
//
- // Run the destroyInternal in a thread. This is because it
- // destroyInternal makes remote invocations.
+ // Run destroyInternal in a thread because it makes remote invocations.
//
new Thread(new Runnable()
{
@@ -311,45 +334,6 @@ public class SessionHelper
}
});
}
- else if(sessionTimeout > 0)
- {
- java.util.concurrent.ScheduledExecutorService timer =
- IceInternal.Util.getInstance(_communicator).timer();
- //
- // We don't need to cancel the task as the communicator is destroyed at the end and
- // ContinueExistingPeriodicTasksAfterShutdownPolicy is false.
- //
- timer.scheduleAtFixedRate(new Runnable()
- {
- @Override
- public void run()
- {
- _router.begin_refreshSession(new Glacier2.Callback_Router_refreshSession()
- {
- @Override
- public void response()
- {
- }
-
- @Override
- public void exception(Ice.LocalException ex)
- {
- SessionHelper.this.destroy();
- }
-
- @Override
- public void exception(Ice.UserException ex)
- {
- SessionHelper.this.destroy();
- }
- });
- //
- // AMI requests can raise CommunicatorDestroyedException directly. We let this
- // out of the task and terminate the timer.
- //
- }
- }, sessionTimeout / 2, sessionTimeout / 2, java.util.concurrent.TimeUnit.SECONDS);
- }
_shutdownHook = new Thread("Shutdown hook")
{
@@ -601,6 +585,7 @@ public class SessionHelper
private Glacier2.SessionPrx _session;
private String _category;
private String _finderStr;
+ private boolean _useCallbacks;
private final SessionCallback _callback;
private boolean _destroy = false;
diff --git a/py/python/Glacier2.py b/py/python/Glacier2.py
index 59efb676f6d..149dde48386 100644
--- a/py/python/Glacier2.py
+++ b/py/python/Glacier2.py
@@ -33,49 +33,6 @@ class RestartSessionException(Exception):
def __init__(self):
pass
-class SessionPingThread(threading.Thread):
- def __init__(self, app, router, period):
- threading.Thread.__init__(self)
- self._app = app
- self._router = router
- self._period = period
- self._done = False
- self._cond = threading.Condition()
-
- def run(self):
- self._cond.acquire()
- try:
- while not self._done:
- self._router.begin_refreshSession(self.response, self.exception)
-
- if not self._done:
- self._cond.wait(self._period)
- finally:
- self._cond.release()
-
- def done(self):
- self._cond.acquire()
- try:
- if not self._done:
- self._done = True
- self._cond.notify()
- finally:
- self._cond.release()
-
- def response(self):
- #
- # Ignore successful call to refreshSession.
- #
- pass
-
- def exception(self, ex):
- #
- # Here the session has gone. The thread terminates, and we notify the
- # application that the session has been destroyed.
- #
- self.done()
- self._app.sessionDestroyed()
-
class ConnectionCallbackI(Ice.ConnectionCallback):
def __init__(self, app):
self._app = app
@@ -159,7 +116,6 @@ Application.NoSignalHandling.
restart = False
status = 0
- ping = None
try:
Ice.Application._communicator = Ice.initialize(args, initData)
@@ -188,16 +144,13 @@ Application.NoSignalHandling.
acmTimeout = Application._router.getACMTimeout()
except(Ice.OperationNotExistException):
pass
+ if acmTimeout <= 0:
+ acmTimeout = Application._router.getSessionTimeout()
if acmTimeout > 0:
connection = Application._router.ice_getCachedConnection()
assert(connection)
connection.setACM(acmTimeout, Ice.Unset, Ice.ACMHeartbeat.HeartbeatAlways)
connection.setCallback(ConnectionCallbackI(self))
- else:
- timeout = Application._router.getSessionTimeout()
- if timeout > 0:
- ping = SessionPingThread(self, Application._router, timeout / 2)
- ping.start()
Application._category = Application._router.getCategoryForClient()
status = self.runWithSession(args)
@@ -237,10 +190,6 @@ Application.NoSignalHandling.
#
Ice.Application._condVar.release()
- if ping:
- ping.done()
- ping.join()
-
if Application._createdSession and Application._router:
try:
Application._router.destroySession()