summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG-3.7.md19
-rw-r--r--cpp/include/Ice/AsyncResult.h10
-rw-r--r--cpp/include/Ice/OutgoingAsync.h2
-rw-r--r--cpp/src/Ice/OutgoingAsync.cpp37
-rw-r--r--cpp/src/Slice/Python.cpp16
-rw-r--r--cpp/src/Slice/PythonUtil.cpp48
-rw-r--r--cpp/src/Slice/PythonUtil.h2
-rw-r--r--python/modules/IcePy/Communicator.cpp59
-rw-r--r--python/modules/IcePy/Connection.cpp46
-rw-r--r--python/modules/IcePy/ObjectAdapter.cpp4
-rw-r--r--python/modules/IcePy/Operation.cpp2209
-rw-r--r--python/modules/IcePy/Operation.h56
-rw-r--r--python/modules/IcePy/Proxy.cpp195
-rw-r--r--python/modules/IcePy/Slice.cpp9
-rw-r--r--python/modules/IcePy/Util.cpp59
-rw-r--r--python/modules/IcePy/Util.h20
-rw-r--r--python/python/Ice.py258
-rw-r--r--python/python/IceFuture.py48
-rw-r--r--python/test/Ice/acm/AllTests.py90
-rw-r--r--python/test/Ice/acm/TestI.py27
-rw-r--r--python/test/Ice/adapterDeactivation/AllTests.py2
-rw-r--r--python/test/Ice/admin/TestI.py10
-rw-r--r--python/test/Ice/ami/AllTests.py695
-rwxr-xr-xpython/test/Ice/ami/Client.py1
-rw-r--r--python/test/Ice/ami/TestI.py15
-rw-r--r--python/test/Ice/binding/AllTests.py19
-rw-r--r--python/test/Ice/blobject/RouterI.py93
-rw-r--r--python/test/Ice/exceptions/AllTests.py236
-rwxr-xr-xpython/test/Ice/exceptions/ServerAMD.py111
-rw-r--r--python/test/Ice/faultTolerance/AllTests.py43
-rwxr-xr-xpython/test/Ice/location/Server.py20
-rw-r--r--python/test/Ice/objects/AllTests.py8
-rw-r--r--python/test/Ice/objects/TestI.py6
-rw-r--r--python/test/Ice/operations/AllTests.py28
-rw-r--r--python/test/Ice/operations/BatchOnewaysAMI.py12
-rw-r--r--python/test/Ice/operations/BatchOnewaysFuture.py88
-rw-r--r--python/test/Ice/operations/OnewaysAMI.py12
-rw-r--r--python/test/Ice/operations/OnewaysFuture.py54
-rwxr-xr-xpython/test/Ice/operations/ServerAMD.py356
-rw-r--r--python/test/Ice/operations/TestI.py12
-rw-r--r--python/test/Ice/operations/TwowaysAMI.py12
-rw-r--r--python/test/Ice/operations/TwowaysFuture.py1354
-rw-r--r--python/test/Ice/optional/AllTests.py120
-rwxr-xr-xpython/test/Ice/optional/ServerAMD.py221
-rwxr-xr-xpython/test/Ice/proxy/ServerAMD.py11
-rw-r--r--python/test/Ice/servantLocator/TestAMDI.py69
-rw-r--r--python/test/Ice/slicing/exceptions/AllTests.py107
-rwxr-xr-xpython/test/Ice/slicing/exceptions/ServerAMD.py135
-rw-r--r--python/test/Ice/slicing/objects/AllTests.py215
-rwxr-xr-xpython/test/Ice/slicing/objects/Server.py20
-rwxr-xr-xpython/test/Ice/slicing/objects/ServerAMD.py173
-rw-r--r--python/test/Ice/timeout/AllTests.py17
-rwxr-xr-xpython/test/Slice/keyword/Client.py4
53 files changed, 5576 insertions, 1917 deletions
diff --git a/CHANGELOG-3.7.md b/CHANGELOG-3.7.md
index 0637f4f7a33..61ee7b6a1c9 100644
--- a/CHANGELOG-3.7.md
+++ b/CHANGELOG-3.7.md
@@ -123,3 +123,22 @@ These are the changes since Ice 3.6.3.
- The --dll-export option of slice2objc is now deprecated, and replaced by the global
Slice metadata objc:dll-export:SYMBOL.
+
+## Python Changes
+
+- Added a new AMI mapping that returns Ice.Future. The Future class provides an API
+ that is compatible with concurrent.futures.Future, with some additional Ice-specific
+ methods. Programs can use the new mapping by adding the suffix `Async` to operation
+ names, such as `sayHelloAsync`. The existing `begin_/end_` mapping is still supported.
+
+- Changed the AMD mapping. AMD servant methods must no longer append the `_async` suffix to
+ their names. Additionally, an AMD callback is no longer passed to a servant method.
+ Now a servant method always uses the mapped name, and it can either return the results
+ (for a synchronous implementation) or return an Ice.Future (for an asynchronous
+ implementation).
+
+ With Python 3, a servant method can also be implemented as a coroutine. Ice will start
+ the coroutine, and coroutines can `await` on Ice.Future objects. Note that because Ice
+ is multithreaded, users who also want to use the asyncio package must make sure it's
+ done in a thread-safe manner. To assist with this, the Ice.wrap_future() function accepts
+ an Ice.Future and returns an asyncio.Future.
diff --git a/cpp/include/Ice/AsyncResult.h b/cpp/include/Ice/AsyncResult.h
index e2c1d53d53b..639a44ed278 100644
--- a/cpp/include/Ice/AsyncResult.h
+++ b/cpp/include/Ice/AsyncResult.h
@@ -62,6 +62,16 @@ public:
static void check(const AsyncResultPtr&, const Connection*, const ::std::string&);
static void check(const AsyncResultPtr&, const Communicator*, const ::std::string&);
+ class Callback : public IceUtil::Shared
+ {
+ public:
+
+ virtual void run() = 0;
+ };
+ typedef IceUtil::Handle<Callback> CallbackPtr;
+
+ virtual void scheduleCallback(const CallbackPtr&) = 0;
+
protected:
static void check(const AsyncResultPtr&, const ::std::string&);
diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h
index 86d017dbfe1..cb83850a048 100644
--- a/cpp/include/Ice/OutgoingAsync.h
+++ b/cpp/include/Ice/OutgoingAsync.h
@@ -107,6 +107,8 @@ public:
virtual void readEmptyParams();
virtual void readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&);
virtual void throwUserException();
+
+ virtual void scheduleCallback(const CallbackPtr&);
#endif
void attachRemoteObserver(const Ice::ConnectionInfoPtr& c, const Ice::EndpointPtr& endpt, Ice::Int requestId)
diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp
index 060f9019e72..40c753fe656 100644
--- a/cpp/src/Ice/OutgoingAsync.cpp
+++ b/cpp/src/Ice/OutgoingAsync.cpp
@@ -124,8 +124,7 @@ OutgoingAsyncBase::invokeExceptionAsync()
};
//
- // CommunicatorDestroyedCompleted is the only exception that can propagate directly
- // from this method.
+ // CommunicatorDestroyedException is the only exception that can propagate directly from this method.
//
_instance->clientThreadPool()->dispatch(new AsynchronousException(_cachedConnection, ICE_SHARED_FROM_THIS));
}
@@ -154,8 +153,7 @@ OutgoingAsyncBase::invokeResponseAsync()
};
//
- // CommunicatorDestroyedCompleted is the only exception that can propagate directly
- // from this method.
+ // CommunicatorDestroyedException is the only exception that can propagate directly from this method.
//
_instance->clientThreadPool()->dispatch(new AsynchronousResponse(_cachedConnection, ICE_SHARED_FROM_THIS));
}
@@ -534,6 +532,37 @@ OutgoingAsyncBase::throwUserException()
}
}
+void
+OutgoingAsyncBase::scheduleCallback(const CallbackPtr& cb)
+{
+ class WorkItem : public DispatchWorkItem
+ {
+ public:
+
+ WorkItem(const CallbackPtr& cb) : _cb(cb) {}
+
+ virtual void run()
+ {
+ try
+ {
+ _cb->run();
+ }
+ catch(...)
+ {
+ }
+ }
+
+ private:
+
+ CallbackPtr _cb;
+ };
+
+ //
+ // CommunicatorDestroyedException is the only exception that can propagate directly from this method.
+ //
+ _instance->clientThreadPool()->dispatch(new WorkItem(cb));
+}
+
#endif
void
diff --git a/cpp/src/Slice/Python.cpp b/cpp/src/Slice/Python.cpp
index cf46117d345..b602b09a1c0 100644
--- a/cpp/src/Slice/Python.cpp
+++ b/cpp/src/Slice/Python.cpp
@@ -401,10 +401,7 @@ usage(const string& n)
"--all Generate code for Slice definitions in included files.\n"
"--checksum Generate checksums for Slice definitions.\n"
"--prefix PREFIX Prepend filenames of Python modules with PREFIX.\n"
- "--ice Allow reserved Ice prefix in Slice identifiers\n"
- " deprecated: use instead [[\"ice-prefix\"]] metadata.\n"
- "--underscore Allow underscores in Slice identifiers\n"
- " deprecated: use instead [[\"underscore\"]] metadata.\n"
+ "--python3 Generate code for the Python 3 mapping.\n"
;
}
@@ -432,6 +429,7 @@ Slice::Python::compile(const vector<string>& argv)
opts.addOpt("", "build-package");
opts.addOpt("", "checksum");
opts.addOpt("", "prefix", IceUtilInternal::Options::NeedArg);
+ opts.addOpt("", "python3");
vector<string> args;
try
@@ -502,6 +500,8 @@ Slice::Python::compile(const vector<string>& argv)
string prefix = opts.optArg("prefix");
+ bool python3 = opts.isSet("python3");
+
if(args.empty())
{
getErrorStream() << argv[0] << ": error: no input file" << endl;
@@ -661,15 +661,17 @@ Slice::Python::compile(const vector<string>& argv)
FileTracker::instance()->addFile(file);
//
- // Python magic comment to set the file encoding, it must be first or second line
+ // Emit a Python magic comment to set the file encoding.
+ // It must be the first or second line.
//
out << "# -*- coding: utf-8 -*-\n";
printHeader(out);
printGeneratedHeader(out, base + ".ice", "#");
+
//
- // Generate the Python mapping.
+ // Generate Python code.
//
- generate(u, all, checksum, includePaths, out);
+ generate(u, all, checksum, python3, includePaths, out);
out.close();
}
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index b07e605a1ed..c8759a6124c 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -87,7 +87,7 @@ class CodeVisitor : public ParserVisitor
{
public:
- CodeVisitor(IceUtilInternal::Output&, set<string>&);
+ CodeVisitor(IceUtilInternal::Output&, set<string>&, bool);
virtual bool visitModuleStart(const ModulePtr&);
virtual void visitModuleEnd(const ModulePtr&);
@@ -181,12 +181,13 @@ private:
};
bool parseOpComment(const string&, OpComment&);
- enum DocstringMode { DocSync, DocAsyncBegin, DocAsyncEnd, DocDispatch, DocAsyncDispatch };
+ enum DocstringMode { DocSync, DocAsync, DocAsyncBegin, DocAsyncEnd, DocDispatch, DocAsyncDispatch };
void writeDocstring(const OperationPtr&, DocstringMode, bool);
Output& _out;
set<string>& _moduleHistory;
+ const bool _python3;
list<string> _moduleStack;
set<string> _classHistory;
};
@@ -315,8 +316,8 @@ Slice::Python::ModuleVisitor::visitModuleStart(const ModulePtr& p)
//
// CodeVisitor implementation.
//
-Slice::Python::CodeVisitor::CodeVisitor(Output& out, set<string>& moduleHistory) :
- _out(out), _moduleHistory(moduleHistory)
+Slice::Python::CodeVisitor::CodeVisitor(Output& out, set<string>& moduleHistory, bool python3) :
+ _out(out), _moduleHistory(moduleHistory), _python3(python3)
{
}
@@ -563,9 +564,9 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
{
string fixedOpName = fixIdent((*oli)->name());
- if(!p->isLocal() && (p->hasMetaData("amd") || (*oli)->hasMetaData("amd")))
+ if(!p->isLocal())
{
- _out << sp << nl << "def " << (*oli)->name() << "_async(self, _cb";
+ _out << sp << nl << "def " << fixedOpName << "(self";
ParamDeclList params = (*oli)->parameters();
@@ -695,6 +696,23 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
// Async operations.
//
_out << sp;
+ writeDocstring(*oli, DocAsync, false);
+ _out << nl << "def " << (*oli)->name() << "Async(self";
+ if(!inParams.empty())
+ {
+ _out << ", " << inParams;
+ }
+ _out << ", _ctx=None):";
+ _out.inc();
+ _out << nl << "return _M_" << abs << "._op_" << (*oli)->name() << ".invokeAsync(self, ((" << inParams;
+ if(!inParams.empty() && inParams.find(',') == string::npos)
+ {
+ _out << ", ";
+ }
+ _out << "), _ctx))";
+ _out.dec();
+
+ _out << sp;
writeDocstring(*oli, DocAsyncBegin, false);
_out << nl << "def begin_" << (*oli)->name() << "(self";
if(!inParams.empty())
@@ -2486,7 +2504,7 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
{
return;
}
- else if(mode == DocAsyncBegin && inParams.empty())
+ else if((mode == DocAsync || mode == DocAsyncBegin) && inParams.empty())
{
return;
}
@@ -2519,6 +2537,7 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
switch(mode)
{
case DocSync:
+ case DocAsync:
case DocAsyncBegin:
case DocDispatch:
needArgs = !local || !inParams.empty();
@@ -2532,10 +2551,6 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
if(needArgs)
{
_out << nl << "Arguments:";
- if(mode == DocAsyncDispatch)
- {
- _out << nl << "_cb -- The asynchronous callback object.";
- }
for(vector<string>::iterator q = inParams.begin(); q != inParams.end(); ++q)
{
string fixed = fixIdent(*q);
@@ -2556,7 +2571,7 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
<< nl << "_ex -- The asynchronous exception callback."
<< nl << "_sent -- The asynchronous sent callback.";
}
- if(!local && (mode == DocSync || mode == DocAsyncBegin))
+ if(!local && (mode == DocSync || mode == DocAsync || mode == DocAsyncBegin))
{
_out << nl << "_ctx -- The request context for the invocation.";
}
@@ -2574,6 +2589,10 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
//
// Emit return value(s).
//
+ if(mode == DocAsync || mode == DocAsyncDispatch)
+ {
+ _out << nl << "Returns: A future object for the invocation.";
+ }
if(mode == DocAsyncBegin)
{
_out << nl << "Returns: An asynchronous result object for the invocation.";
@@ -2641,7 +2660,8 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
}
void
-Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector<string>& includePaths, Output& out)
+Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, bool python3, const vector<string>& includePaths,
+ Output& out)
{
Slice::Python::MetaDataVisitor visitor;
un->visit(&visitor, false);
@@ -2671,7 +2691,7 @@ Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector
ModuleVisitor moduleVisitor(out, moduleHistory);
un->visit(&moduleVisitor, true);
- CodeVisitor codeVisitor(out, moduleHistory);
+ CodeVisitor codeVisitor(out, moduleHistory, python3);
un->visit(&codeVisitor, false);
if(checksum)
diff --git a/cpp/src/Slice/PythonUtil.h b/cpp/src/Slice/PythonUtil.h
index 9d48b3d3871..0966d4ba6a9 100644
--- a/cpp/src/Slice/PythonUtil.h
+++ b/cpp/src/Slice/PythonUtil.h
@@ -21,7 +21,7 @@ namespace Python
//
// Generate Python code for a translation unit.
//
-void generate(const Slice::UnitPtr&, bool, bool, const std::vector<std::string>&, IceUtilInternal::Output&);
+void generate(const Slice::UnitPtr&, bool, bool, bool, const std::vector<std::string>&, IceUtilInternal::Output&);
//
// Convert a scoped name into a Python name.
diff --git a/python/modules/IcePy/Communicator.cpp b/python/modules/IcePy/Communicator.cpp
index eb223c85853..927c3cab5d2 100644
--- a/python/modules/IcePy/Communicator.cpp
+++ b/python/modules/IcePy/Communicator.cpp
@@ -723,6 +723,48 @@ communicatorFlushBatchRequests(CommunicatorObject* self)
extern "C"
#endif
static PyObject*
+communicatorFlushBatchRequestsAsync(CommunicatorObject* self, PyObject* /*args*/, PyObject* /*kwds*/)
+{
+ assert(self->communicator);
+ const string op = "flushBatchRequests";
+
+ FlushAsyncCallbackPtr d = new FlushAsyncCallback(op);
+ Ice::Callback_Communicator_flushBatchRequestsPtr cb =
+ Ice::newCallback_Communicator_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent);
+
+ Ice::AsyncResultPtr result;
+
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+
+ result = (*self->communicator)->begin_flushBatchRequests(cb);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ PyObjectHandle asyncResultObj = createAsyncResult(result, 0, 0, self->wrapper);
+ if(!asyncResultObj.get())
+ {
+ return 0;
+ }
+
+ PyObjectHandle future = createFuture(op, asyncResultObj.get());
+ if(!future.get())
+ {
+ return 0;
+ }
+ d->setFuture(future.get());
+ return future.release();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
communicatorBeginFlushBatchRequests(CommunicatorObject* self, PyObject* args, PyObject* kwds)
{
assert(self->communicator);
@@ -1608,6 +1650,8 @@ static PyMethodDef CommunicatorMethods[] =
PyDoc_STR(STRCAST("setDefaultLocator(proxy) -> None")) },
{ STRCAST("flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorFlushBatchRequests), METH_NOARGS,
PyDoc_STR(STRCAST("flushBatchRequests() -> None")) },
+ { STRCAST("flushBatchRequestsAsync"), reinterpret_cast<PyCFunction>(communicatorFlushBatchRequestsAsync),
+ METH_NOARGS, PyDoc_STR(STRCAST("flushBatchRequestsAsync() -> Ice.Future")) },
{ STRCAST("begin_flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorBeginFlushBatchRequests),
METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) },
@@ -1734,8 +1778,19 @@ IcePy::getCommunicatorWrapper(const Ice::CommunicatorPtr& communicator)
CommunicatorMap::iterator p = _communicatorMap.find(communicator);
assert(p != _communicatorMap.end());
CommunicatorObject* obj = reinterpret_cast<CommunicatorObject*>(p->second);
- Py_INCREF(obj->wrapper);
- return obj->wrapper;
+ if(obj->wrapper)
+ {
+ Py_INCREF(obj->wrapper);
+ return obj->wrapper;
+ }
+ else
+ {
+ //
+ // Communicator must have been destroyed already.
+ //
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
}
extern "C"
diff --git a/python/modules/IcePy/Connection.cpp b/python/modules/IcePy/Connection.cpp
index 2f5998bffc9..ec1e4f8db68 100644
--- a/python/modules/IcePy/Connection.cpp
+++ b/python/modules/IcePy/Connection.cpp
@@ -379,6 +379,50 @@ connectionFlushBatchRequests(ConnectionObject* self)
extern "C"
#endif
static PyObject*
+connectionFlushBatchRequestsAsync(ConnectionObject* self, PyObject* /*args*/, PyObject* /*kwds*/)
+{
+ assert(self->connection);
+ const string op = "flushBatchRequests";
+
+ FlushAsyncCallbackPtr d = new FlushAsyncCallback(op);
+ Ice::Callback_Connection_flushBatchRequestsPtr cb =
+ Ice::newCallback_Connection_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent);
+
+ Ice::AsyncResultPtr result;
+
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+
+ result = (*self->connection)->begin_flushBatchRequests(cb);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator);
+ PyObjectHandle asyncResultObj =
+ createAsyncResult(result, 0, reinterpret_cast<PyObject*>(self), communicatorObj.get());
+ if(!asyncResultObj.get())
+ {
+ return 0;
+ }
+
+ PyObjectHandle future = createFuture(op, asyncResultObj.get());
+ if(!future.get())
+ {
+ return 0;
+ }
+ d->setFuture(future.get());
+ return future.release();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
connectionBeginFlushBatchRequests(ConnectionObject* self, PyObject* args, PyObject* kwds)
{
assert(self->connection);
@@ -821,6 +865,8 @@ static PyMethodDef ConnectionMethods[] =
PyDoc_STR(STRCAST("getAdapter() -> Ice.ObjectAdapter")) },
{ STRCAST("flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionFlushBatchRequests), METH_NOARGS,
PyDoc_STR(STRCAST("flushBatchRequests() -> None")) },
+ { STRCAST("flushBatchRequestsAsync"), reinterpret_cast<PyCFunction>(connectionFlushBatchRequestsAsync),
+ METH_NOARGS, PyDoc_STR(STRCAST("flushBatchRequestsAsync() -> Ice.Future")) },
{ STRCAST("begin_flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionBeginFlushBatchRequests),
METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) },
{ STRCAST("end_flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionEndFlushBatchRequests), METH_VARARGS,
diff --git a/python/modules/IcePy/ObjectAdapter.cpp b/python/modules/IcePy/ObjectAdapter.cpp
index a51cca80c93..d2718b1ca50 100644
--- a/python/modules/IcePy/ObjectAdapter.cpp
+++ b/python/modules/IcePy/ObjectAdapter.cpp
@@ -181,7 +181,7 @@ IcePy::ServantLocatorWrapper::locate(const Ice::Current& current, Ice::LocalObje
{
if(PyTuple_GET_SIZE(res.get()) > 2)
{
- PyErr_Warn(PyExc_RuntimeWarning, STRCAST("invalid return value for ServantLocator::locate"));
+ PyErr_WarnEx(PyExc_RuntimeWarning, STRCAST("invalid return value for ServantLocator::locate"), 1);
return 0;
}
servantObj = PyTuple_GET_ITEM(res.get(), 0);
@@ -200,7 +200,7 @@ IcePy::ServantLocatorWrapper::locate(const Ice::Current& current, Ice::LocalObje
//
if(!PyObject_IsInstance(servantObj, _objectType))
{
- PyErr_Warn(PyExc_RuntimeWarning, STRCAST("return value of ServantLocator::locate is not an Ice object"));
+ PyErr_WarnEx(PyExc_RuntimeWarning, STRCAST("return value of ServantLocator::locate is not an Ice object"), 1);
return 0;
}
diff --git a/python/modules/IcePy/Operation.cpp b/python/modules/IcePy/Operation.cpp
index 3b62b8aef59..6c32d861806 100644
--- a/python/modules/IcePy/Operation.cpp
+++ b/python/modules/IcePy/Operation.cpp
@@ -27,6 +27,7 @@
#include <Ice/AsyncResult.h>
#include <Ice/Properties.h>
#include <Ice/Proxy.h>
+#include <IceUtil/Time.h>
#include <Slice/PythonUtil.h>
using namespace std;
@@ -104,50 +105,44 @@ public:
protected:
- Ice::ObjectPrx _prx;
-};
-typedef IceUtil::Handle<Invocation> InvocationPtr;
-
-//
-// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal
-// parameters and exceptions.
-//
-class TypedInvocation : virtual public Invocation
-{
-public:
+ //
+ // Helpers for typed invocations.
+ //
- TypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
+ enum MappingType { SyncMapping, AsyncMapping, NewAsyncMapping };
-protected:
+ bool prepareRequest(const OperationPtr&, PyObject*, MappingType, Ice::OutputStream*,
+ pair<const Ice::Byte*, const Ice::Byte*>&);
+ PyObject* unmarshalResults(const OperationPtr&, const pair<const Ice::Byte*, const Ice::Byte*>&);
+ PyObject* unmarshalException(const OperationPtr&, const pair<const Ice::Byte*, const Ice::Byte*>&);
+ bool validateException(const OperationPtr&, PyObject*) const;
+ void checkTwowayOnly(const OperationPtr&, const Ice::ObjectPrx&) const;
- OperationPtr _op;
+ Ice::ObjectPrx _prx;
Ice::CommunicatorPtr _communicator;
-
- enum MappingType { SyncMapping, AsyncMapping, OldAsyncMapping };
-
- bool prepareRequest(PyObject*, MappingType, Ice::OutputStream*, pair<const Ice::Byte*, const Ice::Byte*>&);
- PyObject* unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>&);
- PyObject* unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>&);
- bool validateException(PyObject*) const;
- void checkTwowayOnly(const Ice::ObjectPrx&) const;
};
+typedef IceUtil::Handle<Invocation> InvocationPtr;
//
// Synchronous typed invocation.
//
-class SyncTypedInvocation : virtual public TypedInvocation
+class SyncTypedInvocation : public Invocation
{
public:
SyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
virtual PyObject* invoke(PyObject*, PyObject* = 0);
+
+private:
+
+ OperationPtr _op;
};
//
// Asynchronous typed invocation.
//
-class AsyncTypedInvocation : virtual public TypedInvocation
+class AsyncTypedInvocation : public Invocation
{
public:
@@ -163,10 +158,11 @@ public:
void exception(const Ice::Exception&);
void sent(bool);
-protected:
+private:
void checkAsyncTwowayOnly(const Ice::ObjectPrx&) const;
+ OperationPtr _op;
PyObject* _pyProxy;
PyObject* _response;
PyObject* _ex;
@@ -175,14 +171,14 @@ protected:
typedef IceUtil::Handle<AsyncTypedInvocation> AsyncTypedInvocationPtr;
//
-// Old-style asynchronous typed invocation.
+// Asynchronous invocation with futures.
//
-class OldAsyncTypedInvocation : virtual public TypedInvocation
+class NewAsyncInvocation : public Invocation
{
public:
- OldAsyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&);
- ~OldAsyncTypedInvocation();
+ NewAsyncInvocation(const Ice::ObjectPrx&, PyObject*, const string&);
+ ~NewAsyncInvocation();
virtual PyObject* invoke(PyObject*, PyObject* = 0);
@@ -192,13 +188,47 @@ public:
protected:
- PyObject* _callback;
+ virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*) = 0;
+ virtual void handleResponse(PyObject*, bool, const pair<const Ice::Byte*, const Ice::Byte*>&) = 0;
+
+ PyObject* _pyProxy;
+ string _operation;
+ bool _twoway;
+ bool _sent;
+ bool _sentSynchronously;
+ bool _done;
+ PyObject* _future;
+ bool _ok;
+ vector<Ice::Byte> _results;
+ PyObject* _exception;
+};
+typedef IceUtil::Handle<NewAsyncInvocation> NewAsyncInvocationPtr;
+
+//
+// New-style asynchronous typed invocation.
+//
+class NewAsyncTypedInvocation : public NewAsyncInvocation
+{
+public:
+
+ NewAsyncTypedInvocation(const Ice::ObjectPrx&, PyObject*, const OperationPtr&);
+
+protected:
+
+ virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*);
+ virtual void handleResponse(PyObject*, bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
+
+private:
+
+ void checkAsyncTwowayOnly(const Ice::ObjectPrx&) const;
+
+ OperationPtr _op;
};
//
// Synchronous blobject invocation.
//
-class SyncBlobjectInvocation : virtual public Invocation
+class SyncBlobjectInvocation : public Invocation
{
public:
@@ -210,7 +240,7 @@ public:
//
// Asynchronous blobject invocation.
//
-class AsyncBlobjectInvocation : virtual public Invocation
+class AsyncBlobjectInvocation : public Invocation
{
public:
@@ -235,80 +265,83 @@ protected:
typedef IceUtil::Handle<AsyncBlobjectInvocation> AsyncBlobjectInvocationPtr;
//
-// Old-style asynchronous blobject invocation.
+// New-style asynchronous blobject invocation.
//
-class OldAsyncBlobjectInvocation : virtual public Invocation
+class NewAsyncBlobjectInvocation : public NewAsyncInvocation
{
public:
- OldAsyncBlobjectInvocation(const Ice::ObjectPrx&);
- ~OldAsyncBlobjectInvocation();
-
- virtual PyObject* invoke(PyObject*, PyObject* = 0);
-
- void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
- void exception(const Ice::Exception&);
- void sent(bool);
+ NewAsyncBlobjectInvocation(const Ice::ObjectPrx&, PyObject*);
protected:
+ virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*);
+ virtual void handleResponse(PyObject*, bool, const pair<const Ice::Byte*, const Ice::Byte*>&);
+
string _op;
- PyObject* _callback;
};
//
// The base class for server-side upcalls.
//
-class Upcall : virtual public IceUtil::Shared
+class Upcall : public IceUtil::Shared
{
public:
virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&) = 0;
- virtual void response(PyObject*, const Ice::EncodingVersion&) = 0;
- virtual void exception(PyException&, const Ice::EncodingVersion&) = 0;
+ virtual void response(PyObject*) = 0;
+ virtual void exception(PyException&) = 0;
+ virtual void exception(const Ice::Exception&) = 0;
+
+protected:
+
+ void dispatchImpl(PyObject*, const string&, PyObject*, const Ice::Current&);
};
typedef IceUtil::Handle<Upcall> UpcallPtr;
//
-// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal
+// TypedUpcall uses the information in the given Operation to validate, marshal, and unmarshal
// parameters and exceptions.
//
-class TypedUpcall : virtual public Upcall
+class TypedUpcall;
+typedef IceUtil::Handle<TypedUpcall> TypedUpcallPtr;
+
+class TypedUpcall : public Upcall
{
public:
TypedUpcall(const OperationPtr&, const Ice::AMD_Object_ice_invokePtr&, const Ice::CommunicatorPtr&);
virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&);
- virtual void response(PyObject*, const Ice::EncodingVersion&);
- virtual void exception(PyException&, const Ice::EncodingVersion&);
+ virtual void response(PyObject*);
+ virtual void exception(PyException&);
+ virtual void exception(const Ice::Exception&);
private:
OperationPtr _op;
Ice::AMD_Object_ice_invokePtr _callback;
Ice::CommunicatorPtr _communicator;
- bool _finished;
+ Ice::EncodingVersion _encoding;
};
//
// Upcall for blobject servants.
//
-class BlobjectUpcall : virtual public Upcall
+class BlobjectUpcall : public Upcall
{
public:
- BlobjectUpcall(bool, const Ice::AMD_Object_ice_invokePtr&);
+ BlobjectUpcall(const Ice::AMD_Object_ice_invokePtr&);
virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&);
- virtual void response(PyObject*, const Ice::EncodingVersion&);
- virtual void exception(PyException&, const Ice::EncodingVersion&);
+ virtual void response(PyObject*);
+ virtual void exception(PyException&);
+ virtual void exception(const Ice::Exception&);
private:
- bool _amd;
Ice::AMD_Object_ice_invokePtr _callback;
- bool _finished;
};
//
@@ -356,11 +389,19 @@ struct OperationObject
OperationPtr* op;
};
-struct AMDCallbackObject
+struct DoneCallbackObject
+{
+ PyObject_HEAD
+ UpcallPtr* upcall;
+#if PY_VERSION_HEX >= 0x03050000
+ PyObject* coroutine;
+#endif
+};
+
+struct DispatchCallbackObject
{
PyObject_HEAD
UpcallPtr* upcall;
- Ice::EncodingVersion encoding;
};
struct AsyncResultObject
@@ -374,7 +415,6 @@ struct AsyncResultObject
};
extern PyTypeObject OperationType;
-extern PyTypeObject AMDCallbackType;
class UserExceptionFactory : public Ice::UserExceptionFactory
{
@@ -424,8 +464,7 @@ handleException()
void
callException(PyObject* method, PyObject* ex)
{
- PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), ex);
- PyObjectHandle tmp = PyObject_Call(method, args.get(), 0);
+ PyObjectHandle tmp = callMethod(method, ex);
if(PyErr_Occurred())
{
handleException(); // Callback raised an exception.
@@ -441,61 +480,20 @@ callException(PyObject* method, const Ice::Exception& ex)
}
void
-callException(PyObject* callback, const string& op, const string& method, PyObject* ex)
-{
- if(!PyObject_HasAttrString(callback, STRCAST(method.c_str())))
- {
- ostringstream ostr;
- ostr << "AMI callback object for operation `" << op << "' does not define " << method << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
- else
- {
- PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str()));
- assert(m.get());
- callException(m.get(), ex);
- }
-}
-
-void
-callException(PyObject* callback, const string& op, const string& method, const Ice::Exception& ex)
-{
- PyObjectHandle exh = convertException(ex);
- assert(exh.get());
- callException(callback, op, method, exh.get());
-}
-
-void
callSent(PyObject* method, bool sentSynchronously, bool passArg)
{
- PyObjectHandle args;
+ PyObject* arg = 0;
if(passArg)
{
- args = Py_BuildValue(STRCAST("(O)"), sentSynchronously ? getTrue() : getFalse());
+ arg = sentSynchronously ? getTrue() : getFalse();
}
- else
- {
- args = PyTuple_New(0);
- }
- PyObjectHandle tmp = PyObject_Call(method, args.get(), 0);
+ PyObjectHandle tmp = callMethod(method, arg);
if(PyErr_Occurred())
{
handleException(); // Callback raised an exception.
}
}
-void
-callSent(PyObject* callback, const string& method, bool sentSynchronously, bool passArg)
-{
- if(PyObject_HasAttrString(callback, STRCAST(method.c_str())))
- {
- PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str()));
- assert(m.get());
- callSent(m.get(), sentSynchronously, passArg);
- }
-}
-
}
#ifdef WIN32
@@ -581,17 +579,15 @@ extern "C"
static PyObject*
operationInvokeAsync(OperationObject* self, PyObject* args)
{
- PyObject* pyProxy;
+ PyObject* proxy;
PyObject* opArgs;
- if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &pyProxy, &PyTuple_Type, &opArgs))
+ if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &proxy, &PyTuple_Type, &opArgs))
{
return 0;
}
- Ice::ObjectPrx prx = getProxy(pyProxy);
- assert(self->op);
-
- InvocationPtr i = new OldAsyncTypedInvocation(prx, *self->op);
+ Ice::ObjectPrx p = getProxy(proxy);
+ InvocationPtr i = new NewAsyncTypedInvocation(p, proxy, *self->op);
return i->invoke(opArgs);
}
@@ -654,26 +650,28 @@ operationDeprecate(OperationObject* self, PyObject* args)
assert(self->op);
(*self->op)->deprecate(msg);
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
//
-// AMDCallback operations
+// DoneCallback operations
//
#ifdef WIN32
extern "C"
#endif
-static AMDCallbackObject*
-amdCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
+static DoneCallbackObject*
+doneCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
{
- AMDCallbackObject* self = reinterpret_cast<AMDCallbackObject*>(type->tp_alloc(type, 0));
+ DoneCallbackObject* self = reinterpret_cast<DoneCallbackObject*>(type->tp_alloc(type, 0));
if(!self)
{
return 0;
}
self->upcall = 0;
+#if PY_VERSION_HEX >= 0x03050000
+ self->coroutine = 0;
+#endif
return self;
}
@@ -681,9 +679,12 @@ amdCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
extern "C"
#endif
static void
-amdCallbackDealloc(AMDCallbackObject* self)
+doneCallbackDealloc(DoneCallbackObject* self)
{
delete self->upcall;
+#if PY_VERSION_HEX >= 0x03050000
+ Py_XDECREF(self->coroutine);
+#endif
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}
@@ -691,12 +692,32 @@ amdCallbackDealloc(AMDCallbackObject* self)
extern "C"
#endif
static PyObject*
-amdCallbackIceResponse(AMDCallbackObject* self, PyObject* args)
+doneCallbackInvoke(DoneCallbackObject* self, PyObject* args)
{
+ PyObject* future = 0;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &future))
+ {
+ return 0;
+ }
+
try
{
assert(self->upcall);
- (*self->upcall)->response(args, self->encoding);
+
+ PyObjectHandle resultMethod = PyObject_GetAttrString(future, STRCAST("result"));
+ assert(resultMethod.get());
+ PyObjectHandle empty = PyTuple_New(0);
+ PyObjectHandle result = PyObject_Call(resultMethod.get(), empty.get(), 0);
+
+ if(PyErr_Occurred())
+ {
+ PyException ex;
+ (*self->upcall)->exception(ex);
+ }
+ else
+ {
+ (*self->upcall)->response(result.get());
+ }
}
catch(...)
{
@@ -706,33 +727,83 @@ amdCallbackIceResponse(AMDCallbackObject* self, PyObject* args)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
+}
+
+//
+// DispatchCallbackObject operations
+//
+
+#ifdef WIN32
+extern "C"
+#endif
+static DispatchCallbackObject*
+dispatchCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/)
+{
+ DispatchCallbackObject* self = reinterpret_cast<DispatchCallbackObject*>(type->tp_alloc(type, 0));
+ if(!self)
+ {
+ return 0;
+ }
+ self->upcall = 0;
+ return self;
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static void
+dispatchCallbackDealloc(DispatchCallbackObject* self)
+{
+ delete self->upcall;
+ Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}
#ifdef WIN32
extern "C"
#endif
static PyObject*
-amdCallbackIceException(AMDCallbackObject* self, PyObject* args)
+dispatchCallbackResponse(DispatchCallbackObject* self, PyObject* args)
{
- PyObject* ex;
- if(!PyArg_ParseTuple(args, STRCAST("O"), &ex))
+ PyObject* result = 0;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &result))
{
return 0;
}
- if(!PyObject_IsInstance(ex, PyExc_Exception))
+ try
+ {
+ assert(self->upcall);
+ (*self->upcall)->response(result);
+ }
+ catch(...)
+ {
+ //
+ // No exceptions should propagate to Python.
+ //
+ assert(false);
+ }
+
+ return incRef(Py_None);
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
+dispatchCallbackException(DispatchCallbackObject* self, PyObject* args)
+{
+ PyObject* ex = 0;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &ex))
{
- PyErr_Format(PyExc_TypeError, "ice_exception argument is not an exception");
return 0;
}
try
{
assert(self->upcall);
- PyException pye(ex); // No traceback information available.
- (*self->upcall)->exception(pye, self->encoding);
+ PyException pyex(ex);
+ (*self->upcall)->exception(pyex);
}
catch(...)
{
@@ -742,8 +813,7 @@ amdCallbackIceException(AMDCallbackObject* self, PyObject* args)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
//
@@ -791,12 +861,10 @@ asyncResultGetCommunicator(AsyncResultObject* self)
{
if(self->communicator)
{
- Py_INCREF(self->communicator);
- return self->communicator;
+ return incRef(self->communicator);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -814,8 +882,7 @@ asyncResultCancel(AsyncResultObject* self)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -826,12 +893,10 @@ asyncResultGetConnection(AsyncResultObject* self)
{
if(self->connection)
{
- Py_INCREF(self->connection);
- return self->connection;
+ return incRef(self->connection);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -842,12 +907,10 @@ asyncResultGetProxy(AsyncResultObject* self)
{
if(self->proxy)
{
- Py_INCREF(self->proxy);
- return self->proxy;
+ return incRef(self->proxy);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -888,8 +951,7 @@ asyncResultWaitForCompleted(AsyncResultObject* self)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -930,8 +992,7 @@ asyncResultWaitForSent(AsyncResultObject* self)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -955,8 +1016,7 @@ asyncResultThrowLocalException(AsyncResultObject* self)
assert(false);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
#ifdef WIN32
@@ -1017,6 +1077,72 @@ asyncResultGetOperation(AsyncResultObject* self)
return createString(op);
}
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
+asyncResultCallLater(AsyncResultObject* self, PyObject* args)
+{
+ PyObject* callback;
+ if(!PyArg_ParseTuple(args, STRCAST("O"), &callback))
+ {
+ return 0;
+ }
+
+ if(!PyCallable_Check(callback))
+ {
+ PyErr_Format(PyExc_ValueError, STRCAST("invalid argument passed to callLater"));
+ return 0;
+ }
+
+ class CallbackI : public Ice::AsyncResult::Callback
+ {
+ public:
+
+ CallbackI(PyObject* callback) :
+ _callback(incRef(callback))
+ {
+ }
+
+ ~CallbackI()
+ {
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ Py_DECREF(_callback);
+ }
+
+ virtual void run()
+ {
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ PyObjectHandle args = PyTuple_New(0);
+ assert(args.get());
+ PyObjectHandle tmp = PyObject_Call(_callback, args.get(), 0);
+ PyErr_Clear();
+ }
+
+ private:
+
+ PyObject* _callback;
+ };
+
+ try
+ {
+ (*self->result)->scheduleCallback(new CallbackI(callback));
+ }
+ catch(const Ice::CommunicatorDestroyedException& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+ catch(...)
+ {
+ assert(false);
+ }
+
+ return incRef(Py_None);
+}
+
//
// ParamInfo implementation.
//
@@ -1025,8 +1151,7 @@ IcePy::ParamInfo::unmarshaled(PyObject* val, PyObject* target, void* closure)
{
assert(PyTuple_Check(target));
Py_ssize_t i = reinterpret_cast<Py_ssize_t>(closure);
- PyTuple_SET_ITEM(target, i, val);
- Py_INCREF(val); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(target, i, incRef(val)); // PyTuple_SET_ITEM steals a reference.
}
//
@@ -1055,14 +1180,7 @@ IcePy::Operation::Operation(const char* n, PyObject* m, PyObject* sm, int amdFla
// amd
//
amd = amdFlag ? true : false;
- if(amd)
- {
- dispatchName = name + "_async";
- }
- else
- {
- dispatchName = fixIdent(name);
- }
+ dispatchName = fixIdent(name); // Use the same dispatch name regardless of AMD.
//
// format
@@ -1252,11 +1370,18 @@ static PyMethodDef OperationMethods[] =
{ 0, 0 } /* sentinel */
};
-static PyMethodDef AMDCallbackMethods[] =
+static PyMethodDef DoneCallbackMethods[] =
+{
+ { STRCAST("invoke"), reinterpret_cast<PyCFunction>(doneCallbackInvoke), METH_VARARGS,
+ PyDoc_STR(STRCAST("internal function")) },
+ { 0, 0 } /* sentinel */
+};
+
+static PyMethodDef DispatchCallbackMethods[] =
{
- { STRCAST("ice_response"), reinterpret_cast<PyCFunction>(amdCallbackIceResponse), METH_VARARGS,
+ { STRCAST("response"), reinterpret_cast<PyCFunction>(dispatchCallbackResponse), METH_VARARGS,
PyDoc_STR(STRCAST("internal function")) },
- { STRCAST("ice_exception"), reinterpret_cast<PyCFunction>(amdCallbackIceException), METH_VARARGS,
+ { STRCAST("exception"), reinterpret_cast<PyCFunction>(dispatchCallbackException), METH_VARARGS,
PyDoc_STR(STRCAST("internal function")) },
{ 0, 0 } /* sentinel */
};
@@ -1285,6 +1410,8 @@ static PyMethodDef AsyncResultMethods[] =
PyDoc_STR(STRCAST("returns true if the request was sent synchronously")) },
{ STRCAST("getOperation"), reinterpret_cast<PyCFunction>(asyncResultGetOperation), METH_NOARGS,
PyDoc_STR(STRCAST("returns the name of the operation")) },
+ { STRCAST("callLater"), reinterpret_cast<PyCFunction>(asyncResultCallLater), METH_VARARGS,
+ PyDoc_STR(STRCAST("internal function")) },
{ 0, 0 } /* sentinel */
};
@@ -1338,16 +1465,16 @@ PyTypeObject OperationType =
0, /* tp_is_gc */
};
-PyTypeObject AMDCallbackType =
+static PyTypeObject DoneCallbackType =
{
/* The ob_type field must be initialized in the module init function
* to be portable to Windows without using C++. */
PyVarObject_HEAD_INIT(0, 0)
- STRCAST("IcePy.AMDCallback"), /* tp_name */
- sizeof(AMDCallbackObject), /* tp_basicsize */
+ STRCAST("IcePy.DoneCallback"), /* tp_name */
+ sizeof(DoneCallbackObject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
- reinterpret_cast<destructor>(amdCallbackDealloc), /* tp_dealloc */
+ reinterpret_cast<destructor>(doneCallbackDealloc), /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
@@ -1370,7 +1497,7 @@ PyTypeObject AMDCallbackType =
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- AMDCallbackMethods, /* tp_methods */
+ DoneCallbackMethods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@@ -1380,7 +1507,54 @@ PyTypeObject AMDCallbackType =
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- reinterpret_cast<newfunc>(amdCallbackNew), /* tp_new */
+ reinterpret_cast<newfunc>(doneCallbackNew), /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+};
+
+static PyTypeObject DispatchCallbackType =
+{
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(0, 0)
+ STRCAST("IcePy.Dispatch"), /* tp_name */
+ sizeof(DispatchCallbackObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ reinterpret_cast<destructor>(dispatchCallbackDealloc), /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ DispatchCallbackMethods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ reinterpret_cast<newfunc>(dispatchCallbackNew), /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
};
@@ -1447,12 +1621,22 @@ IcePy::initOperation(PyObject* module)
return false;
}
- if(PyType_Ready(&AMDCallbackType) < 0)
+ if(PyType_Ready(&DoneCallbackType) < 0)
{
return false;
}
- PyTypeObject* cbType = &AMDCallbackType; // Necessary to prevent GCC's strict-alias warnings.
- if(PyModule_AddObject(module, STRCAST("AMDCallback"), reinterpret_cast<PyObject*>(cbType)) < 0)
+ PyTypeObject* cbType = &DoneCallbackType; // Necessary to prevent GCC's strict-alias warnings.
+ if(PyModule_AddObject(module, STRCAST("DoneCallback"), reinterpret_cast<PyObject*>(cbType)) < 0)
+ {
+ return false;
+ }
+
+ if(PyType_Ready(&DispatchCallbackType) < 0)
+ {
+ return false;
+ }
+ PyTypeObject* dispatchType = &DispatchCallbackType; // Necessary to prevent GCC's strict-alias warnings.
+ if(PyModule_AddObject(module, STRCAST("DispatchCallback"), reinterpret_cast<PyObject*>(dispatchType)) < 0)
{
return false;
}
@@ -1474,21 +1658,13 @@ IcePy::initOperation(PyObject* module)
// Invocation
//
IcePy::Invocation::Invocation(const Ice::ObjectPrx& prx) :
- _prx(prx)
-{
-}
-
-//
-// TypedInvocation
-//
-IcePy::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) :
- Invocation(prx), _op(op), _communicator(prx->ice_getCommunicator())
+ _prx(prx), _communicator(prx->ice_getCommunicator())
{
}
bool
-IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice::OutputStream* os,
- pair<const Ice::Byte*, const Ice::Byte*>& params)
+IcePy::Invocation::prepareRequest(const OperationPtr& op, PyObject* args, MappingType mapping, Ice::OutputStream* os,
+ pair<const Ice::Byte*, const Ice::Byte*>& params)
{
assert(PyTuple_Check(args));
params.first = params.second = static_cast<const Ice::Byte*>(0);
@@ -1497,35 +1673,35 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
// Validate the number of arguments.
//
Py_ssize_t argc = PyTuple_GET_SIZE(args);
- Py_ssize_t paramCount = static_cast<Py_ssize_t>(_op->inParams.size());
+ Py_ssize_t paramCount = static_cast<Py_ssize_t>(op->inParams.size());
if(argc != paramCount)
{
string opName;
- if(mapping == OldAsyncMapping)
+ if(mapping == NewAsyncMapping)
{
- opName = _op->name + "_async";
+ opName = op->name + "Async";
}
else if(mapping == AsyncMapping)
{
- opName = "begin_" + _op->name;
+ opName = "begin_" + op->name;
}
else
{
- opName = fixIdent(_op->name);
+ opName = fixIdent(op->name);
}
PyErr_Format(PyExc_RuntimeError, STRCAST("%s expects %d in parameters"), opName.c_str(),
static_cast<int>(paramCount));
return false;
}
- if(!_op->inParams.empty())
+ if(!op->inParams.empty())
{
try
{
//
// Marshal the in parameters.
//
- os->startEncapsulation(_prx->ice_getEncodingVersion(), _op->format);
+ os->startEncapsulation(_prx->ice_getEncodingVersion(), op->format);
ObjectMap objectMap;
ParamInfoList::iterator p;
@@ -1533,28 +1709,27 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
//
// Validate the supplied arguments.
//
- for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
+ for(p = op->inParams.begin(); p != op->inParams.end(); ++p)
{
ParamInfoPtr info = *p;
PyObject* arg = PyTuple_GET_ITEM(args, info->pos);
if((!info->optional || arg != Unset) && !info->type->validate(arg))
{
string name;
- if(mapping == OldAsyncMapping)
+ if(mapping == NewAsyncMapping)
{
- name = _op->name + "_async";
+ name = op->name + "Async";
}
else if(mapping == AsyncMapping)
{
- name = "begin_" + _op->name;
+ name = "begin_" + op->name;
}
else
{
- name = fixIdent(_op->name);
+ name = fixIdent(op->name);
}
PyErr_Format(PyExc_ValueError, STRCAST("invalid value for argument %d in operation `%s'"),
- mapping == OldAsyncMapping ? info->pos + 2 : info->pos + 1,
- const_cast<char*>(name.c_str()));
+ info->pos + 1, const_cast<char*>(name.c_str()));
return false;
}
}
@@ -1562,7 +1737,7 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
//
// Marshal the required parameters.
//
- for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p)
+ for(p = op->inParams.begin(); p != op->inParams.end(); ++p)
{
ParamInfoPtr info = *p;
if(!info->optional)
@@ -1575,7 +1750,7 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
//
// Marshal the optional parameters.
//
- for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p)
+ for(p = op->optionalInParams.begin(); p != op->optionalInParams.end(); ++p)
{
ParamInfoPtr info = *p;
PyObject* arg = PyTuple_GET_ITEM(args, info->pos);
@@ -1585,7 +1760,7 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
}
}
- if(_op->sendsClasses)
+ if(op->sendsClasses)
{
os->writePendingValues();
}
@@ -1609,10 +1784,10 @@ IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice:
}
PyObject*
-IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
+IcePy::Invocation::unmarshalResults(const OperationPtr& op, const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
{
- Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size());
- if(_op->returnType)
+ Py_ssize_t numResults = static_cast<Py_ssize_t>(op->outParams.size());
+ if(op->returnType)
{
numResults++;
}
@@ -1637,7 +1812,7 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
//
// Unmarshal the required out parameters.
//
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ for(p = op->outParams.begin(); p != op->outParams.end(); ++p)
{
ParamInfoPtr info = *p;
if(!info->optional)
@@ -1650,17 +1825,17 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
//
// Unmarshal the required return value, if any.
//
- if(_op->returnType && !_op->returnType->optional)
+ if(op->returnType && !op->returnType->optional)
{
- assert(_op->returnType->pos == 0);
- void* closure = reinterpret_cast<void*>(static_cast<Py_ssize_t>(_op->returnType->pos));
- _op->returnType->type->unmarshal(&is, _op->returnType, results.get(), closure, false, &_op->metaData);
+ assert(op->returnType->pos == 0);
+ void* closure = reinterpret_cast<void*>(static_cast<Py_ssize_t>(op->returnType->pos));
+ op->returnType->type->unmarshal(&is, op->returnType, results.get(), closure, false, &op->metaData);
}
//
// Unmarshal the optional results. This includes an optional return value.
//
- for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
+ for(p = op->optionalOutParams.begin(); p != op->optionalOutParams.end(); ++p)
{
ParamInfoPtr info = *p;
if(is.readOptional(info->tag, info->type->optionalFormat()))
@@ -1670,15 +1845,11 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
}
else
{
- if(PyTuple_SET_ITEM(results.get(), info->pos, Unset) < 0)
- {
- return 0;
- }
- Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(results.get(), info->pos, incRef(Unset)); // PyTuple_SET_ITEM steals a reference.
}
}
- if(_op->returnsClasses)
+ if(op->returnsClasses)
{
is.readPendingValues();
}
@@ -1692,7 +1863,7 @@ IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice:
}
PyObject*
-IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
+IcePy::Invocation::unmarshalException(const OperationPtr& op, const pair<const Ice::Byte*, const Ice::Byte*>& bytes)
{
Ice::InputStream is(_communicator, bytes);
@@ -1717,7 +1888,7 @@ IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ic
PyObject* ex = r.getException();
- if(validateException(ex))
+ if(validateException(op, ex))
{
util.updateSlicedData();
@@ -1727,8 +1898,7 @@ IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ic
StreamUtil::setSlicedDataMember(ex, slicedData);
}
- Py_INCREF(ex);
- return ex;
+ return incRef(ex);
}
else
{
@@ -1758,9 +1928,9 @@ IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ic
}
bool
-IcePy::TypedInvocation::validateException(PyObject* ex) const
+IcePy::Invocation::validateException(const OperationPtr& op, PyObject* ex) const
{
- for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p)
+ for(ExceptionInfoList::const_iterator p = op->exceptions.begin(); p != op->exceptions.end(); ++p)
{
if(PyObject_IsInstance(ex, (*p)->pythonType.get()))
{
@@ -1772,12 +1942,12 @@ IcePy::TypedInvocation::validateException(PyObject* ex) const
}
void
-IcePy::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const
+IcePy::Invocation::checkTwowayOnly(const OperationPtr& op, const Ice::ObjectPrx& proxy) const
{
- if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway())
+ if((op->returnType != 0 || !op->outParams.empty() || !op->exceptions.empty()) && !proxy->ice_isTwoway())
{
Ice::TwowayOnlyException ex(__FILE__, __LINE__);
- ex.operation = _op->name;
+ ex.operation = op->name;
throw ex;
}
}
@@ -1786,7 +1956,7 @@ IcePy::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const
// SyncTypedInvocation
//
IcePy::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) :
- Invocation(prx), TypedInvocation(prx, op)
+ Invocation(prx), _op(op)
{
}
@@ -1804,14 +1974,14 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
//
Ice::OutputStream os(_communicator);
pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, SyncMapping, &os, params))
+ if(!prepareRequest(_op, pyparams, SyncMapping, &os, params))
{
return 0;
}
try
{
- checkTwowayOnly(_prx);
+ checkTwowayOnly(_op, _prx);
//
// Invoke the operation.
@@ -1861,7 +2031,7 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
rb.first = &result[0];
rb.second = &result[0] + result.size();
}
- PyObjectHandle ex = unmarshalException(rb);
+ PyObjectHandle ex = unmarshalException(_op, rb);
//
// Set the Python exception.
@@ -1882,7 +2052,7 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
rb.first = &result[0];
rb.second = &result[0] + result.size();
}
- PyObjectHandle results = unmarshalResults(rb);
+ PyObjectHandle results = unmarshalResults(_op, rb);
if(!results.get())
{
return 0;
@@ -1901,8 +2071,7 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
}
else
{
- Py_INCREF(ret);
- return ret;
+ return incRef(ret);
}
}
}
@@ -1919,8 +2088,7 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
return 0;
}
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
//
@@ -1928,7 +2096,7 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
//
IcePy::AsyncTypedInvocation::AsyncTypedInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy,
const OperationPtr& op) :
- Invocation(prx), TypedInvocation(prx, op), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0)
+ Invocation(prx), _op(op), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0)
{
Py_INCREF(_pyProxy);
}
@@ -1956,8 +2124,7 @@ IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
callable = PyTuple_GET_ITEM(args, 1);
if(PyCallable_Check(callable))
{
- _response = callable;
- Py_INCREF(_response);
+ _response = incRef(callable);
}
else if(callable != Py_None)
{
@@ -1968,8 +2135,7 @@ IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
callable = PyTuple_GET_ITEM(args, 2);
if(PyCallable_Check(callable))
{
- _ex = callable;
- Py_INCREF(_ex);
+ _ex = incRef(callable);
}
else if(callable != Py_None)
{
@@ -1980,8 +2146,7 @@ IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
callable = PyTuple_GET_ITEM(args, 3);
if(PyCallable_Check(callable))
{
- _sent = callable;
- Py_INCREF(_sent);
+ _sent = incRef(callable);
}
else if(callable != Py_None)
{
@@ -2008,7 +2173,7 @@ IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
//
Ice::OutputStream os(_communicator);
pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, AsyncMapping, &os, params))
+ if(!prepareRequest(_op, pyparams, AsyncMapping, &os, params))
{
return 0;
}
@@ -2092,8 +2257,7 @@ IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
}
obj->result = new Ice::AsyncResultPtr(result);
obj->invocation = new InvocationPtr(this);
- obj->proxy = _pyProxy;
- Py_INCREF(obj->proxy);
+ obj->proxy = incRef(_pyProxy);
obj->communicator = getCommunicatorWrapper(_communicator);
return reinterpret_cast<PyObject*>(obj);
}
@@ -2122,7 +2286,7 @@ IcePy::AsyncTypedInvocation::end(const Ice::ObjectPrx& proxy, const OperationPtr
//
// Unmarshal the results.
//
- PyObjectHandle args = unmarshalResults(results);
+ PyObjectHandle args = unmarshalResults(_op, results);
if(args.get())
{
//
@@ -2132,14 +2296,12 @@ IcePy::AsyncTypedInvocation::end(const Ice::ObjectPrx& proxy, const OperationPtr
assert(PyTuple_Check(args.get()));
if(PyTuple_GET_SIZE(args.get()) == 0)
{
- Py_INCREF(Py_None);
- return Py_None;
+ return incRef(Py_None);
}
else if(PyTuple_GET_SIZE(args.get()) == 1)
{
PyObject* res = PyTuple_GET_ITEM(args.get(), 0);
- Py_INCREF(res);
- return res;
+ return incRef(res);
}
else
{
@@ -2149,7 +2311,7 @@ IcePy::AsyncTypedInvocation::end(const Ice::ObjectPrx& proxy, const OperationPtr
}
else
{
- PyObjectHandle ex = unmarshalException(results);
+ PyObjectHandle ex = unmarshalException(_op, results);
setPythonException(ex.get());
}
}
@@ -2193,7 +2355,7 @@ IcePy::AsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, cons
PyObjectHandle args;
try
{
- args = unmarshalResults(results);
+ args = unmarshalResults(_op, results);
if(!args.get())
{
assert(PyErr_Occurred());
@@ -2218,7 +2380,7 @@ IcePy::AsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, cons
else
{
assert(_ex);
- PyObjectHandle ex = unmarshalException(results);
+ PyObjectHandle ex = unmarshalException(_op, results);
callException(_ex, ex.get());
}
}
@@ -2263,114 +2425,344 @@ IcePy::AsyncTypedInvocation::checkAsyncTwowayOnly(const Ice::ObjectPrx& proxy) c
}
//
-// OldAsyncTypedInvocation
+// NewAsyncInvocation
//
-IcePy::OldAsyncTypedInvocation::OldAsyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op)
- : Invocation(prx), TypedInvocation(prx, op), _callback(0)
+IcePy::NewAsyncInvocation::NewAsyncInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy, const string& operation)
+ : Invocation(prx), _pyProxy(pyProxy), _operation(operation), _twoway(prx->ice_isTwoway()), _sent(false),
+ _sentSynchronously(false), _done(false), _future(0), _ok(false), _exception(0)
{
+ Py_INCREF(_pyProxy);
}
-IcePy::OldAsyncTypedInvocation::~OldAsyncTypedInvocation()
+IcePy::NewAsyncInvocation::~NewAsyncInvocation()
{
AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- Py_XDECREF(_callback);
+ Py_DECREF(_pyProxy);
+ Py_XDECREF(_future);
+ Py_XDECREF(_exception);
}
PyObject*
-IcePy::OldAsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */)
+IcePy::NewAsyncInvocation::invoke(PyObject* args, PyObject* kwds)
{
- assert(PyTuple_Check(args));
- assert(PyTuple_GET_SIZE(args) == 3); // Format is (callback, (params...), context|None)
- _callback = PyTuple_GET_ITEM(args, 0);
- Py_INCREF(_callback);
- PyObject* pyparams = PyTuple_GET_ITEM(args, 1);
- assert(PyTuple_Check(pyparams));
- PyObject* pyctx = PyTuple_GET_ITEM(args, 2);
-
//
- // Marshal the input parameters to a byte sequence.
+ // Called from Python code, so the GIL is already acquired.
//
- Ice::OutputStream os(_communicator);
- pair<const Ice::Byte*, const Ice::Byte*> params;
- if(!prepareRequest(pyparams, OldAsyncMapping, &os, params))
+
+ Ice::AsyncResultPtr result;
+
+ try
+ {
+ result = handleInvoke(args, kwds);
+ }
+ catch(const Ice::CommunicatorDestroyedException& ex)
+ {
+ //
+ // CommunicatorDestroyedException can propagate directly.
+ //
+ setPythonException(ex);
+ return 0;
+ }
+ catch(const IceUtil::IllegalArgumentException& ex)
{
+ //
+ // IllegalArgumentException can propagate directly.
+ // (Raised by checkAsyncTwowayOnly)
+ //
+ PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str()));
return 0;
}
+ catch(const Ice::Exception&)
+ {
+ //
+ // No other exceptions should be raised by begin_ice_invoke.
+ //
+ assert(false);
+ }
- bool sentSynchronously = false;
- try
+ if(PyErr_Occurred())
{
- checkTwowayOnly(_prx);
+ return 0;
+ }
- Ice::Callback_Object_ice_invokePtr cb =
- Ice::newCallback_Object_ice_invoke(this, &OldAsyncTypedInvocation::response,
- &OldAsyncTypedInvocation::exception, &OldAsyncTypedInvocation::sent);
+ assert(result);
- Ice::AsyncResultPtr result;
+ PyObjectHandle communicatorObj = getCommunicatorWrapper(_communicator);
+ PyObjectHandle asyncResultObj;
- //
- // Invoke the operation asynchronously.
- //
- if(pyctx != Py_None)
+ //
+ // Pass the AsyncResult object to the future. Note that this creates a circular reference.
+ // Don't do this for batch invocations because there is no opportunity to break the circular
+ // reference.
+ //
+ if(!_prx->ice_isBatchOneway() && !_prx->ice_isBatchDatagram())
+ {
+ asyncResultObj = createAsyncResult(result, _pyProxy, 0, communicatorObj.get());
+ if(!asyncResultObj.get())
{
- Ice::Context ctx;
+ return 0;
+ }
+ }
+
+ //
+ // NOTE: Any time we call into interpreted Python code there's a chance that another thread will be
+ // allowed to run!
+ //
+
+ PyObjectHandle future = createFuture(_operation, asyncResultObj.get()); // Calls into Python code.
+ if(!future.get())
+ {
+ return 0;
+ }
+
+ //
+ // Check if any callbacks have been invoked already.
+ //
+
+ if(_sent)
+ {
+ PyObjectHandle tmp = callMethod(future.get(), "set_sent", _sentSynchronously ? getTrue() : getFalse());
+ if(PyErr_Occurred())
+ {
+ return 0;
+ }
- if(!PyDict_Check(pyctx))
+ if(!_twoway)
+ {
+ //
+ // For a oneway/datagram invocation, we consider it complete when sent.
+ //
+ tmp = callMethod(future.get(), "set_result", Py_None);
+ if(PyErr_Occurred())
{
- PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary"));
return 0;
}
+ }
+ }
- if(!dictionaryToContext(pyctx, ctx))
+ if(_done)
+ {
+ if(_exception)
+ {
+ PyObjectHandle tmp = callMethod(future.get(), "set_exception", _exception);
+ if(PyErr_Occurred())
{
return 0;
}
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb);
}
else
{
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb);
+ //
+ // Delegate to the subclass.
+ //
+ pair<const Ice::Byte*, const Ice::Byte*> p(&_results[0], &_results[0] + _results.size());
+ handleResponse(future.get(), _ok, p);
+ if(PyErr_Occurred())
+ {
+ return 0;
+ }
}
-
- sentSynchronously = result->sentSynchronously();
}
- catch(const Ice::CommunicatorDestroyedException& ex)
+
+ _future = future.release();
+ return incRef(_future);
+}
+
+void
+IcePy::NewAsyncInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
{
//
- // CommunicatorDestroyedException can propagate directly.
+ // The future hasn't been created yet, which means invoke() is still running. Save the results for later.
//
- setPythonException(ex);
- return 0;
+ _ok = ok;
+ vector<Ice::Byte> v(results.first, results.second);
+ _results.swap(v);
+ _done = true;
+ return;
+ }
+
+ PyObjectHandle future = _future; // Steals a reference.
+
+ if(_sent)
+ {
+ _future = 0; // Break cyclic dependency.
}
- catch(const Ice::TwowayOnlyException& ex)
+ else
{
+ assert(!_done);
+
//
- // Raised by checkTwowayOnly.
+ // The sent callback will release our reference.
//
- callException(_callback, _op->name, "ice_exception", ex);
+ Py_INCREF(_future);
}
- catch(const Ice::Exception&)
+
+ _done = true;
+
+ //
+ // Delegate to the subclass.
+ //
+ handleResponse(future.get(), ok, results);
+ if(PyErr_Occurred())
+ {
+ handleException();
+ }
+}
+
+void
+IcePy::NewAsyncInvocation::exception(const Ice::Exception& ex)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
{
//
- // No other exceptions should be raised by begin_ice_invoke.
+ // The future hasn't been created yet, which means invoke() is still running. Save the exception for later.
//
- assert(false);
+ _exception = convertException(ex);
+ _done = true;
+ return;
}
- PyRETURN_BOOL(sentSynchronously);
+ PyObjectHandle future = _future; // Steals a reference.
+ _future = 0; // Break cyclic dependency.
+ _done = true;
+
+ PyObjectHandle exh = convertException(ex);
+ assert(exh.get());
+ PyObjectHandle tmp = callMethod(future.get(), "set_exception", exh.get());
+ if(PyErr_Occurred())
+ {
+ handleException();
+ }
}
void
-IcePy::OldAsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
+IcePy::NewAsyncInvocation::sent(bool sentSynchronously)
{
AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
- assert(_callback);
+ if(!_future)
+ {
+ //
+ // The future hasn't been created yet, which means invoke() is still running.
+ //
+ _sent = true;
+ _sentSynchronously = sentSynchronously;
+ return;
+ }
+
+ PyObjectHandle future = _future;
+
+ if(_done || !_twoway)
+ {
+ _future = 0; // Break cyclic dependency.
+ }
+ else
+ {
+ _sent = true;
+
+ //
+ // The reference to _future will be released in response() or exception().
+ //
+ Py_INCREF(_future);
+ }
+
+ PyObjectHandle tmp = callMethod(future.get(), "set_sent", sentSynchronously ? getTrue() : getFalse());
+ if(PyErr_Occurred())
+ {
+ handleException();
+ }
+
+ if(!_twoway)
+ {
+ //
+ // For a oneway/datagram invocation, we consider it complete when sent.
+ //
+ tmp = callMethod(future.get(), "set_result", Py_None);
+ if(PyErr_Occurred())
+ {
+ handleException();
+ }
+ }
+}
+
+//
+// NewAsyncTypedInvocation
+//
+IcePy::NewAsyncTypedInvocation::NewAsyncTypedInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy,
+ const OperationPtr& op)
+ : NewAsyncInvocation(prx, pyProxy, op->name), _op(op)
+{
+}
+
+Ice::AsyncResultPtr
+IcePy::NewAsyncTypedInvocation::handleInvoke(PyObject* args, PyObject* /* kwds */)
+{
+ //
+ // Called from Python code, so the GIL is already acquired.
+ //
+
+ assert(PyTuple_Check(args));
+ assert(PyTuple_GET_SIZE(args) == 2); // Format is ((params...), context|None)
+ PyObject* pyparams = PyTuple_GET_ITEM(args, 0);
+ assert(PyTuple_Check(pyparams));
+ PyObject* pyctx = PyTuple_GET_ITEM(args, 1);
+
+ //
+ // Marshal the input parameters to a byte sequence.
+ //
+ Ice::OutputStream os(_communicator);
+ pair<const Ice::Byte*, const Ice::Byte*> params;
+ if(!prepareRequest(_op, pyparams, NewAsyncMapping, &os, params))
+ {
+ return 0;
+ }
+
+ checkAsyncTwowayOnly(_prx);
+
+ NewAsyncInvocationPtr self = this;
+ Ice::Callback_Object_ice_invokePtr cb =
+ Ice::newCallback_Object_ice_invoke(self, &NewAsyncInvocation::response, &NewAsyncInvocation::exception,
+ &NewAsyncInvocation::sent);
+
+ //
+ // Invoke the operation asynchronously.
+ //
+ if(pyctx != Py_None)
+ {
+ Ice::Context ctx;
+
+ if(!PyDict_Check(pyctx))
+ {
+ PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary"));
+ return 0;
+ }
+
+ if(!dictionaryToContext(pyctx, ctx))
+ {
+ return 0;
+ }
+
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+ return _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb);
+ }
+ else
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+ return _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb);
+ }
+}
+void
+IcePy::NewAsyncTypedInvocation::handleResponse(PyObject* future, bool ok,
+ const pair<const Ice::Byte*, const Ice::Byte*>& results)
+{
try
{
if(ok)
@@ -2379,69 +2771,70 @@ IcePy::OldAsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, c
// Unmarshal the results.
//
PyObjectHandle args;
+
try
{
- args = unmarshalResults(results);
+ args = unmarshalResults(_op, results);
if(!args.get())
{
assert(PyErr_Occurred());
- PyErr_Print();
return;
}
}
catch(const Ice::Exception& ex)
{
- callException(_callback, _op->name, "ice_exception", ex);
+ PyObjectHandle exh = convertException(ex);
+ assert(exh.get());
+ PyObjectHandle tmp = callMethod(future, "set_exception", exh.get());
+ PyErr_Clear();
return;
}
- const string methodName = "ice_response";
- if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str())))
+ //
+ // The future's result is always one value:
+ //
+ // - If the operation has no out parameters, the result is None
+ // - If the operation returns one value, the result is the value
+ // - If the operation returns multiple values, the result is a tuple containing the values
+ //
+ PyObjectHandle r;
+ if(PyTuple_GET_SIZE(args.get()) == 0)
{
- ostringstream ostr;
- ostr << "AMI callback object for operation `" << _op->name << "' does not define " << methodName
- << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
+ r = incRef(Py_None);
+ }
+ else if(PyTuple_GET_SIZE(args.get()) == 1)
+ {
+ r = incRef(PyTuple_GET_ITEM(args.get(), 0)); // PyTuple_GET_ITEM steals a reference.
}
else
{
- PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str()));
- assert(method.get());
- PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
+ r = args;
}
+
+ PyObjectHandle tmp = callMethod(future, "set_result", r.get());
+ PyErr_Clear();
}
else
{
- PyObjectHandle ex = unmarshalException(results);
- callException(_callback, _op->name, "ice_exception", ex.get());
+ PyObjectHandle ex = unmarshalException(_op, results);
+ PyObjectHandle tmp = callMethod(future, "set_exception", ex.get());
+ PyErr_Clear();
}
}
catch(const AbortMarshaling&)
{
assert(PyErr_Occurred());
- PyErr_Print();
}
}
void
-IcePy::OldAsyncTypedInvocation::exception(const Ice::Exception& ex)
+IcePy::NewAsyncTypedInvocation::checkAsyncTwowayOnly(const Ice::ObjectPrx& proxy) const
{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callException(_callback, _op->name, "ice_exception", ex);
-}
-
-void
-IcePy::OldAsyncTypedInvocation::sent(bool)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- callSent(_callback, "ice_sent", false, false);
+ if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway())
+ {
+ throw IceUtil::IllegalArgumentException(__FILE__, __LINE__,
+ "`" + _op->name + "' can only be called with a twoway proxy");
+ }
}
//
@@ -2574,11 +2967,7 @@ IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
}
#endif
- if(PyTuple_SET_ITEM(result.get(), 1, op.get()) < 0)
- {
- throwPythonException();
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(result.get(), 1, op.release()); // PyTuple_SET_ITEM steals a reference.
return result.release();
}
@@ -2652,8 +3041,7 @@ IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds)
if(PyCallable_Check(response))
{
- _response = response;
- Py_INCREF(_response);
+ _response = incRef(response);
}
else if(response != Py_None)
{
@@ -2663,8 +3051,7 @@ IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds)
if(PyCallable_Check(ex))
{
- _ex = ex;
- Py_INCREF(_ex);
+ _ex = incRef(ex);
}
else if(ex != Py_None)
{
@@ -2674,8 +3061,7 @@ IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds)
if(PyCallable_Check(sent))
{
- _sent = sent;
- Py_INCREF(_sent);
+ _sent = incRef(sent);
}
else if(sent != Py_None)
{
@@ -2787,8 +3173,7 @@ IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds)
}
obj->result = new Ice::AsyncResultPtr(result);
obj->invocation = new InvocationPtr(this);
- obj->proxy = _pyProxy;
- Py_INCREF(obj->proxy);
+ obj->proxy = incRef(_pyProxy);
obj->communicator = getCommunicatorWrapper(_prx->ice_getCommunicator());
return reinterpret_cast<PyObject*>(obj);
}
@@ -2855,11 +3240,7 @@ IcePy::AsyncBlobjectInvocation::end(const Ice::ObjectPrx& proxy, const Ice::Asyn
memcpy(buf, results.first, sz);
#endif
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- return 0;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(args.get(), 1, op.release()); // PyTuple_SET_ITEM steals a reference.
return args.release();
}
@@ -2946,13 +3327,7 @@ IcePy::AsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, c
memcpy(buf, results.first, sz);
#endif
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(args.get(), 1, op.release()); // PyTuple_SET_ITEM steals a reference.
PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0);
if(PyErr_Occurred())
@@ -2981,22 +3356,15 @@ IcePy::AsyncBlobjectInvocation::sent(bool sentSynchronously)
}
//
-// OldAsyncBlobjectInvocation
+// NewAsyncBlobjectInvocation
//
-IcePy::OldAsyncBlobjectInvocation::OldAsyncBlobjectInvocation(const Ice::ObjectPrx& prx) :
- Invocation(prx), _callback(0)
-{
-}
-
-IcePy::OldAsyncBlobjectInvocation::~OldAsyncBlobjectInvocation()
+IcePy::NewAsyncBlobjectInvocation::NewAsyncBlobjectInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy) :
+ NewAsyncInvocation(prx, pyProxy, "ice_invoke")
{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- Py_XDECREF(_callback);
}
-PyObject*
-IcePy::OldAsyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
+Ice::AsyncResultPtr
+IcePy::NewAsyncBlobjectInvocation::handleInvoke(PyObject* args, PyObject* /* kwds */)
{
char* operation;
PyObject* mode;
@@ -3004,20 +3372,19 @@ IcePy::OldAsyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
PyObject* operationModeType = lookupType("Ice.OperationMode");
PyObject* ctx = 0;
#if PY_VERSION_HEX >= 0x03000000
- if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode,
+ if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode,
&PyBytes_Type, &inParams, &ctx))
{
return 0;
}
#else
- if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode,
+ if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode,
&PyBuffer_Type, &inParams, &ctx))
{
return 0;
}
#endif
- Py_INCREF(_callback);
_op = operation;
PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value"));
@@ -3049,169 +3416,175 @@ IcePy::OldAsyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */)
}
#endif
- bool sentSynchronously = false;
- try
- {
- Ice::AsyncResultPtr result;
- Ice::Callback_Object_ice_invokePtr cb =
- Ice::newCallback_Object_ice_invoke(this, &OldAsyncBlobjectInvocation::response,
- &OldAsyncBlobjectInvocation::exception,
- &OldAsyncBlobjectInvocation::sent);
+ NewAsyncInvocationPtr self = this;
+ Ice::Callback_Object_ice_invokePtr cb =
+ Ice::newCallback_Object_ice_invoke(self, &NewAsyncInvocation::response, &NewAsyncInvocation::exception,
+ &NewAsyncInvocation::sent);
- if(ctx == 0 || ctx == Py_None)
- {
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(operation, sendMode, in, cb);
- }
- else
- {
- Ice::Context context;
- if(!dictionaryToContext(ctx, context))
- {
- return 0;
- }
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
- result = _prx->begin_ice_invoke(operation, sendMode, in, context, cb);
- }
-
- sentSynchronously = result->sentSynchronously();
- }
- catch(const Ice::CommunicatorDestroyedException& ex)
+ if(ctx == 0 || ctx == Py_None)
{
//
- // CommunicatorDestroyedException is the only exception that can propagate directly.
+ // Don't release the GIL here. We want other threads to block until we've had a chance
+ // to create the future.
//
- setPythonException(ex);
- return 0;
+ //AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+ return _prx->begin_ice_invoke(operation, sendMode, in, cb);
}
- catch(const Ice::Exception&)
+ else
{
+ Ice::Context context;
+ if(!dictionaryToContext(ctx, context))
+ {
+ return 0;
+ }
+
//
- // No other exceptions should be raised by begin_ice_invoke.
+ // Don't release the GIL here. We want other threads to block until we've had a chance
+ // to create the future.
//
- assert(false);
+ //AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+ return _prx->begin_ice_invoke(operation, sendMode, in, context, cb);
}
-
- PyRETURN_BOOL(sentSynchronously);
}
void
-IcePy::OldAsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results)
+IcePy::NewAsyncBlobjectInvocation::handleResponse(PyObject* future, bool ok,
+ const pair<const Ice::Byte*, const Ice::Byte*>& results)
{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
-
- try
+ //
+ // Prepare the args as a tuple of the bool and out param buffer.
+ //
+ PyObjectHandle args = PyTuple_New(2);
+ if(!args.get())
{
- //
- // Prepare the args as a tuple of the bool and out param buffer.
- //
- PyObjectHandle args = PyTuple_New(2);
- if(!args.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ return;
+ }
- if(PyTuple_SET_ITEM(args.get(), 0, ok ? incTrue() : incFalse()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
+ if(PyTuple_SET_ITEM(args.get(), 0, ok ? incTrue() : incFalse()) < 0)
+ {
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ return;
+ }
#if PY_VERSION_HEX >= 0x03000000
- Py_ssize_t sz = results.second - results.first;
- PyObjectHandle op;
- if(sz == 0)
- {
- op = PyBytes_FromString("");
- }
- else
- {
- op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz);
- }
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
+ Py_ssize_t sz = results.second - results.first;
+ PyObjectHandle op;
+ if(sz == 0)
+ {
+ op = PyBytes_FromString("");
+ }
+ else
+ {
+ op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz);
+ }
+ if(!op.get())
+ {
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ return;
+ }
#else
- //
- // Create the output buffer and copy in the outParams.
- //
- PyObjectHandle op = PyBuffer_New(results.second - results.first);
- if(!op.get())
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
+ //
+ // Create the output buffer and copy in the outParams.
+ //
+ PyObjectHandle op = PyBuffer_New(results.second - results.first);
+ if(!op.get())
+ {
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ return;
+ }
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- assert(sz == results.second - results.first);
- memcpy(buf, results.first, sz);
+ void* buf;
+ Py_ssize_t sz;
+ if(PyObject_AsWriteBuffer(op.get(), &buf, &sz))
+ {
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ return;
+ }
+ assert(sz == results.second - results.first);
+ memcpy(buf, results.first, sz);
#endif
- if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0)
- {
- assert(PyErr_Occurred());
- PyErr_Print();
- return;
- }
- op.release(); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(args.get(), 1, op.release()); // PyTuple_SET_ITEM steals a reference.
- const string methodName = "ice_response";
- if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str())))
- {
- ostringstream ostr;
- ostr << "AMI callback object for operation `ice_invoke_async' does not define " << methodName << "()";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- }
- else
- {
- PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str()));
- assert(method.get());
- PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0);
- if(PyErr_Occurred())
- {
- handleException(); // Callback raised an exception.
- }
- }
+ PyObjectHandle tmp = callMethod(future, "set_result", args.get());
+ PyErr_Clear();
+}
+
+//
+// Upcall
+//
+void
+Upcall::dispatchImpl(PyObject* servant, const string& dispatchName, PyObject* args, const Ice::Current& current)
+{
+ Ice::CommunicatorPtr communicator = current.adapter->getCommunicator();
+
+ //
+ // Find the servant method for the operation. Use dispatchName here, not current.operation.
+ //
+ PyObjectHandle servantMethod = PyObject_GetAttrString(servant, const_cast<char*>(dispatchName.c_str()));
+ if(!servantMethod.get())
+ {
+ ostringstream ostr;
+ ostr << "servant for identity " << communicator->identityToString(current.id)
+ << " does not define operation `" << dispatchName << "'";
+ string str = ostr.str();
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ Ice::UnknownException ex(__FILE__, __LINE__);
+ ex.unknown = str;
+ throw ex;
}
- catch(const Ice::Exception& ex)
+
+ //
+ // Get the _dispatch method. The _dispatch method will invoke the servant method and pass it the arguments.
+ //
+ PyObjectHandle dispatchMethod = PyObject_GetAttrString(servant, STRCAST("_dispatch"));
+ if(!dispatchMethod.get())
{
ostringstream ostr;
- ostr << "Exception raised by AMI callback for operation `ice_invoke_async':" << ex;
+ ostr << "_dispatch method not found for identity " << communicator->identityToString(current.id)
+ << " and operation `" << dispatchName << "'";
string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ Ice::UnknownException ex(__FILE__, __LINE__);
+ ex.unknown = str;
+ throw ex;
}
-}
-void
-IcePy::OldAsyncBlobjectInvocation::exception(const Ice::Exception& ex)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+ PyObjectHandle dispatchArgs = PyTuple_New(3);
+ if(!dispatchArgs.get())
+ {
+ throwPythonException();
+ }
- callException(_callback, "ice_invoke", "ice_exception", ex);
-}
+ DispatchCallbackObject* callback = dispatchCallbackNew(&DispatchCallbackType, 0, 0);
+ if(!callback)
+ {
+ throwPythonException();
+ }
+ callback->upcall = new UpcallPtr(this);
+ PyTuple_SET_ITEM(dispatchArgs.get(), 0, reinterpret_cast<PyObject*>(callback)); // Steals a reference.
+ PyTuple_SET_ITEM(dispatchArgs.get(), 1, servantMethod.release()); // Steals a reference.
+ PyTuple_SET_ITEM(dispatchArgs.get(), 2, incRef(args)); // Steals a reference.
-void
-IcePy::OldAsyncBlobjectInvocation::sent(bool)
-{
- AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+ //
+ // Ignore the return value of _dispatch -- it will use the dispatch callback.
+ //
+ PyObjectHandle ignore = PyObject_Call(dispatchMethod.get(), dispatchArgs.get(), 0);
- callSent(_callback, "ice_sent", false, false);
+ //
+ // Check for exceptions.
+ //
+ if(PyErr_Occurred())
+ {
+ PyException ex; // Retrieve it before another Python API call clears it.
+ exception(ex);
+ }
}
//
@@ -3219,7 +3592,7 @@ IcePy::OldAsyncBlobjectInvocation::sent(bool)
//
IcePy::TypedUpcall::TypedUpcall(const OperationPtr& op, const Ice::AMD_Object_ice_invokePtr& callback,
const Ice::CommunicatorPtr& communicator) :
- _op(op), _callback(callback), _communicator(communicator), _finished(false)
+ _op(op), _callback(callback), _communicator(communicator)
{
}
@@ -3227,19 +3600,14 @@ void
IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, const Ice::Byte*>& inBytes,
const Ice::Current& current)
{
+ _encoding = current.encoding;
+
//
// Unmarshal the in parameters. We have to leave room in the arguments for a trailing
// Ice::Current object.
//
Py_ssize_t count = static_cast<Py_ssize_t>(_op->inParams.size()) + 1;
- Py_ssize_t offset = 0;
- if(_op->amd)
- {
- ++count; // Leave room for a leading AMD callback argument.
- offset = 1;
- }
-
PyObjectHandle args = PyTuple_New(count);
if(!args.get())
{
@@ -3272,7 +3640,7 @@ IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, con
ParamInfoPtr info = *p;
if(!info->optional)
{
- void* closure = reinterpret_cast<void*>(info->pos + offset);
+ void* closure = reinterpret_cast<void*>(info->pos);
info->type->unmarshal(&is, info, args.get(), closure, false, &info->metaData);
}
}
@@ -3285,16 +3653,12 @@ IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, con
ParamInfoPtr info = *p;
if(is.readOptional(info->tag, info->type->optionalFormat()))
{
- void* closure = reinterpret_cast<void*>(info->pos + offset);
+ void* closure = reinterpret_cast<void*>(info->pos);
info->type->unmarshal(&is, info, args.get(), closure, true, &info->metaData);
}
else
{
- if(PyTuple_SET_ITEM(args.get(), info->pos + offset, Unset) < 0)
- {
- throwPythonException();
- }
- Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference.
+ PyTuple_SET_ITEM(args.get(), info->pos, incRef(Unset)); // PyTuple_SET_ITEM steals a reference.
}
}
@@ -3317,209 +3681,149 @@ IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, con
// Create an object to represent Ice::Current. We need to append this to the argument tuple.
//
PyObjectHandle curr = createCurrent(current);
- if(PyTuple_SET_ITEM(args.get(), PyTuple_GET_SIZE(args.get()) - 1, curr.get()) < 0)
- {
- throwPythonException();
- }
- curr.release(); // PyTuple_SET_ITEM steals a reference.
-
- if(_op->amd)
- {
- //
- // Create the callback object and pass it as the first argument.
- //
- AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0);
- if(!obj)
- {
- throwPythonException();
- }
- obj->upcall = new UpcallPtr(this);
- obj->encoding = current.encoding;
- if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference.
- {
- Py_DECREF(obj);
- throwPythonException();
- }
- }
-
- //
- // Dispatch the operation. Use _dispatchName here, not current.operation.
- //
- PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(_op->dispatchName.c_str()));
- if(!method.get())
- {
- ostringstream ostr;
- ostr << "servant for identity " << _communicator->identityToString(current.id)
- << " does not define operation `" << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- Ice::UnknownException ex(__FILE__, __LINE__);
- ex.unknown = str;
- throw ex;
- }
-
- PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0);
-
- //
- // Check for exceptions.
- //
- if(PyErr_Occurred())
- {
- PyException ex; // Retrieve it before another Python API call clears it.
- exception(ex, current.encoding);
- return;
- }
+ PyTuple_SET_ITEM(args.get(), PyTuple_GET_SIZE(args.get()) - 1,
+ curr.release()); // PyTuple_SET_ITEM steals a reference.
- if(!_op->amd)
- {
- response(result.get(), current.encoding);
- }
+ dispatchImpl(servant, _op->dispatchName, args.get(), current);
}
void
-IcePy::TypedUpcall::response(PyObject* args, const Ice::EncodingVersion& encoding)
+IcePy::TypedUpcall::response(PyObject* result)
{
- if(_finished)
+ try
{
//
- // This method could be called more than once if the application calls
- // ice_response multiple times. We ignore subsequent calls.
+ // Marshal the results. If there is more than one value to be returned, then they must be
+ // returned in a tuple of the form (result, outParam1, ...).
//
- return;
- }
- _finished = true;
+ Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size());
+ if(_op->returnType)
+ {
+ numResults++;
+ }
+
+ if(numResults > 1 && (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != numResults))
+ {
+ ostringstream ostr;
+ ostr << "operation `" << fixIdent(_op->name) << "' should return a tuple of length " << numResults;
+ string str = ostr.str();
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ throw Ice::MarshalException(__FILE__, __LINE__);
+ }
- try
- {
//
- // Marshal the results. If there is more than one value to be returned, then they must be
- // returned in a tuple of the form (result, outParam1, ...).
+ // Normalize the result value. When there are multiple result values, result is already a tuple.
+ // Otherwise, we create a tuple to make the code a little simpler.
//
- Ice::OutputStream os(_communicator);
- try
+ PyObjectHandle t;
+ if(numResults > 1)
+ {
+ t = incRef(result);
+ }
+ else
{
- Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size());
- if(_op->returnType)
+ t = PyTuple_New(1);
+ if(!t.get())
{
- numResults++;
+ throw AbortMarshaling();
}
+ PyTuple_SET_ITEM(t.get(), 0, incRef(result));
+ }
+
+ ObjectMap objectMap;
+ ParamInfoList::iterator p;
- if(numResults > 1 && (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != numResults))
+ //
+ // Validate the results.
+ //
+ for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
+ if((!info->optional || arg != Unset) && !info->type->validate(arg))
{
+ // TODO: Provide the parameter name instead?
ostringstream ostr;
- ostr << "operation `" << fixIdent(_op->name) << "' should return a tuple of length " << numResults;
+ ostr << "invalid value for out argument " << (info->pos + 1) << " in operation `"
+ << _op->dispatchName << "'";
string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
throw Ice::MarshalException(__FILE__, __LINE__);
}
-
- //
- // Normalize the args value. For an AMD operation, or when there are multiple
- // result values, args is already a tuple. Otherwise, we create a tuple to
- // make the code a little simpler.
- //
- PyObjectHandle t;
- if(_op->amd || numResults > 1)
- {
- t = args;
- }
- else
+ }
+ if(_op->returnType)
+ {
+ PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
+ if((!_op->returnType->optional || res != Unset) && !_op->returnType->type->validate(res))
{
- t = PyTuple_New(1);
- if(!t.get())
- {
- throw AbortMarshaling();
- }
- PyTuple_SET_ITEM(t.get(), 0, args);
+ ostringstream ostr;
+ ostr << "invalid return value for operation `" << _op->dispatchName << "'";
+ string str = ostr.str();
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ throw Ice::MarshalException(__FILE__, __LINE__);
}
- Py_INCREF(args);
-
- os.startEncapsulation(encoding, _op->format);
+ }
- ObjectMap objectMap;
- ParamInfoList::iterator p;
+ Ice::OutputStream os(_communicator);
+ os.startEncapsulation(_encoding, _op->format);
- //
- // Validate the results.
- //
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ //
+ // Marshal the required out parameters.
+ //
+ for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ if(!info->optional)
{
- ParamInfoPtr info = *p;
PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- if((!info->optional || arg != Unset) && !info->type->validate(arg))
- {
- // TODO: Provide the parameter name instead?
- ostringstream ostr;
- ostr << "invalid value for out argument " << (info->pos + 1) << " in operation `"
- << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
- }
- if(_op->returnType)
- {
- PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
- if((!_op->returnType->optional || res != Unset) && !_op->returnType->type->validate(res))
- {
- ostringstream ostr;
- ostr << "invalid return value for operation `" << _op->dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
- }
-
- //
- // Marshal the required out parameters.
- //
- for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p)
- {
- ParamInfoPtr info = *p;
- if(!info->optional)
- {
- PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- info->type->marshal(arg, &os, &objectMap, false, &info->metaData);
- }
+ info->type->marshal(arg, &os, &objectMap, false, &info->metaData);
}
+ }
- //
- // Marshal the required return value, if any.
- //
- if(_op->returnType && !_op->returnType->optional)
- {
- PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
- _op->returnType->type->marshal(res, &os, &objectMap, false, &_op->metaData);
- }
+ //
+ // Marshal the required return value, if any.
+ //
+ if(_op->returnType && !_op->returnType->optional)
+ {
+ PyObject* res = PyTuple_GET_ITEM(t.get(), 0);
+ _op->returnType->type->marshal(res, &os, &objectMap, false, &_op->metaData);
+ }
- //
- // Marshal the optional results.
- //
- for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
+ //
+ // Marshal the optional results.
+ //
+ for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p)
+ {
+ ParamInfoPtr info = *p;
+ PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
+ if(arg != Unset && os.writeOptional(info->tag, info->type->optionalFormat()))
{
- ParamInfoPtr info = *p;
- PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos);
- if(arg != Unset && os.writeOptional(info->tag, info->type->optionalFormat()))
- {
- info->type->marshal(arg, &os, &objectMap, true, &info->metaData);
- }
+ info->type->marshal(arg, &os, &objectMap, true, &info->metaData);
}
+ }
- if(_op->returnsClasses)
- {
- os.writePendingValues();
- }
+ if(_op->returnsClasses)
+ {
+ os.writePendingValues();
+ }
- os.endEncapsulation();
+ os.endEncapsulation();
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_response(true, os.finished());
- }
- catch(const AbortMarshaling&)
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
+ _callback->ice_response(true, os.finished());
+ }
+ catch(const AbortMarshaling&)
+ {
+ try
{
throwPythonException();
}
+ catch(const Ice::Exception& ex)
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
+ _callback->ice_exception(ex);
+ }
}
catch(const Ice::Exception& ex)
{
@@ -3529,19 +3833,8 @@ IcePy::TypedUpcall::response(PyObject* args, const Ice::EncodingVersion& encodin
}
void
-IcePy::TypedUpcall::exception(PyException& ex, const Ice::EncodingVersion& encoding)
+IcePy::TypedUpcall::exception(PyException& ex)
{
- if(_finished)
- {
- //
- // An asynchronous response or exception has already been sent. We just
- // raise an exception and let the C++ run time handle it.
- //
- ex.raise();
- }
-
- _finished = true;
-
try
{
try
@@ -3567,7 +3860,7 @@ IcePy::TypedUpcall::exception(PyException& ex, const Ice::EncodingVersion& encod
assert(info);
Ice::OutputStream os(_communicator);
- os.startEncapsulation(encoding, _op->format);
+ os.startEncapsulation(_encoding, _op->format);
ExceptionWriter writer(ex.ex, info);
os.writeException(writer);
@@ -3589,16 +3882,22 @@ IcePy::TypedUpcall::exception(PyException& ex, const Ice::EncodingVersion& encod
}
catch(const Ice::Exception& ex)
{
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_exception(ex);
+ exception(ex);
}
}
+void
+IcePy::TypedUpcall::exception(const Ice::Exception& ex)
+{
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
+ _callback->ice_exception(ex);
+}
+
//
// BlobjectUpcall
//
-IcePy::BlobjectUpcall::BlobjectUpcall(bool amd, const Ice::AMD_Object_ice_invokePtr& callback) :
- _amd(amd), _callback(callback), _finished(false)
+IcePy::BlobjectUpcall::BlobjectUpcall(const Ice::AMD_Object_ice_invokePtr& callback) :
+ _callback(callback)
{
}
@@ -3611,11 +3910,6 @@ IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*,
Py_ssize_t count = 2; // First is the inParams, second is the Ice::Current object.
Py_ssize_t start = 0;
- if(_amd)
- {
- ++count; // Leave room for a leading AMD callback argument.
- start = 1;
- }
PyObjectHandle args = PyTuple_New(count);
if(!args.get())
@@ -3636,196 +3930,113 @@ IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*,
}
#else
//
- // If using AMD we need to copy the bytes since the bytes may be
- // accessed after this method is over, otherwise
- // PyBuffer_FromMemory can be used which doesn't do a copy.
+ // Make a copy of the bytes since the bytes may be accessed after this method is over.
//
- if(!_amd)
+ ip = PyBuffer_New(inBytes.second - inBytes.first);
+ if(!ip.get())
{
- ip = PyBuffer_FromMemory((void*)inBytes.first, inBytes.second - inBytes.first);
- if(!ip.get())
- {
- throwPythonException();
- }
+ throwPythonException();
}
- else
+ void* buf;
+ Py_ssize_t sz;
+ if(PyObject_AsWriteBuffer(ip.get(), &buf, &sz))
{
- ip = PyBuffer_New(inBytes.second - inBytes.first);
- if(!ip.get())
- {
- throwPythonException();
- }
- void* buf;
- Py_ssize_t sz;
- if(PyObject_AsWriteBuffer(ip.get(), &buf, &sz))
- {
- throwPythonException();
- }
- assert(sz == inBytes.second - inBytes.first);
- memcpy(buf, inBytes.first, sz);
+ throwPythonException();
}
+ assert(sz == inBytes.second - inBytes.first);
+ memcpy(buf, inBytes.first, sz);
#endif
- if(PyTuple_SET_ITEM(args.get(), start, ip.get()) < 0)
- {
- throwPythonException();
- }
+ PyTuple_SET_ITEM(args.get(), start, ip.release()); // PyTuple_SET_ITEM steals a reference.
++start;
- ip.release(); // PyTuple_SET_ITEM steals a reference.
//
// Create an object to represent Ice::Current. We need to append
// this to the argument tuple.
//
PyObjectHandle curr = createCurrent(current);
- if(PyTuple_SET_ITEM(args.get(), start, curr.get()) < 0)
- {
- throwPythonException();
- }
- curr.release(); // PyTuple_SET_ITEM steals a reference.
-
- string dispatchName = "ice_invoke";
- if(_amd)
- {
- dispatchName += "_async";
- //
- // Create the callback object and pass it as the first argument.
- //
- AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0);
- if(!obj)
- {
- throwPythonException();
- }
- obj->upcall = new UpcallPtr(this);
- obj->encoding = current.encoding;
- if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference.
- {
- Py_DECREF(obj);
- throwPythonException();
- }
- }
-
- //
- // Dispatch the operation.
- //
- PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(dispatchName.c_str()));
- if(!method.get())
- {
- ostringstream ostr;
- ostr << "servant for identity " << communicator->identityToString(current.id)
- << " does not define operation `" << dispatchName << "'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- Ice::UnknownException ex(__FILE__, __LINE__);
- ex.unknown = str;
- throw ex;
- }
-
- PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0);
-
- //
- // Check for exceptions.
- //
- if(PyErr_Occurred())
- {
- PyException ex; // Retrieve it before another Python API call clears it.
- exception(ex, current.encoding);
- return;
- }
+ PyTuple_SET_ITEM(args.get(), start, curr.release()); // PyTuple_SET_ITEM steals a reference.
- if(!_amd)
- {
- response(result.get(), current.encoding);
- }
+ dispatchImpl(servant, "ice_invoke", args.get(), current);
}
void
-IcePy::BlobjectUpcall::response(PyObject* args, const Ice::EncodingVersion&)
+IcePy::BlobjectUpcall::response(PyObject* result)
{
- if(_finished)
+ try
{
//
- // This method could be called more than once if the application calls
- // ice_response multiple times. We ignore subsequent calls.
+ // The result is a tuple of (bool, results).
//
- return;
- }
+ if(!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 2)
+ {
+ string str = "operation `ice_invoke' should return a tuple of length 2";
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ throw Ice::MarshalException(__FILE__, __LINE__);
+ }
- _finished = true;
+ PyObject* arg = PyTuple_GET_ITEM(result, 0);
+ bool isTrue = PyObject_IsTrue(arg) == 1;
- //
- // The return value is a tuple of (bool, results).
- //
- if(!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != 2)
- {
- ostringstream ostr;
- string name = "ice_invoke";
- if(_amd)
+ arg = PyTuple_GET_ITEM(result, 1);
+
+#if PY_VERSION_HEX >= 0x03000000
+ if(!PyBytes_Check(arg))
{
- name += "_async";
+ ostringstream ostr;
+ ostr << "invalid return value for operation `ice_invoke'";
+ string str = ostr.str();
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ throw Ice::MarshalException(__FILE__, __LINE__);
}
- ostr << "operation `" << name << "' should return a tuple of length 2";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
- }
- PyObject* arg = PyTuple_GET_ITEM(args, 0);
- bool isTrue = PyObject_IsTrue(arg) == 1;
+ Py_ssize_t sz = PyBytes_GET_SIZE(arg);
+ pair<const ::Ice::Byte*, const ::Ice::Byte*> r(static_cast<const Ice::Byte*>(0),
+ static_cast<const Ice::Byte*>(0));
+ if(sz > 0)
+ {
+ r.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(arg));
+ r.second = r.first + sz;
+ }
+#else
+ if(!PyBuffer_Check(arg))
+ {
+ ostringstream ostr;
+ ostr << "invalid return value for operation `ice_invoke'";
+ string str = ostr.str();
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
+ throw Ice::MarshalException(__FILE__, __LINE__);
+ }
- arg = PyTuple_GET_ITEM(args, 1);
+ char* charBuf = 0;
+ Py_ssize_t sz = arg->ob_type->tp_as_buffer->bf_getcharbuffer(arg, 0, &charBuf);
+ const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
+ const pair<const ::Ice::Byte*, const ::Ice::Byte*> r(mem, mem + sz);
+#endif
-#if PY_VERSION_HEX >= 0x03000000
- if(!PyBytes_Check(arg))
- {
- ostringstream ostr;
- ostr << "invalid return value for operation `ice_invoke'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
+ _callback->ice_response(isTrue, r);
}
-
- Py_ssize_t sz = PyBytes_GET_SIZE(arg);
- pair<const ::Ice::Byte*, const ::Ice::Byte*> r(static_cast<const Ice::Byte*>(0),static_cast<const Ice::Byte*>(0));
- if(sz > 0)
+ catch(const AbortMarshaling&)
{
- r.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(arg));
- r.second = r.first + sz;
+ try
+ {
+ throwPythonException();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ exception(ex);
+ }
}
-#else
- if(!PyBuffer_Check(arg))
+ catch(const Ice::Exception& ex)
{
- ostringstream ostr;
- ostr << "invalid return value for operation `ice_invoke'";
- string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
- throw Ice::MarshalException(__FILE__, __LINE__);
+ exception(ex);
}
-
- char* charBuf = 0;
- Py_ssize_t sz = arg->ob_type->tp_as_buffer->bf_getcharbuffer(arg, 0, &charBuf);
- const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf);
- const pair<const ::Ice::Byte*, const ::Ice::Byte*> r(mem, mem + sz);
-#endif
-
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_response(isTrue, r);
}
void
-IcePy::BlobjectUpcall::exception(PyException& ex, const Ice::EncodingVersion&)
+IcePy::BlobjectUpcall::exception(PyException& ex)
{
- if(_finished)
- {
- //
- // An asynchronous response or exception has already been sent. We just
- // raise an exception and let the C++ run time handle it.
- //
- ex.raise();
- }
-
- _finished = true;
-
try
{
//
@@ -3840,11 +4051,17 @@ IcePy::BlobjectUpcall::exception(PyException& ex, const Ice::EncodingVersion&)
}
catch(const Ice::Exception& ex)
{
- AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
- _callback->ice_exception(ex);
+ exception(ex);
}
}
+void
+IcePy::BlobjectUpcall::exception(const Ice::Exception& ex)
+{
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls.
+ _callback->ice_exception(ex);
+}
+
PyObject*
IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
{
@@ -3863,6 +4080,23 @@ IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
}
PyObject*
+IcePy::invokeBuiltinAsync(PyObject* proxy, const string& builtin, PyObject* args)
+{
+ string name = "_op_" + builtin;
+ PyObject* objectType = lookupType("Ice.Object");
+ assert(objectType);
+ PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str()));
+ assert(obj.get());
+
+ OperationPtr op = getOperation(obj.get());
+ assert(op);
+
+ Ice::ObjectPrx p = getProxy(proxy);
+ InvocationPtr i = new NewAsyncTypedInvocation(p, proxy, op);
+ return i->invoke(args);
+}
+
+PyObject*
IcePy::beginBuiltin(PyObject* proxy, const string& builtin, PyObject* args)
{
string name = "_op_" + builtin;
@@ -3921,7 +4155,7 @@ PyObject*
IcePy::iceInvokeAsync(PyObject* proxy, PyObject* args)
{
Ice::ObjectPrx p = getProxy(proxy);
- InvocationPtr i = new OldAsyncBlobjectInvocation(p);
+ InvocationPtr i = new NewAsyncBlobjectInvocation(p, proxy);
return i->invoke(args);
}
@@ -3963,12 +4197,9 @@ IcePy::createAsyncResult(const Ice::AsyncResultPtr& r, PyObject* proxy, PyObject
return 0;
}
obj->result = new Ice::AsyncResultPtr(r);
- obj->proxy = proxy;
- Py_XINCREF(obj->proxy);
- obj->connection = connection;
- Py_XINCREF(obj->connection);
- obj->communicator = communicator;
- Py_XINCREF(obj->communicator);
+ obj->proxy = incRef(proxy);
+ obj->connection = incRef(connection);
+ obj->communicator = incRef(communicator);
return reinterpret_cast<PyObject*>(obj);
}
@@ -3980,6 +4211,9 @@ IcePy::getAsyncResult(PyObject* p)
return *obj->result;
}
+//
+// FlushCallback
+//
IcePy::FlushCallback::FlushCallback(PyObject* ex, PyObject* sent, const string& op) :
_ex(ex), _sent(sent), _op(op)
{
@@ -4014,6 +4248,100 @@ IcePy::FlushCallback::sent(bool sentSynchronously)
}
}
+IcePy::FlushAsyncCallback::FlushAsyncCallback(const string& op) :
+ _op(op), _future(0), _sent(false), _sentSynchronously(false), _exception(0)
+{
+}
+
+IcePy::FlushAsyncCallback::~FlushAsyncCallback()
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ Py_XDECREF(_future);
+ Py_XDECREF(_exception);
+}
+
+void
+IcePy::FlushAsyncCallback::setFuture(PyObject* future)
+{
+ //
+ // Called with the GIL locked.
+ //
+
+ //
+ // Check if any callbacks have been invoked already.
+ //
+ if(_exception)
+ {
+ PyObjectHandle tmp = callMethod(future, "set_exception", _exception);
+ PyErr_Clear();
+ }
+ else if(_sent)
+ {
+ PyObjectHandle tmp = callMethod(future, "set_sent", _sentSynchronously ? getTrue() : getFalse());
+ PyErr_Clear();
+ //
+ // We consider the invocation complete when sent.
+ //
+ tmp = callMethod(future, "set_result", Py_None);
+ PyErr_Clear();
+ }
+ else
+ {
+ _future = incRef(future);
+ }
+}
+
+void
+IcePy::FlushAsyncCallback::exception(const Ice::Exception& ex)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
+ {
+ //
+ // The future hasn't been set yet, which means the request is still being invoked. Save the results for later.
+ //
+ _exception = convertException(ex);
+ return;
+ }
+
+ PyObjectHandle exh = convertException(ex);
+ assert(exh.get());
+ PyObjectHandle tmp = callMethod(_future, "set_exception", exh.get());
+ PyErr_Clear();
+
+ Py_DECREF(_future); // Break cyclic dependency.
+ _future = 0;
+}
+
+void
+IcePy::FlushAsyncCallback::sent(bool sentSynchronously)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
+ {
+ //
+ // The future hasn't been set yet, which means the request is still being invoked. Save the results for later.
+ //
+ _sent = true;
+ _sentSynchronously = sentSynchronously;
+ return;
+ }
+
+ PyObjectHandle tmp = callMethod(_future, "set_sent", _sentSynchronously ? getTrue() : getFalse());
+ PyErr_Clear();
+ //
+ // We consider the invocation complete when sent.
+ //
+ tmp = callMethod(_future, "set_result", Py_None);
+ PyErr_Clear();
+
+ Py_DECREF(_future); // Break cyclic dependency.
+ _future = 0;
+}
+
IcePy::GetConnectionCallback::GetConnectionCallback(const Ice::CommunicatorPtr& communicator,
PyObject* response, PyObject* ex, const string& op) :
_communicator(communicator), _response(response), _ex(ex), _op(op)
@@ -4053,6 +4381,92 @@ IcePy::GetConnectionCallback::exception(const Ice::Exception& ex)
callException(_ex, ex);
}
+IcePy::GetConnectionAsyncCallback::GetConnectionAsyncCallback(const Ice::CommunicatorPtr& communicator,
+ const string& op) :
+ _communicator(communicator), _op(op), _future(0), _exception(0)
+{
+}
+
+IcePy::GetConnectionAsyncCallback::~GetConnectionAsyncCallback()
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ Py_XDECREF(_future);
+ Py_XDECREF(_exception);
+}
+
+void
+IcePy::GetConnectionAsyncCallback::setFuture(PyObject* future)
+{
+ //
+ // Called with the GIL locked.
+ //
+
+ //
+ // Check if any callbacks have been invoked already.
+ //
+ if(_connection)
+ {
+ PyObjectHandle pyConn = createConnection(_connection, _communicator);
+ assert(pyConn.get());
+ PyObjectHandle tmp = callMethod(future, "set_result", pyConn.get());
+ PyErr_Clear();
+ }
+ else if(_exception)
+ {
+ PyObjectHandle tmp = callMethod(future, "set_exception", _exception);
+ PyErr_Clear();
+ }
+ else
+ {
+ _future = incRef(future);
+ }
+}
+
+void
+IcePy::GetConnectionAsyncCallback::response(const Ice::ConnectionPtr& conn)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
+ {
+ //
+ // The future hasn't been set yet, which means the request is still being invoked. Save the results for later.
+ //
+ _connection = conn;
+ return;
+ }
+
+ PyObjectHandle pyConn = createConnection(conn, _communicator);
+ PyObjectHandle tmp = callMethod(_future, "set_result", pyConn.get());
+ PyErr_Clear();
+
+ Py_DECREF(_future); // Break cyclic dependency.
+ _future = 0;
+}
+
+void
+IcePy::GetConnectionAsyncCallback::exception(const Ice::Exception& ex)
+{
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ if(!_future)
+ {
+ //
+ // The future hasn't been set yet, which means the request is still being invoked. Save the results for later.
+ //
+ _exception = convertException(ex);
+ return;
+ }
+
+ PyObjectHandle exh = convertException(ex);
+ PyObjectHandle tmp = callMethod(_future, "set_exception", exh.get());
+ PyErr_Clear();
+
+ Py_DECREF(_future); // Break cyclic dependency.
+ _future = 0;
+}
+
//
// ServantWrapper implementation.
//
@@ -4172,7 +4586,7 @@ IcePy::BlobjectServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invoke
try
{
- UpcallPtr up = new BlobjectUpcall(_amd, cb);
+ UpcallPtr up = new BlobjectUpcall(cb);
up->dispatch(_servant, inParams, current);
}
catch(const Ice::Exception& ex)
@@ -4199,3 +4613,50 @@ IcePy::createServantWrapper(PyObject* servant)
return new TypedServantWrapper(servant);
}
+
+PyObject*
+IcePy::createFuture()
+{
+ PyObject* futureType = lookupType("Ice.Future");
+ assert(futureType);
+ PyObjectHandle args = PyTuple_New(0);
+ if(!args.get())
+ {
+ return 0;
+ }
+ PyTypeObject* type = reinterpret_cast<PyTypeObject*>(futureType);
+ PyObject* future = type->tp_new(type, args.get(), 0);
+ if(!future)
+ {
+ return 0;
+ }
+ type->tp_init(future, args.get(), 0); // Call the constructor
+ return future;
+}
+
+PyObject*
+IcePy::createFuture(const string& operation, PyObject* asyncResult)
+{
+ if(!asyncResult) // Can be nil for batch invocations.
+ {
+ asyncResult = Py_None;
+ }
+
+ PyObject* futureType = lookupType("Ice.InvocationFuture");
+ assert(futureType);
+ PyObjectHandle args = PyTuple_New(2);
+ if(!args.get())
+ {
+ return 0;
+ }
+ PyTuple_SET_ITEM(args.get(), 0, createString(operation));
+ PyTuple_SET_ITEM(args.get(), 1, incRef(asyncResult));
+ PyTypeObject* type = reinterpret_cast<PyTypeObject*>(futureType);
+ PyObject* future = type->tp_new(type, args.get(), 0);
+ if(!future)
+ {
+ return 0;
+ }
+ type->tp_init(future, args.get(), 0); // Call the constructor
+ return future;
+}
diff --git a/python/modules/IcePy/Operation.h b/python/modules/IcePy/Operation.h
index cc8736f1ec7..3d0c2e44850 100644
--- a/python/modules/IcePy/Operation.h
+++ b/python/modules/IcePy/Operation.h
@@ -15,6 +15,8 @@
#include <Ice/Object.h>
#include <Ice/AsyncResultF.h>
#include <Ice/CommunicatorF.h>
+#include <IceUtil/Monitor.h>
+#include <Util.h>
namespace IcePy
{
@@ -25,6 +27,7 @@ bool initOperation(PyObject*);
// Builtin operations.
//
PyObject* invokeBuiltin(PyObject*, const std::string&, PyObject*);
+PyObject* invokeBuiltinAsync(PyObject*, const std::string&, PyObject*);
PyObject* beginBuiltin(PyObject*, const std::string&, PyObject*);
PyObject* endBuiltin(PyObject*, const std::string&, PyObject*);
@@ -63,6 +66,31 @@ protected:
typedef IceUtil::Handle<GetConnectionCallback> GetConnectionCallbackPtr;
//
+// Used as the callback for getConnectionAsync operation.
+//
+class GetConnectionAsyncCallback : public IceUtil::Shared
+{
+public:
+
+ GetConnectionAsyncCallback(const Ice::CommunicatorPtr&, const std::string&);
+ ~GetConnectionAsyncCallback();
+
+ void setFuture(PyObject*);
+
+ void response(const Ice::ConnectionPtr&);
+ void exception(const Ice::Exception&);
+
+protected:
+
+ Ice::CommunicatorPtr _communicator;
+ std::string _op;
+ PyObject* _future;
+ Ice::ConnectionPtr _connection;
+ PyObject* _exception;
+};
+typedef IceUtil::Handle<GetConnectionAsyncCallback> GetConnectionAsyncCallbackPtr;
+
+//
// Used as the callback for the various flushBatchRequest operations.
//
class FlushCallback : public IceUtil::Shared
@@ -84,6 +112,31 @@ protected:
typedef IceUtil::Handle<FlushCallback> FlushCallbackPtr;
//
+// Used as the callback for the various flushBatchRequestAsync operations.
+//
+class FlushAsyncCallback : public IceUtil::Shared
+{
+public:
+
+ FlushAsyncCallback(const std::string&);
+ ~FlushAsyncCallback();
+
+ void setFuture(PyObject*);
+
+ void exception(const Ice::Exception&);
+ void sent(bool);
+
+protected:
+
+ std::string _op;
+ PyObject* _future;
+ bool _sent;
+ bool _sentSynchronously;
+ PyObject* _exception;
+};
+typedef IceUtil::Handle<FlushAsyncCallback> FlushAsyncCallbackPtr;
+
+//
// ServantWrapper handles dispatching to a Python servant.
//
class ServantWrapper : public Ice::BlobjectArrayAsync
@@ -103,6 +156,9 @@ typedef IceUtil::Handle<ServantWrapper> ServantWrapperPtr;
ServantWrapperPtr createServantWrapper(PyObject*);
+PyObject* createFuture();
+PyObject* createFuture(const std::string&, PyObject*);
+
}
#endif
diff --git a/python/modules/IcePy/Proxy.cpp b/python/modules/IcePy/Proxy.cpp
index 0d1c11bb082..a9fb3b09360 100644
--- a/python/modules/IcePy/Proxy.cpp
+++ b/python/modules/IcePy/Proxy.cpp
@@ -201,6 +201,27 @@ proxyIceIsA(ProxyObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+proxyIceIsAAsync(ProxyObject* self, PyObject* args)
+{
+ PyObject* type;
+ PyObject* ctx = Py_None;
+ if(!PyArg_ParseTuple(args, STRCAST("O|O!"), &type, &PyDict_Type, &ctx))
+ {
+ return 0;
+ }
+
+ //
+ // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None)
+ //
+ PyObjectHandle newArgs = Py_BuildValue(STRCAST("((O), O)"), type, ctx);
+
+ return invokeBuiltinAsync(reinterpret_cast<PyObject*>(self), "ice_isA", newArgs.get());
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceIsA(ProxyObject* self, PyObject* args, PyObject* kwds)
{
static char* argNames[] =
@@ -265,6 +286,26 @@ proxyIcePing(ProxyObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+proxyIcePingAsync(ProxyObject* self, PyObject* args)
+{
+ PyObject* ctx = Py_None;
+ if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx))
+ {
+ return 0;
+ }
+
+ //
+ // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None)
+ //
+ PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx);
+
+ return invokeBuiltinAsync(reinterpret_cast<PyObject*>(self), "ice_ping", newArgs.get());
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIcePing(ProxyObject* self, PyObject* args, PyObject* kwds)
{
static char* argNames[] =
@@ -327,6 +368,26 @@ proxyIceIds(ProxyObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+proxyIceIdsAsync(ProxyObject* self, PyObject* args)
+{
+ PyObject* ctx = Py_None;
+ if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx))
+ {
+ return 0;
+ }
+
+ //
+ // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None)
+ //
+ PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx);
+
+ return invokeBuiltinAsync(reinterpret_cast<PyObject*>(self), "ice_ids", newArgs.get());
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceIds(ProxyObject* self, PyObject* args, PyObject* kwds)
{
static char* argNames[] =
@@ -389,6 +450,26 @@ proxyIceId(ProxyObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+proxyIceIdAsync(ProxyObject* self, PyObject* args)
+{
+ PyObject* ctx = Py_None;
+ if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx))
+ {
+ return 0;
+ }
+
+ //
+ // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None)
+ //
+ PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx);
+
+ return invokeBuiltinAsync(reinterpret_cast<PyObject*>(self), "ice_id", newArgs.get());
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceId(ProxyObject* self, PyObject* args, PyObject* kwds)
{
static char* argNames[] =
@@ -1733,6 +1814,51 @@ proxyIceGetConnection(ProxyObject* self)
extern "C"
#endif
static PyObject*
+proxyIceGetConnectionAsync(ProxyObject* self, PyObject* /*args*/, PyObject* /*kwds*/)
+{
+ assert(self->proxy);
+ const string op = "ice_getConnection";
+
+ GetConnectionAsyncCallbackPtr d = new GetConnectionAsyncCallback(*self->communicator, op);
+ Ice::Callback_Object_ice_getConnectionPtr cb =
+ Ice::newCallback_Object_ice_getConnection(d, &GetConnectionAsyncCallback::response,
+ &GetConnectionAsyncCallback::exception);
+
+ Ice::AsyncResultPtr result;
+
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+
+ result = (*self->proxy)->begin_ice_getConnection(cb);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator);
+ PyObjectHandle asyncResultObj =
+ createAsyncResult(result, reinterpret_cast<PyObject*>(self), 0, communicatorObj.get());
+ if(!asyncResultObj.get())
+ {
+ return 0;
+ }
+
+ PyObjectHandle future = createFuture(op, asyncResultObj.get());
+ if(!future.get())
+ {
+ return 0;
+ }
+ d->setFuture(future.get());
+ return future.release();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceGetConnection(ProxyObject* self, PyObject* args, PyObject* kwds)
{
assert(self->proxy);
@@ -1894,6 +2020,50 @@ proxyIceFlushBatchRequests(ProxyObject* self)
extern "C"
#endif
static PyObject*
+proxyIceFlushBatchRequestsAsync(ProxyObject* self, PyObject* /*args*/, PyObject* /*kwds*/)
+{
+ assert(self->proxy);
+ const string op = "ice_flushBatchRequests";
+
+ FlushAsyncCallbackPtr d = new FlushAsyncCallback(op);
+ Ice::Callback_Object_ice_flushBatchRequestsPtr cb =
+ Ice::newCallback_Object_ice_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent);
+
+ Ice::AsyncResultPtr result;
+
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+
+ result = (*self->proxy)->begin_ice_flushBatchRequests(cb);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator);
+ PyObjectHandle asyncResultObj =
+ createAsyncResult(result, reinterpret_cast<PyObject*>(self), 0, communicatorObj.get());
+ if(!asyncResultObj.get())
+ {
+ return 0;
+ }
+
+ PyObjectHandle future = createFuture(op, asyncResultObj.get());
+ if(!future.get())
+ {
+ return 0;
+ }
+ d->setFuture(future.get());
+ return future.release();
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceFlushBatchRequests(ProxyObject* self, PyObject* args, PyObject* kwds)
{
assert(self->proxy);
@@ -2030,7 +2200,7 @@ AMI_Object_ice_flushBatchRequestsI::exception(const Ice::Exception& ex)
ostringstream ostr;
ostr << "AMI callback object for ice_flushBatchRequests does not define " << methodName << "()";
string str = ostr.str();
- PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()));
+ PyErr_WarnEx(PyExc_RuntimeWarning, const_cast<char*>(str.c_str()), 1);
}
else
{
@@ -2081,6 +2251,15 @@ proxyIceInvoke(ProxyObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+proxyIceInvokeAsync(ProxyObject* self, PyObject* args, PyObject* /*kwds*/)
+{
+ return iceInvokeAsync(reinterpret_cast<PyObject*>(self), args);
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
proxyBeginIceInvoke(ProxyObject* self, PyObject* args, PyObject* kwds)
{
return beginIceInvoke(reinterpret_cast<PyObject*>(self), args, kwds);
@@ -2389,24 +2568,32 @@ static PyMethodDef ProxyMethods[] =
PyDoc_STR(STRCAST("ice_toString() -> string")) },
{ STRCAST("ice_isA"), reinterpret_cast<PyCFunction>(proxyIceIsA), METH_VARARGS,
PyDoc_STR(STRCAST("ice_isA(type, [ctx]) -> bool")) },
+ { STRCAST("ice_isAAsync"), reinterpret_cast<PyCFunction>(proxyIceIsAAsync), METH_VARARGS,
+ PyDoc_STR(STRCAST("ice_isAAsync(type, [ctx]) -> Ice.Future")) },
{ STRCAST("begin_ice_isA"), reinterpret_cast<PyCFunction>(proxyBeginIceIsA), METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_ice_isA(type[, _response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_isA"), reinterpret_cast<PyCFunction>(proxyEndIceIsA), METH_VARARGS,
PyDoc_STR(STRCAST("end_ice_isA(Ice.AsyncResult) -> bool")) },
{ STRCAST("ice_ping"), reinterpret_cast<PyCFunction>(proxyIcePing), METH_VARARGS,
PyDoc_STR(STRCAST("ice_ping([ctx]) -> None")) },
+ { STRCAST("ice_pingAsync"), reinterpret_cast<PyCFunction>(proxyIcePingAsync), METH_VARARGS,
+ PyDoc_STR(STRCAST("ice_pingAsync([ctx]) -> Ice.Future")) },
{ STRCAST("begin_ice_ping"), reinterpret_cast<PyCFunction>(proxyBeginIcePing), METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_ice_ping([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_ping"), reinterpret_cast<PyCFunction>(proxyEndIcePing), METH_VARARGS,
PyDoc_STR(STRCAST("end_ice_ping(Ice.AsyncResult) -> None")) },
{ STRCAST("ice_ids"), reinterpret_cast<PyCFunction>(proxyIceIds), METH_VARARGS,
PyDoc_STR(STRCAST("ice_ids([ctx]) -> list")) },
+ { STRCAST("ice_idsAsync"), reinterpret_cast<PyCFunction>(proxyIceIdsAsync), METH_VARARGS,
+ PyDoc_STR(STRCAST("ice_idsAsync([ctx]) -> Ice.Future")) },
{ STRCAST("begin_ice_ids"), reinterpret_cast<PyCFunction>(proxyBeginIceIds), METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_ice_ids([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_ids"), reinterpret_cast<PyCFunction>(proxyEndIceIds), METH_VARARGS,
PyDoc_STR(STRCAST("end_ice_ids(Ice.AsyncResult) -> list")) },
{ STRCAST("ice_id"), reinterpret_cast<PyCFunction>(proxyIceId), METH_VARARGS,
PyDoc_STR(STRCAST("ice_id([ctx]) -> string")) },
+ { STRCAST("ice_idAsync"), reinterpret_cast<PyCFunction>(proxyIceIdAsync), METH_VARARGS,
+ PyDoc_STR(STRCAST("ice_idAsync([ctx]) -> Ice.Future")) },
{ STRCAST("begin_ice_id"), reinterpret_cast<PyCFunction>(proxyBeginIceId), METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_ice_id([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_id"), reinterpret_cast<PyCFunction>(proxyEndIceId), METH_VARARGS,
@@ -2501,6 +2688,8 @@ static PyMethodDef ProxyMethods[] =
PyDoc_STR(STRCAST("ice_connectionId(string) -> Ice.ObjectPrx")) },
{ STRCAST("ice_getConnection"), reinterpret_cast<PyCFunction>(proxyIceGetConnection), METH_NOARGS,
PyDoc_STR(STRCAST("ice_getConnection() -> Ice.Connection")) },
+ { STRCAST("ice_getConnectionAsync"), reinterpret_cast<PyCFunction>(proxyIceGetConnectionAsync),
+ METH_NOARGS, PyDoc_STR(STRCAST("ice_getConnectionAsync() -> Ice.Future")) },
{ STRCAST("begin_ice_getConnection"), reinterpret_cast<PyCFunction>(proxyBeginIceGetConnection),
METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_ice_getConnection([_response][, _ex]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_getConnection"), reinterpret_cast<PyCFunction>(proxyEndIceGetConnection), METH_VARARGS,
@@ -2509,12 +2698,16 @@ static PyMethodDef ProxyMethods[] =
PyDoc_STR(STRCAST("ice_getCachedConnection() -> Ice.Connection")) },
{ STRCAST("ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyIceFlushBatchRequests), METH_NOARGS,
PyDoc_STR(STRCAST("ice_flushBatchRequests() -> void")) },
+ { STRCAST("ice_flushBatchRequestsAsync"), reinterpret_cast<PyCFunction>(proxyIceFlushBatchRequestsAsync),
+ METH_NOARGS, PyDoc_STR(STRCAST("ice_flushBatchRequestsAsync() -> Ice.Future")) },
{ STRCAST("begin_ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyBeginIceFlushBatchRequests),
METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_ice_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyEndIceFlushBatchRequests), METH_VARARGS,
PyDoc_STR(STRCAST("end_ice_flushBatchRequests(Ice.AsyncResult) -> void")) },
{ STRCAST("ice_invoke"), reinterpret_cast<PyCFunction>(proxyIceInvoke), METH_VARARGS,
PyDoc_STR(STRCAST("ice_invoke(operation, mode, inParams) -> bool, outParams")) },
+ { STRCAST("ice_invokeAsync"), reinterpret_cast<PyCFunction>(proxyIceInvokeAsync), METH_VARARGS | METH_KEYWORDS,
+ PyDoc_STR(STRCAST("ice_invokeAsync(op, mode, inParams[, _ctx]) -> Ice.Future")) },
{ STRCAST("begin_ice_invoke"), reinterpret_cast<PyCFunction>(proxyBeginIceInvoke), METH_VARARGS | METH_KEYWORDS,
PyDoc_STR(STRCAST("begin_ice_invoke(op, mode, inParams[, _response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) },
{ STRCAST("end_ice_invoke"), reinterpret_cast<PyCFunction>(proxyEndIceInvoke), METH_VARARGS,
diff --git a/python/modules/IcePy/Slice.cpp b/python/modules/IcePy/Slice.cpp
index 1294a80194c..4581a97f45b 100644
--- a/python/modules/IcePy/Slice.cpp
+++ b/python/modules/IcePy/Slice.cpp
@@ -72,6 +72,7 @@ IcePy_loadSlice(PyObject* /*self*/, PyObject* args)
opts.addOpt("", "underscore");
opts.addOpt("", "checksum");
opts.addOpt("", "all");
+ opts.addOpt("", "python3");
vector<string> files;
try
@@ -102,6 +103,7 @@ IcePy_loadSlice(PyObject* /*self*/, PyObject* args)
bool underscore = opts.isSet("underscore");
bool all = false;
bool checksum = false;
+ bool python3 = false;
if(opts.isSet("D"))
{
vector<string> optargs = opts.argVec("D");
@@ -129,6 +131,7 @@ IcePy_loadSlice(PyObject* /*self*/, PyObject* args)
debug = opts.isSet("d") || opts.isSet("debug");
all = opts.isSet("all");
checksum = opts.isSet("checksum");
+ python3 = opts.isSet("python3");
bool ignoreRedefs = false;
bool keepComments = true;
@@ -161,11 +164,13 @@ IcePy_loadSlice(PyObject* /*self*/, PyObject* args)
ostringstream codeStream;
IceUtilInternal::Output out(codeStream);
out.setUseTab(false);
+
//
- // Python magic comment to set the file encoding, it must be first or second line
+ // Emit a Python magic comment to set the file encoding.
+ // It must be the first or second line.
//
out << "# -*- coding: utf-8 -*-\n";
- generate(u, all, checksum, includePaths, out);
+ generate(u, all, checksum, python3, includePaths, out);
u->destroy();
string code = codeStream.str();
diff --git a/python/modules/IcePy/Util.cpp b/python/modules/IcePy/Util.cpp
index b40d9f3dcfb..8d0cd602aae 100644
--- a/python/modules/IcePy/Util.cpp
+++ b/python/modules/IcePy/Util.cpp
@@ -468,11 +468,12 @@ IcePy::PyException::getTraceback()
PyObjectHandle str = createString("traceback");
PyObjectHandle mod = PyImport_Import(str.get());
assert(mod.get()); // Unable to import traceback module - Python installation error?
- PyObject* d = PyModule_GetDict(mod.get());
- PyObject* func = PyDict_GetItemString(d, "format_exception");
+ PyObject* func = PyDict_GetItemString(PyModule_GetDict(mod.get()), "format_exception");
assert(func); // traceback.format_exception must be present.
PyObjectHandle args = Py_BuildValue("(OOO)", _type.get(), ex.get(), _tb.get());
+ assert(args.get());
PyObjectHandle list = PyObject_CallObject(func, args.get());
+ assert(list.get());
string result;
for(Py_ssize_t i = 0; i < PyList_GET_SIZE(list.get()); ++i)
@@ -1090,6 +1091,60 @@ IcePy::getEncodingVersion(PyObject* args, Ice::EncodingVersion& v)
return true;
}
+PyObject*
+IcePy::callMethod(PyObject* obj, const string& name, PyObject* arg1, PyObject* arg2)
+{
+ PyObjectHandle method = PyObject_GetAttrString(obj, const_cast<char*>(name.c_str()));
+ if(!method.get())
+ {
+ return 0;
+ }
+ return callMethod(method.get(), arg1, arg2);
+}
+
+PyObject*
+IcePy::callMethod(PyObject* method, PyObject* arg1, PyObject* arg2)
+{
+ PyObjectHandle args;
+ if(arg1 && arg2)
+ {
+ args = PyTuple_New(2);
+ if(!args.get())
+ {
+ return 0;
+ }
+ PyTuple_SET_ITEM(args.get(), 0, incRef(arg1));
+ PyTuple_SET_ITEM(args.get(), 1, incRef(arg2));
+ }
+ else if(arg1)
+ {
+ args = PyTuple_New(1);
+ if(!args.get())
+ {
+ return 0;
+ }
+ PyTuple_SET_ITEM(args.get(), 0, incRef(arg1));
+ }
+ else if(arg2)
+ {
+ args = PyTuple_New(1);
+ if(!args.get())
+ {
+ return 0;
+ }
+ PyTuple_SET_ITEM(args.get(), 0, incRef(arg2));
+ }
+ else
+ {
+ args = PyTuple_New(0);
+ if(!args.get())
+ {
+ return 0;
+ }
+ }
+ return PyObject_Call(method, args.get(), 0);
+}
+
extern "C"
PyObject*
IcePy_stringVersion(PyObject* /*self*/)
diff --git a/python/modules/IcePy/Util.h b/python/modules/IcePy/Util.h
index 54f1df6b21f..76035279ebe 100644
--- a/python/modules/IcePy/Util.h
+++ b/python/modules/IcePy/Util.h
@@ -28,6 +28,12 @@
namespace IcePy
{
+inline PyObject* incRef(PyObject* obj)
+{
+ Py_XINCREF(obj);
+ return obj;
+}
+
//
// This should be used instead of Py_False to avoid GCC compiler warnings.
//
@@ -58,16 +64,12 @@ inline PyObject* getTrue()
inline PyObject* incFalse()
{
- PyObject* f = getFalse();
- Py_INCREF(f);
- return f;
+ return incRef(getFalse());
}
inline PyObject* incTrue()
{
- PyObject* t = getTrue();
- Py_INCREF(t);
- return t;
+ return incRef(getTrue());
}
//
@@ -262,6 +264,12 @@ PyObject* createEncodingVersion(const Ice::EncodingVersion&);
//
bool getEncodingVersion(PyObject*, Ice::EncodingVersion&);
+//
+// Call a Python method.
+//
+PyObject* callMethod(PyObject*, const std::string&, PyObject* = 0, PyObject* = 0);
+PyObject* callMethod(PyObject*, PyObject* = 0, PyObject* = 0);
+
}
extern "C" PyObject* IcePy_stringVersion(PyObject*);
diff --git a/python/python/Ice.py b/python/python/Ice.py
index 7c06a1fec77..46218a57f6f 100644
--- a/python/python/Ice.py
+++ b/python/python/Ice.py
@@ -11,7 +11,7 @@
Ice module
"""
-import sys, string, imp, os, threading, warnings, datetime
+import sys, string, imp, os, threading, warnings, datetime, logging, time, inspect
#
# RTTI problems can occur in C++ code unless we modify Python's dlopen flags.
@@ -76,6 +76,208 @@ loadSlice = IcePy.loadSlice
AsyncResult = IcePy.AsyncResult
Unset = IcePy.Unset
+if sys.version_info[0] > 3 or (sys.version_info[0] == 3 and sys.version_info[1] >= 5):
+ from IceFuture import FutureBase, wrap_future
+else:
+ FutureBase = object
+
+class Future(FutureBase):
+ def __init__(self):
+ self._result = None
+ self._exception = None
+ self._condition = threading.Condition()
+ self._doneCallbacks = []
+ self._state = Future.StateRunning
+
+ def cancel(self):
+ callbacks = []
+ with self._condition:
+ if self._state == Future.StateDone:
+ return False
+
+ if self._state == Future.StateCancelled:
+ return True
+
+ self._state = Future.StateCancelled
+ callbacks = self._doneCallbacks
+ self._doneCallbacks = []
+ self._condition.notify_all()
+
+ self._callCallbacks(callbacks)
+
+ return True
+
+ def cancelled(self):
+ with self._condition:
+ return self._state == Future.StateCancelled
+
+ def running(self):
+ with self._condition:
+ return self._state == Future.StateRunning
+
+ def done(self):
+ with self._condition:
+ return self._state in [Future.StateCancelled, Future.StateDone]
+
+ def add_done_callback(self, fn):
+ with self._condition:
+ if self._state == Future.StateRunning:
+ self._doneCallbacks.append(fn)
+ return
+ fn(self)
+
+ def result(self, timeout=None):
+ with self._condition:
+ if not self._wait(timeout, lambda: self._state == Future.StateRunning):
+ raise TimeoutException()
+ if self._state == Future.StateCancelled:
+ raise InvocationCanceledException()
+ elif self._exception:
+ raise self._exception
+ else:
+ return self._result
+
+ def exception(self, timeout=None):
+ with self._condition:
+ if not self._wait(timeout, lambda: self._state == Future.StateRunning):
+ raise TimeoutException()
+ if self._state == Future.StateCancelled:
+ raise InvocationCanceledException()
+ else:
+ return self._exception
+
+ def set_result(self, result):
+ callbacks = []
+ with self._condition:
+ if self._state != Future.StateRunning:
+ return
+ self._result = result
+ self._state = Future.StateDone
+ callbacks = self._doneCallbacks
+ self._doneCallbacks = []
+ self._condition.notify_all()
+
+ self._callCallbacks(callbacks)
+
+ def set_exception(self, ex):
+ callbacks = []
+ with self._condition:
+ if self._state != Future.StateRunning:
+ return
+ self._exception = ex
+ self._state = Future.StateDone
+ callbacks = self._doneCallbacks
+ self._doneCallbacks = []
+ self._condition.notify_all()
+
+ self._callCallbacks(callbacks)
+
+ def completed(result):
+ f = Future()
+ f.set_result(result)
+ return f
+ completed = staticmethod(completed)
+
+ def _wait(self, timeout, testFn=None):
+ # Must be called with _condition acquired
+
+ while testFn():
+ if timeout:
+ start = time.time()
+ self._condition.wait(timeout)
+ # Subtract the elapsed time so far from the timeout
+ timeout -= (time.time() - start)
+ if timeout <= 0:
+ return False
+ else:
+ self._condition.wait()
+
+ return True
+
+ def _callCallbacks(self, callbacks):
+ for callback in callbacks:
+ try:
+ callback(self)
+ except:
+ logging.getLogger("Ice.Future").exception('callback raised exception')
+
+ StateRunning = 'running'
+ StateCancelled = 'cancelled'
+ StateDone = 'done'
+
+class InvocationFuture(Future):
+ def __init__(self, operation, asyncResult):
+ Future.__init__(self)
+ self._operation = operation
+ self._asyncResult = asyncResult # May be None for a batch invocation.
+ self._sent = False
+ self._sentSynchronously = False
+ self._sentCallbacks = []
+
+ def cancel(self):
+ if self._asyncResult:
+ self._asyncResult.cancel()
+ return Future.cancel(self)
+
+ def is_sent(self):
+ with self._condition:
+ return self._sent
+
+ def sent_synchronously(self):
+ with self._condition:
+ return self._sentSynchronously
+
+ def add_sent_callback(self, fn):
+ with self._condition:
+ if not self._sent:
+ self._sentCallbacks.append(fn)
+ return
+ if self._sentSynchronously or not self._asyncResult:
+ fn(self, self._sentSynchronously)
+ else:
+ self._asyncResult.callLater(lambda: fn(self, self._sentSynchronously))
+
+ def sent(self, timeout=None):
+ with self._condition:
+ if not self._wait(timeout, lambda: not self._sent):
+ raise TimeoutException()
+ if self._state == Future.StateCancelled:
+ raise InvocationCanceledException()
+ elif self._exception:
+ raise self._exception
+ else:
+ return self._sentSynchronously
+
+ def set_sent(self, sentSynchronously):
+ callbacks = []
+ with self._condition:
+ if self._sent:
+ return
+
+ self._sent = True
+ self._sentSynchronously = sentSynchronously
+ callbacks = self._sentCallbacks
+ self._sentCallbacks = []
+ self._condition.notify_all()
+
+ for callback in callbacks:
+ try:
+ callback(self, sentSynchronously)
+ except Exception:
+ logging.getLogger("Ice.Future").exception('callback raised exception')
+
+ def operation(self):
+ return self._operation
+
+ def proxy(self):
+ return None if not self._asyncResult else self._asyncResult.getProxy()
+
+ def connection(self):
+ return None if not self._asyncResult else self._asyncResult.getConnection()
+
+ def communicator(self):
+ return None if not self._asyncResult else self._asyncResult.getCommunicator()
+
#
# This value is used as the default value for struct types in the constructors
# of user-defined types. It allows us to determine whether the application has
@@ -134,11 +336,52 @@ Returns:
#def ice_postUnmarshal(self):
# pass
-#
-# LocalObject is deprecated; use the Python base 'object' type instead.
-#
-class LocalObject(object):
- pass
+ def _dispatch(self, cb, method, args):
+ # Invoke the given servant method. Exceptions can propagate to the caller.
+ result = method(*args)
+
+ # Check for a future.
+ if isinstance(result, Future) or callable(getattr(result, "add_done_callback", None)):
+ def handler(future):
+ try:
+ cb.response(future.result())
+ except:
+ cb.exception(sys.exc_info()[1])
+ result.add_done_callback(handler)
+ elif self._isCoroutine(result):
+ self._dispatchCoroutine(cb, result)
+ else:
+ cb.response(result)
+
+ def _isCoroutine(self, coro):
+ # The inspect.iscoroutine() function was added in Python 3.5.
+ if sys.version_info[0] > 3 or (sys.version_info[0] == 3 and sys.version_info[1] >= 5):
+ return inspect.iscoroutine(coro)
+ else:
+ return False
+
+ def _dispatchCoroutine(self, cb, coro, value=None, exception=None):
+ try:
+ if exception:
+ result = coro.throw(exception)
+ else:
+ result = coro.send(value)
+
+ # Calling 'await <future>' will return the future. Check if we've received a future.
+ if isinstance(result, Future) or callable(getattr(result, "add_done_callback", None)):
+ def handler(future):
+ try:
+ self._dispatchCoroutine(cb, coro, value=future.result())
+ except:
+ self._dispatchCoroutine(cb, coro, exception=sys.exc_info()[1])
+ result.add_done_callback(handler)
+ else:
+ raise RuntimeError('unexpected value of type ' + str(type(result)) + ' provided by coroutine')
+ except StopIteration as ex:
+ # StopIteration is raised when the coroutine completes.
+ cb.response(ex.value)
+ except:
+ cb.exception(sys.exc_info()[1])
class Blobject(Object):
'''Special-purpose servant base class that allows a subclass to
@@ -670,6 +913,9 @@ class CommunicatorI(Communicator):
def flushBatchRequests(self):
self._impl.flushBatchRequests()
+ def flushBatchRequestsAsync(self):
+ return self._impl.flushBatchRequestsAsync()
+
def begin_flushBatchRequests(self, _ex=None, _sent=None):
return self._impl.begin_flushBatchRequests(_ex, _sent)
diff --git a/python/python/IceFuture.py b/python/python/IceFuture.py
new file mode 100644
index 00000000000..c79c5b8d512
--- /dev/null
+++ b/python/python/IceFuture.py
@@ -0,0 +1,48 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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.
+#
+# **********************************************************************
+
+#
+# This file should only be used in Python >= 3.5.
+#
+
+import asyncio
+
+#
+# This class defines an __await__ method so that coroutines can call 'await <future>'.
+#
+# Python 2.x rejects this code with a syntax error because a return statement is not allowed in a generator.
+#
+class FutureBase(object):
+ def __await__(self):
+ if not self.done():
+ yield self
+ return self.result()
+
+def wrap_future(future, *, loop=None):
+ '''Wrap Ice.Future object into an asyncio.Future.'''
+ if isinstance(future, asyncio.Future):
+ return future
+
+ assert isinstance(future, FutureBase), 'Ice.Future is expected, got {!r}'.format(future)
+
+ if loop is None:
+ loop = asyncio.get_event_loop()
+
+ af = loop.create_future()
+
+ def callback():
+ if future.cancelled():
+ af.cancel()
+ elif future.exception():
+ af.set_exception(future.exception())
+ else:
+ af.set_result(future.result())
+
+ future.add_done_callback(lambda f: loop.call_soon_threadsafe(callback))
+ return af
diff --git a/python/test/Ice/acm/AllTests.py b/python/test/Ice/acm/AllTests.py
index a82b6515db2..c10edd1de77 100644
--- a/python/test/Ice/acm/AllTests.py
+++ b/python/test/Ice/acm/AllTests.py
@@ -20,48 +20,33 @@ class LoggerI(Ice.Logger):
self.m = threading.Lock()
def start(self):
- self.m.acquire()
- try:
+ with self.m:
self._started = True
self.dump()
- finally:
- self.m.release()
def _print(self, msg):
- self.m.acquire()
- try:
+ with self.m:
self._messages.append(msg)
if self._started:
self.dump()
- finally:
- self.m.release()
def trace(self, category, msg):
- self.m.acquire()
- try:
+ with self.m:
self._messages.append("[" + category + "] " + msg)
if self._started:
self.dump()
- finally:
- self.m.release()
def warning(self, msg):
- self.m.acquire()
- try:
+ with self.m:
self._messages.append("warning: " + msg)
if self._started:
self.dump()
- finally:
- self.m.release()
def error(self, msg):
- self.m.acquire()
- try:
+ with self.m:
self._messages.append("error: " + msg)
if self._started:
self.dump()
- finally:
- self.m.release()
def getPrefix(self):
return ""
@@ -136,18 +121,12 @@ class TestCase(threading.Thread):
self._msg = "unexpected exception:\n" + traceback.format_exc()
def heartbeat(self, con):
- self.m.acquire()
- try:
+ with self.m:
self._heartbeat = self._heartbeat + 1
- finally:
- self.m.release()
def closed(self, con):
- self.m.acquire()
- try:
+ with self.m:
self._closed = True
- finally:
- self.m.release()
def runTestCase(self, adapter, proxy):
test(False)
@@ -175,11 +154,8 @@ def allTests(communicator):
def runTestCase(self, adapter, proxy):
proxy.sleep(2)
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat >= 2)
- finally:
- self.m.release()
class InvocationHeartbeatOnHoldTest(TestCase):
def __init__(self, com):
@@ -197,11 +173,8 @@ def allTests(communicator):
adapter.activate()
proxy.interruptSleep()
- self.m.acquire()
- try:
+ with self.m:
test(self._closed)
- finally:
- self.m.release()
class InvocationNoHeartbeatTest(TestCase):
def __init__(self, com):
@@ -218,12 +191,9 @@ def allTests(communicator):
except Ice.ConnectionTimeoutException:
proxy.interruptSleep()
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(self._closed)
- finally:
- self.m.release()
class InvocationHeartbeatCloseOnIdleTest(TestCase):
def __init__(self, com):
@@ -235,12 +205,9 @@ def allTests(communicator):
# No close on invocation, the call should succeed this time.
proxy.sleep(2)
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(not self._closed)
- finally:
- self.m.release()
class CloseOnIdleTest(TestCase):
def __init__(self, com):
@@ -250,12 +217,9 @@ def allTests(communicator):
def runTestCase(self, adapter, proxy):
time.sleep(1.6) # Idle for 1.6 seconds
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(self._closed)
- finally:
- self.m.release()
class CloseOnInvocationTest(TestCase):
def __init__(self, com):
@@ -265,12 +229,9 @@ def allTests(communicator):
def runTestCase(self, adapter, proxy):
time.sleep(1.5) # Idle for 1.5 seconds
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(not self._closed)
- finally:
- self.m.release()
class CloseOnIdleAndInvocationTest(TestCase):
def __init__(self, com):
@@ -286,21 +247,15 @@ def allTests(communicator):
adapter.hold()
time.sleep(1.6) # Idle for 1.6 seconds
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(not self._closed) # Not closed yet because of graceful close.
- finally:
- self.m.release()
adapter.activate()
time.sleep(0.5)
- self.m.acquire()
- try:
+ with self.m:
test(self._closed) # Connection should be closed this time.
- finally:
- self.m.release()
class ForcefulCloseOnIdleAndInvocationTest(TestCase):
def __init__(self, com):
@@ -311,12 +266,9 @@ def allTests(communicator):
adapter.hold()
time.sleep(1.6) # Idle for 1.6 seconds
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat == 0)
test(self._closed) # Connection closed forcefully by ACM.
- finally:
- self.m.release()
class HeartbeatOnIdleTest(TestCase):
def __init__(self, com):
@@ -326,11 +278,8 @@ def allTests(communicator):
def runTestCase(self, adapter, proxy):
time.sleep(2)
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat >= 3)
- finally:
- self.m.release()
class HeartbeatAlwaysTest(TestCase):
def __init__(self, com):
@@ -342,11 +291,8 @@ def allTests(communicator):
proxy.ice_ping()
time.sleep(0.1)
- self.m.acquire()
- try:
+ with self.m:
test(self._heartbeat >= 3)
- finally:
- self.m.release()
class SetACMTest(TestCase):
def __init__(self, com):
diff --git a/python/test/Ice/acm/TestI.py b/python/test/Ice/acm/TestI.py
index a728dfce1b3..a54e13621bb 100644
--- a/python/test/Ice/acm/TestI.py
+++ b/python/test/Ice/acm/TestI.py
@@ -56,26 +56,17 @@ class TestIntfI(Test.TestIntf):
self.m = threading.Condition()
def sleep(self, delay, current=None):
- self.m.acquire()
- try:
+ with self.m:
self.m.wait(delay)
- finally:
- self.m.release()
def sleepAndHold(self, delay, current=None):
- self.m.acquire()
- try:
+ with self.m:
current.adapter.hold()
self.m.wait(delay)
- finally:
- self.m.release()
def interruptSleep(self, delay, current=None):
- self.m.acquire()
- try:
+ with self.m:
self.m.notifyAll()
- finally:
- self.m.release()
def waitForHeartbeat(self, count, current=None):
@@ -86,21 +77,15 @@ class TestIntfI(Test.TestIntf):
self.count = 0
def heartbeat(self, con):
- self.m.acquire()
- try:
+ with self.m:
self.count -= 1
self.m.notifyAll()
- finally:
- self.m.release()
def waitForCount(self, count):
- self.m.acquire()
- self.count = count
- try:
+ with self.m:
+ self.count = count
while self.count > 0:
self.m.wait()
- finally:
- self.m.release()
callback = ConnectionCallbackI()
current.con.setHeartbeatCallback(lambda con: callback.heartbeat(con))
diff --git a/python/test/Ice/adapterDeactivation/AllTests.py b/python/test/Ice/adapterDeactivation/AllTests.py
index a8936ef5b4a..4bcdff20117 100644
--- a/python/test/Ice/adapterDeactivation/AllTests.py
+++ b/python/test/Ice/adapterDeactivation/AllTests.py
@@ -57,7 +57,7 @@ def allTests(communicator):
initData = Ice.InitializationData();
initData.properties = communicator.getProperties().clone();
comm = Ice.initialize(initData);
- comm.stringToProxy("test:default -p 12010").begin_ice_ping();
+ comm.stringToProxy("test:default -p 12010").ice_pingAsync();
comm.destroy();
print("ok");
diff --git a/python/test/Ice/admin/TestI.py b/python/test/Ice/admin/TestI.py
index f1e6e0b49d5..c040ffbef59 100644
--- a/python/test/Ice/admin/TestI.py
+++ b/python/test/Ice/admin/TestI.py
@@ -27,8 +27,7 @@ class RemoteCommunicatorI(Test.RemoteCommunicator, Ice.PropertiesAdminUpdateCall
return self.communicator.getAdmin()
def getChanges(self, current = None):
- self.m.acquire()
- try:
+ with self.m:
#
# The client calls PropertiesAdmin::setProperties() and then invokes
# this operation. Since setProperties() is implemented using AMD, the
@@ -42,8 +41,6 @@ class RemoteCommunicatorI(Test.RemoteCommunicator, Ice.PropertiesAdminUpdateCall
self.called = False
return self.changes
- finally:
- self.m.release()
def shutdown(self, current = None):
self.communicator.shutdown()
@@ -59,13 +56,10 @@ class RemoteCommunicatorI(Test.RemoteCommunicator, Ice.PropertiesAdminUpdateCall
self.communicator.destroy()
def updated(self, changes):
- self.m.acquire()
- try:
+ with self.m:
self.changes = changes
self.called = True
self.m.notify()
- finally:
- self.m.release()
class RemoteCommunicatorFactoryI(Test.RemoteCommunicatorFactory):
diff --git a/python/test/Ice/ami/AllTests.py b/python/test/Ice/ami/AllTests.py
index e209138f9f3..5418336f12d 100644
--- a/python/test/Ice/ami/AllTests.py
+++ b/python/test/Ice/ami/AllTests.py
@@ -19,19 +19,15 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
def exception(self, ex):
test(False)
@@ -241,6 +237,86 @@ class FlushExCallback(CallbackBase):
def sentWC(self, sentSynchronously, cookie):
test(False)
+class FutureDoneCallback(CallbackBase):
+ def isA(self, f):
+ test(f.result())
+ self.called()
+
+ def ping(self, f):
+ self.called()
+
+ def id(self, f):
+ test(f.result() == "::Test::TestIntf")
+ self.called()
+
+ def ids(self, f):
+ test(len(f.result()) == 2)
+ self.called()
+
+ def connection(self, f):
+ test(f.result() != None)
+ self.called()
+
+ def op(self, f):
+ self.called()
+
+ def opWithResult(self, f):
+ test(f.result() == 15)
+ self.called()
+
+ def opWithUE(self, f):
+ try:
+ f.result()
+ test(False)
+ except Test.TestIntfException:
+ self.called()
+ except:
+ test(False)
+
+class FutureExceptionCallback(CallbackBase):
+ def opWithUE(self, f):
+ test(isinstance(f.exception(), Test.TestIntfException))
+ self.called()
+
+ def ex(self, f):
+ test(isinstance(f.exception(), Ice.NoEndpointException))
+ self.called()
+
+ def noEx(self, f):
+ test(f.exception() is None)
+
+class FutureSentCallback(CallbackBase):
+ def __init__(self):
+ CallbackBase.__init__(self)
+ self._thread = threading.currentThread()
+
+ def sent(self, f, sentSynchronously):
+ test((sentSynchronously and self._thread == threading.currentThread()) or \
+ (not sentSynchronously and self._thread != threading.currentThread()))
+ self.called()
+
+class FutureFlushCallback(CallbackBase):
+ def __init__(self, cookie=None):
+ CallbackBase.__init__(self)
+ self._thread = threading.currentThread()
+ self._cookie = cookie
+
+ def sent(self, f, sentSynchronously):
+ test((sentSynchronously and self._thread == threading.currentThread()) or \
+ (not sentSynchronously and self._thread != threading.currentThread()))
+ self.called()
+
+class FutureFlushExCallback(CallbackBase):
+ def __init__(self, cookie=None):
+ CallbackBase.__init__(self)
+ self._cookie = cookie
+
+ def exception(self, f):
+ self.called()
+
+ def sent(self, f, sentSynchronously):
+ test(False)
+
LocalException = 0
UserException = 1
OtherException = 2
@@ -1087,4 +1163,607 @@ def allTests(communicator, collocated):
print("ok")
+def allTestsFuture(communicator, collocated):
+ sref = "test:default -p 12010"
+ obj = communicator.stringToProxy(sref)
+ test(obj)
+
+ p = Test.TestIntfPrx.uncheckedCast(obj)
+
+ sref = "testController:default -p 12011"
+ obj = communicator.stringToProxy(sref)
+ test(obj)
+
+ testController = Test.TestIntfControllerPrx.uncheckedCast(obj)
+
+ sys.stdout.write("testing future invocations... ")
+ sys.stdout.flush()
+ ctx = {}
+
+ test(p.ice_isAAsync("::Test::TestIntf").result())
+ test(p.ice_isAAsync("::Test::TestIntf", ctx).result())
+
+ p.ice_pingAsync().result()
+ p.ice_pingAsync(ctx).result()
+
+ test(p.ice_idAsync().result() == "::Test::TestIntf")
+ test(p.ice_idAsync(ctx).result() == "::Test::TestIntf")
+
+ test(len(p.ice_idsAsync().result()) == 2)
+ test(len(p.ice_idsAsync(ctx).result()) == 2)
+
+ if not collocated:
+ test(p.ice_getConnectionAsync().result() != None)
+
+ p.opAsync().result()
+ p.opAsync(ctx).result()
+
+ test(p.opWithResultAsync().result() == 15)
+ test(p.opWithResultAsync(ctx).result() == 15)
+
+ try:
+ p.opWithUEAsync().result()
+ test(False)
+ except Test.TestIntfException:
+ pass
+ try:
+ p.opWithUEAsync(ctx).result()
+ test(False)
+ except Test.TestIntfException:
+ pass
+
+ print("ok")
+
+ sys.stdout.write("testing done callback... ")
+ sys.stdout.flush()
+
+ ctx = {}
+ cb = FutureDoneCallback()
+
+ p.ice_isAAsync(Test.TestIntf.ice_staticId()).add_done_callback(cb.isA)
+ cb.check()
+ p.ice_isAAsync(Test.TestIntf.ice_staticId(), ctx).add_done_callback(cb.isA)
+ cb.check()
+
+ p.ice_pingAsync().add_done_callback(cb.ping)
+ cb.check()
+ p.ice_pingAsync(ctx).add_done_callback(cb.ping)
+ cb.check()
+
+ p.ice_idAsync().add_done_callback(cb.id)
+ cb.check()
+ p.ice_idAsync(ctx).add_done_callback(cb.id)
+ cb.check()
+
+ p.ice_idsAsync().add_done_callback(cb.ids)
+ cb.check()
+ p.ice_idsAsync(ctx).add_done_callback(cb.ids)
+ cb.check()
+
+ if not collocated:
+ p.ice_getConnectionAsync().add_done_callback(cb.connection)
+ cb.check()
+
+ p.opAsync().add_done_callback(cb.op)
+ cb.check()
+ p.opAsync(ctx).add_done_callback(cb.op)
+ cb.check()
+
+ p.opWithResultAsync().add_done_callback(cb.opWithResult)
+ cb.check()
+ p.opWithResultAsync(ctx).add_done_callback(cb.opWithResult)
+ cb.check()
+
+ p.opWithUEAsync().add_done_callback(cb.opWithUE)
+ cb.check()
+ p.opWithUEAsync(ctx).add_done_callback(cb.opWithUE)
+ cb.check()
+
+ print("ok")
+
+ sys.stdout.write("testing local exceptions... ")
+ sys.stdout.flush()
+
+ indirect = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy"))
+
+ try:
+ indirect.opAsync().result()
+ test(False)
+ except Ice.NoEndpointException:
+ pass
+
+ try:
+ p.ice_oneway().opWithResultAsync().result()
+ test(False)
+ except RuntimeError:
+ pass
+
+ #
+ # Check that CommunicatorDestroyedException is raised directly.
+ #
+ if p.ice_getConnection():
+ initData = Ice.InitializationData()
+ initData.properties = communicator.getProperties().clone()
+ ic = Ice.initialize(initData)
+ obj = ic.stringToProxy(p.ice_toString())
+ p2 = Test.TestIntfPrx.checkedCast(obj)
+ ic.destroy();
+
+ try:
+ p2.opAsync()
+ test(False)
+ except Ice.CommunicatorDestroyedException:
+ pass
+
+ print("ok")
+
+ sys.stdout.write("testing local exceptions with done callback... ")
+ sys.stdout.flush()
+
+ i = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy"))
+ cb = FutureExceptionCallback()
+
+ i.ice_isAAsync(Test.TestIntf.ice_staticId()).add_done_callback(cb.ex)
+ cb.check()
+
+ i.ice_pingAsync().add_done_callback(cb.ex)
+ cb.check()
+
+ i.ice_idAsync().add_done_callback(cb.ex)
+ cb.check()
+
+ i.ice_idsAsync().add_done_callback(cb.ex)
+ cb.check()
+
+ if not collocated:
+ i.ice_getConnectionAsync().add_done_callback(cb.ex)
+ cb.check()
+
+ i.opAsync().add_done_callback(cb.ex)
+ cb.check()
+
+ print("ok")
+
+ sys.stdout.write("testing exceptions with done callback... ")
+ sys.stdout.flush()
+
+ cb = FutureExceptionCallback()
+
+ # Ensures no exception is set when response is received.
+ p.ice_isAAsync(Test.TestIntf.ice_staticId()).add_done_callback(cb.noEx)
+ p.opAsync().add_done_callback(cb.noEx)
+
+ # If response is a user exception, it should be received.
+ p.opWithUEAsync().add_done_callback(cb.opWithUE)
+ cb.check()
+
+ print("ok")
+
+ sys.stdout.write("testing sent callback... ")
+ sys.stdout.flush()
+
+ cb = FutureSentCallback()
+
+ p.ice_isAAsync("").add_sent_callback(cb.sent)
+ cb.check()
+
+ p.ice_pingAsync().add_sent_callback(cb.sent)
+ cb.check()
+
+ p.ice_idAsync().add_sent_callback(cb.sent)
+ cb.check()
+
+ p.ice_idsAsync().add_sent_callback(cb.sent)
+ cb.check()
+
+ p.opAsync().add_sent_callback(cb.sent)
+ cb.check()
+
+ cbs = []
+ if sys.version_info[0] == 2:
+ b = [chr(random.randint(0, 255)) for x in range(0, 1024)]
+ seq = ''.join(b)
+ else:
+ b = [random.randint(0, 255) for x in range(0, 1024)]
+ seq = bytes(b)
+ testController.holdAdapter()
+ try:
+ cb = FutureSentCallback()
+ while True:
+ f = p.opWithPayloadAsync(seq)
+ f.add_sent_callback(cb.sent)
+ cbs.append(cb)
+ if not f.sent_synchronously():
+ break
+ cb = FutureSentCallback()
+ except Exception as ex:
+ testController.resumeAdapter()
+ raise ex
+ testController.resumeAdapter()
+ for r in cbs:
+ r.check()
+
+ print("ok")
+
+ sys.stdout.write("testing batch requests with proxy... ")
+ sys.stdout.flush()
+
+ test(p.opBatchCount() == 0)
+ b1 = p.ice_batchOneway()
+ b1.opBatch()
+ b1.opBatch()
+ cb = FutureFlushCallback()
+ f = b1.ice_flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ test(f.is_sent())
+ test(f.done())
+ test(p.waitForBatch(2))
+
+ if p.ice_getConnection(): # No collocation optimization
+ test(p.opBatchCount() == 0)
+ b1 = p.ice_batchOneway()
+ b1.opBatch()
+ b1.ice_getConnection().close(False)
+ cb = FutureFlushCallback()
+ f = b1.ice_flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent())
+ test(f.done())
+ test(p.waitForBatch(1))
+
+ print("ok")
+
+ if p.ice_getConnection(): # No collocation optimization
+ sys.stdout.write("testing batch requests with connection... ")
+ sys.stdout.flush()
+
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b1.opBatch()
+ b1.opBatch()
+ cb = FutureFlushCallback()
+ f = b1.ice_getConnection().flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent())
+ test(f.done())
+ test(p.waitForBatch(2))
+
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b1.opBatch()
+ b1.ice_getConnection().close(False)
+ cb = FutureFlushExCallback()
+ f = b1.ice_getConnection().flushBatchRequestsAsync()
+ f.add_done_callback(cb.exception)
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ test(not f.is_sent())
+ test(f.done())
+ test(p.opBatchCount() == 0)
+
+ print("ok")
+
+ sys.stdout.write("testing batch requests with communicator... ")
+ sys.stdout.flush()
+
+ #
+ # 1 connection.
+ #
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b1.opBatch()
+ b1.opBatch()
+ cb = FutureFlushCallback()
+ f = communicator.flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent())
+ test(f.done())
+ test(p.waitForBatch(2))
+
+ #
+ # 1 connection.
+ #
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b1.opBatch()
+ b1.ice_getConnection().close(False)
+ cb = FutureFlushCallback()
+ f = communicator.flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent()) # Exceptions are ignored!
+ test(f.done())
+ test(p.opBatchCount() == 0)
+
+ #
+ # 2 connections.
+ #
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy(
+ p.ice_getIdentity()).ice_batchOneway())
+ b2.ice_getConnection() # Ensure connection is established.
+ b1.opBatch()
+ b1.opBatch()
+ b2.opBatch()
+ b2.opBatch()
+ cb = FutureFlushCallback()
+ f = communicator.flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent())
+ test(f.done())
+ test(p.waitForBatch(4))
+
+ #
+ # 2 connections - 1 failure.
+ #
+ # All connections should be flushed even if there are failures on some connections.
+ # Exceptions should not be reported.
+ #
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy(
+ p.ice_getIdentity()).ice_batchOneway())
+ b2.ice_getConnection() # Ensure connection is established.
+ b1.opBatch()
+ b2.opBatch()
+ b1.ice_getConnection().close(False)
+ cb = FutureFlushCallback()
+ f = communicator.flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent()) # Exceptions are ignored!
+ test(f.done())
+ test(p.waitForBatch(1))
+
+ #
+ # 2 connections - 2 failures.
+ #
+ # The sent callback should be invoked even if all connections fail.
+ #
+ test(p.opBatchCount() == 0)
+ b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway())
+ b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy(
+ p.ice_getIdentity()).ice_batchOneway())
+ b2.ice_getConnection() # Ensure connection is established.
+ b1.opBatch()
+ b2.opBatch()
+ b1.ice_getConnection().close(False)
+ b2.ice_getConnection().close(False)
+ cb = FutureFlushCallback()
+ f = communicator.flushBatchRequestsAsync()
+ f.add_sent_callback(cb.sent)
+ cb.check()
+ f.result() # Wait until finished.
+ test(f.is_sent()) # Exceptions are ignored!
+ test(f.done())
+ test(p.opBatchCount() == 0)
+
+ print("ok")
+
+ sys.stdout.write("testing future operations... ")
+ sys.stdout.flush()
+
+ indirect = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy"))
+ f = indirect.opAsync()
+ try:
+ f.result()
+ test(False)
+ except Ice.NoEndpointException:
+ pass
+
+ testController.holdAdapter()
+ f1 = None
+ f2 = None
+ try:
+ f1 = p.opAsync()
+ if sys.version_info[0] == 2:
+ b = [chr(random.randint(0, 255)) for x in range(0, 1024)]
+ seq = ''.join(b)
+ else:
+ b = [random.randint(0, 255) for x in range(0, 1024)]
+ seq = bytes(b)
+ while(True):
+ f2 = p.opWithPayloadAsync(seq)
+ if not f2.sent_synchronously():
+ break
+
+ test(f1 == f1)
+ test(f1 != f2)
+
+ if p.ice_getConnection():
+ test((f1.sent_synchronously() and f1.is_sent() and not f1.done()) or
+ (not f1.sent_synchronously() and not f1.done()))
+
+ test(not f2.sent_synchronously() and not f2.done())
+ except Exception as ex:
+ testController.resumeAdapter()
+ raise ex
+ testController.resumeAdapter()
+
+ f1.sent()
+ test(f1.is_sent())
+
+ f2.sent()
+ test(f2.is_sent())
+
+ f1.result()
+ test(f1.done())
+
+ f2.result()
+ test(f2.done())
+
+ test(f1.operation() == "op")
+ test(f2.operation() == "opWithPayload")
+
+ #
+ # Twoway
+ #
+ f = p.ice_pingAsync()
+ test(f.operation() == "ice_ping")
+ test(f.connection() == None) # Expected
+ test(f.communicator() == communicator)
+ test(f.proxy() == p)
+ f.result()
+
+ #
+ # Oneway
+ #
+ p2 = p.ice_oneway()
+ f = p2.ice_pingAsync()
+ test(f.operation() == "ice_ping")
+ test(f.connection() == None) # Expected
+ test(f.communicator() == communicator)
+ test(f.proxy() == p2)
+
+ #
+ # Batch request via proxy
+ #
+ p2 = p.ice_batchOneway()
+ p2.ice_ping()
+ f = p2.ice_flushBatchRequestsAsync()
+ test(f.connection() == None) # Expected
+ test(f.communicator() == communicator)
+ test(f.proxy() == p2)
+ f.result()
+
+ if p.ice_getConnection():
+ #
+ # Batch request via connection
+ #
+ con = p.ice_getConnection()
+ p2 = p.ice_batchOneway()
+ p2.ice_ping()
+ f = con.flushBatchRequestsAsync()
+ test(f.connection() == con)
+ test(f.communicator() == communicator)
+ test(f.proxy() == None) # Expected
+ f.result()
+
+ #
+ # Batch request via communicator
+ #
+ p2 = p.ice_batchOneway()
+ p2.ice_ping()
+ f = communicator.flushBatchRequestsAsync()
+ test(f.connection() == None) # Expected
+ test(f.communicator() == communicator)
+ test(f.proxy() == None) # Expected
+ f.result()
+
+ if(p.ice_getConnection()):
+ f1 = None
+ f2 = None
+
+ if sys.version_info[0] == 2:
+ b = [chr(random.randint(0, 255)) for x in range(0, 10024)]
+ seq = ''.join(b)
+ else:
+ b = [random.randint(0, 255) for x in range(0, 10024)]
+ seq = bytes(b)
+
+ testController.holdAdapter()
+
+ for x in range(0, 200): # 2MB
+ f = p.opWithPayloadAsync(seq)
+
+ test(not f.is_sent())
+
+ f1 = p.ice_pingAsync()
+ f2 = p.ice_idAsync()
+ f1.cancel()
+ f2.cancel()
+ try:
+ f1.result()
+ test(false)
+ except(Ice.InvocationCanceledException):
+ pass
+
+ try:
+ f2.result()
+ test(false)
+ except(Ice.InvocationCanceledException):
+ pass
+
+ testController.resumeAdapter()
+ p.ice_ping()
+ test(not f1.is_sent() and f1.done())
+ test(not f2.is_sent() and f2.done())
+
+ testController.holdAdapter()
+
+ f1 = p.opAsync()
+ f2 = p.ice_idAsync()
+ f1.sent()
+ f2.sent()
+ f1.cancel()
+ f2.cancel()
+ try:
+ f1.result()
+ test(false)
+ except:
+ pass
+ try:
+ f2.result()
+ test(false)
+ except:
+ pass
+ testController.resumeAdapter()
+
+ print("ok")
+
+ if p.ice_getConnection():
+ sys.stdout.write("testing close connection with sending queue... ")
+ sys.stdout.flush()
+
+ if sys.version_info[0] == 2:
+ b = [chr(random.randint(0, 255)) for x in range(0, 10*1024)]
+ seq = ''.join(b)
+ else:
+ b = [random.randint(0, 255) for x in range(0, 10*1024)]
+ seq = bytes(b)
+
+ #
+ # Send multiple opWithPayload, followed by a close and followed by multiple opWithPaylod.
+ # The goal is to make sure that none of the opWithPayload fail even if the server closes
+ # the connection gracefully in between.
+ #
+ maxQueue = 2
+ done = False
+ while not done and maxQueue < 50:
+ done = True
+ p.ice_ping()
+ results = []
+ for i in range(0, maxQueue):
+ results.append(p.opWithPayloadAsync(seq))
+ if not p.closeAsync(False).is_sent():
+ for i in range(0, maxQueue):
+ f = p.opWithPayloadAsync(seq)
+ results.append(f)
+ if f.is_sent():
+ done = False
+ maxQueue = maxQueue * 2
+ break
+ else:
+ maxQueue = maxQueue * 2
+ done = False
+ for f in results:
+ try:
+ f.result()
+ except Ice.LocalException:
+ test(False)
+
+ print("ok")
+
p.shutdown()
diff --git a/python/test/Ice/ami/Client.py b/python/test/Ice/ami/Client.py
index 0b2c5389137..f09179c2893 100755
--- a/python/test/Ice/ami/Client.py
+++ b/python/test/Ice/ami/Client.py
@@ -26,6 +26,7 @@ def test(b):
def run(args, communicator):
AllTests.allTests(communicator, False)
+ AllTests.allTestsFuture(communicator, False)
return True
try:
diff --git a/python/test/Ice/ami/TestI.py b/python/test/Ice/ami/TestI.py
index 53ee490ff71..f37bd47f806 100644
--- a/python/test/Ice/ami/TestI.py
+++ b/python/test/Ice/ami/TestI.py
@@ -27,30 +27,21 @@ class TestIntfI(Test.TestIntf):
pass
def opBatch(self, current=None):
- self._cond.acquire()
- try:
+ with self._cond:
self._batchCount += 1
self._cond.notify()
- finally:
- self._cond.release()
def opBatchCount(self, current=None):
- self._cond.acquire()
- try:
+ with self._cond:
return self._batchCount
- finally:
- self._cond.release()
def waitForBatch(self, count, current=None):
- self._cond.acquire()
- try:
+ with self._cond:
while self._batchCount < count:
self._cond.wait(5)
result = count == self._batchCount
self._batchCount = 0
return result
- finally:
- self._cond.release()
def close(self, force, current=None):
current.con.close(force)
diff --git a/python/test/Ice/binding/AllTests.py b/python/test/Ice/binding/AllTests.py
index 1517526688a..e7b46e4f727 100644
--- a/python/test/Ice/binding/AllTests.py
+++ b/python/test/Ice/binding/AllTests.py
@@ -18,30 +18,23 @@ class GetAdapterNameCB:
self._name = ""
self._cond = threading.Condition()
- def response(self, name):
- self._cond.acquire()
- self._name = name
- self._cond.notify()
- self._cond.release()
-
- def exception(self, ex):
- test(False)
+ def response(self, f):
+ with self._cond:
+ self._name = f.result()
+ self._cond.notify()
def getResult(self):
- self._cond.acquire()
- try:
+ with self._cond:
while self._name == "":
self._cond.wait(5.0)
if self._name != "":
return self._name
else:
return ""
- finally:
- self._cond.release()
def getAdapterNameWithAMI(proxy):
cb = GetAdapterNameCB()
- proxy.begin_getAdapterName(cb.response, cb.exception)
+ proxy.getAdapterNameAsync().add_done_callback(cb.response)
return cb.getResult()
def createTestIntfPrx(adapters):
diff --git a/python/test/Ice/blobject/RouterI.py b/python/test/Ice/blobject/RouterI.py
index d49d7153b48..7b07b36e1da 100644
--- a/python/test/Ice/blobject/RouterI.py
+++ b/python/test/Ice/blobject/RouterI.py
@@ -17,43 +17,29 @@ class CallQueue(threading.Thread):
self._destroy = False
def add(self, call):
- self._condVar.acquire()
- self._queue.append(call)
- self._condVar.notify()
- self._condVar.release()
+ with self._condVar:
+ self._queue.append(call)
+ self._condVar.notify()
def destroy(self):
- self._condVar.acquire()
- self._destroy = True
- self._condVar.notify()
- self._condVar.release()
+ with self._condVar:
+ self._destroy = True
+ self._condVar.notify()
def run(self):
while True:
- self._condVar.acquire()
- while len(self._queue) == 0 and not self._destroy:
- self._condVar.wait()
- if self._destroy:
- self._condVar.release()
- break
- call = self._queue.pop()
- self._condVar.release()
+ with self._condVar:
+ while len(self._queue) == 0 and not self._destroy:
+ self._condVar.wait()
+ if self._destroy:
+ break
+ call = self._queue.pop()
call.execute()
-class AsyncCallback(object):
- def __init__(self, cb):
- self._cb = cb
-
- def response(self, ok, results):
- self._cb.ice_response(ok, results)
-
- def exception(self, ex):
- self._cb.ice_exception(ex)
-
class BlobjectCall(object):
- def __init__(self, proxy, amdCallback, inParams, curr):
+ def __init__(self, proxy, future, inParams, curr):
self._proxy = proxy
- self._amdCallback = amdCallback
+ self._future = future
self._inParams = inParams
self._curr = curr
@@ -66,13 +52,19 @@ class BlobjectCall(object):
proxy = proxy.ice_oneway()
try:
ok, out = proxy.ice_invoke(self._curr.operation, self._curr.mode, self._inParams, self._curr.ctx)
- self._amdCallback.ice_response(ok, out)
+ self._future.set_result((ok, out))
except Ice.Exception as e:
- self._amdCallback.ice_exception(e)
+ self._future.set_exception(e)
else:
- cb = AsyncCallback(self._amdCallback)
- proxy.begin_ice_invoke(self._curr.operation, self._curr.mode, self._inParams, cb.response, cb.exception,
- None, self._curr.ctx)
+ f = proxy.ice_invokeAsync(self._curr.operation, self._curr.mode, self._inParams, self._curr.ctx)
+ f.add_done_callback(self.done)
+
+ def done(self, future):
+ try:
+ (ok, bytes) = future.result()
+ self._future.set_result((ok, bytes))
+ except Exception as ex:
+ self._future.set_exception(ex)
class BlobjectAsyncI(Ice.BlobjectAsync):
def __init__(self):
@@ -81,23 +73,22 @@ class BlobjectAsyncI(Ice.BlobjectAsync):
self._objects = {}
self._lock = threading.Lock()
- def ice_invoke_async(self, amdCallback, inParams, curr):
- self._lock.acquire()
- proxy = self._objects[curr.id]
- assert proxy
- self._lock.release()
- self._queue.add(BlobjectCall(proxy, amdCallback, inParams, curr))
+ def ice_invoke(self, inParams, curr):
+ f = Ice.Future()
+ with self._lock:
+ proxy = self._objects[curr.id]
+ assert proxy
+ self._queue.add(BlobjectCall(proxy, f, inParams, curr))
+ return f
def add(self, proxy):
- self._lock.acquire()
- self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None)
- self._lock.release()
+ with self._lock:
+ self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None)
def destroy(self):
- self._lock.acquire()
- self._queue.destroy()
- self._queue.join()
- self._lock.release()
+ with self._lock:
+ self._queue.destroy()
+ self._queue.join()
class BlobjectI(Ice.Blobject):
def __init__(self):
@@ -105,9 +96,8 @@ class BlobjectI(Ice.Blobject):
self._lock = threading.Lock()
def ice_invoke(self, inParams, curr):
- self._lock.acquire()
- proxy = self._objects[curr.id]
- self._lock.release()
+ with self._lock:
+ proxy = self._objects[curr.id]
if len(curr.facet) > 0:
proxy = proxy.ice_facet(curr.facet)
@@ -122,9 +112,8 @@ class BlobjectI(Ice.Blobject):
raise
def add(self, proxy):
- self._lock.acquire()
- self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None)
- self._lock.release()
+ with self._lock:
+ self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None)
def destroy(self):
pass
diff --git a/python/test/Ice/exceptions/AllTests.py b/python/test/Ice/exceptions/AllTests.py
index 0f660497980..3c13e06f24c 100644
--- a/python/test/Ice/exceptions/AllTests.py
+++ b/python/test/Ice/exceptions/AllTests.py
@@ -35,19 +35,15 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
def __init__(self, communicator=None):
@@ -598,6 +594,230 @@ def allTests(communicator):
print("ok")
+ sys.stdout.write("catching exact types with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower.throwAasAAsync(1).result()
+ test(False)
+ except Test.A as ex:
+ test(ex.aMem == 1)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwAorDasAorDAsync(1).result()
+ test(False)
+ except Test.A as ex:
+ test(ex.aMem == 1)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwAorDasAorDAsync(-1).result()
+ test(False)
+ except Test.D as ex:
+ test(ex.dMem == -1)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwBasBAsync(1, 2).result()
+ test(False)
+ except Test.B as ex:
+ test(ex.aMem == 1)
+ test(ex.bMem == 2)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwCasCAsync(1, 2, 3).result()
+ test(False)
+ except Test.C as ex:
+ test(ex.aMem == 1)
+ test(ex.bMem == 2)
+ test(ex.cMem == 3)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwModAAsync(1, 2).result()
+ test(False)
+ except Test.Mod.A as ex:
+ test(ex.aMem == 1)
+ test(ex.a2Mem == 2)
+ except Ice.OperationNotExistException:
+ #
+ # This operation is not supported in Java.
+ #
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching derived types with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower.throwBasAAsync(1, 2).result()
+ test(False)
+ except Test.B as ex:
+ test(ex.aMem == 1)
+ test(ex.bMem == 2)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwCasAAsync(1, 2, 3).result()
+ test(False)
+ except Test.C as ex:
+ test(ex.aMem == 1)
+ test(ex.bMem == 2)
+ test(ex.cMem == 3)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwCasBAsync(1, 2, 3).result()
+ test(False)
+ except Test.C as ex:
+ test(ex.aMem == 1)
+ test(ex.bMem == 2)
+ test(ex.cMem == 3)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ if thrower.supportsUndeclaredExceptions():
+ sys.stdout.write("catching unknown user exception with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower.throwUndeclaredAAsync(1).result()
+ test(False)
+ except Ice.UnknownUserException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwUndeclaredBAsync(1, 2).result()
+ test(False)
+ except Ice.UnknownUserException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ try:
+ thrower.throwUndeclaredCAsync(1, 2, 3).result()
+ test(False)
+ except Ice.UnknownUserException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching object not exist exception with futures... ")
+ sys.stdout.flush()
+
+ id = Ice.stringToIdentity("does not exist")
+ try:
+ thrower2 = Test.ThrowerPrx.uncheckedCast(thrower.ice_identity(id))
+ thrower2.throwAasAAsync(1).result()
+# thrower2.ice_ping()
+ test(False)
+ except Ice.ObjectNotExistException as ex:
+ test(ex.id == id)
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching facet not exist exception with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower2 = Test.ThrowerPrx.uncheckedCast(thrower, "no such facet")
+ try:
+ thrower2.ice_pingAsync().result()
+ test(False)
+ except Ice.FacetNotExistException as ex:
+ test(ex.facet == "no such facet")
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching operation not exist exception with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower2 = Test.WrongOperationPrx.uncheckedCast(thrower)
+ thrower2.noSuchOperationAsync().result()
+ test(False)
+ except Ice.OperationNotExistException as ex:
+ test(ex.operation == "noSuchOperation")
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching unknown local exception with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower.throwLocalExceptionAsync().result()
+ test(False)
+ except Ice.UnknownLocalException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+ try:
+ thrower.throwLocalExceptionIdempotentAsync().result()
+ test(False)
+ except Ice.UnknownLocalException:
+ pass
+ except Ice.OperationNotExistException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
+ sys.stdout.write("catching unknown non-Ice exception with futures... ")
+ sys.stdout.flush()
+
+ try:
+ thrower.throwNonIceExceptionAsync().result()
+ test(False)
+ except Ice.UnknownException:
+ pass
+ except:
+ print(sys.exc_info())
+ test(False)
+
+ print("ok")
+
sys.stdout.write("catching exact types with AMI mapping... ")
sys.stdout.flush()
diff --git a/python/test/Ice/exceptions/ServerAMD.py b/python/test/Ice/exceptions/ServerAMD.py
index ae11c454596..ef4511a383b 100755
--- a/python/test/Ice/exceptions/ServerAMD.py
+++ b/python/test/Ice/exceptions/ServerAMD.py
@@ -24,120 +24,131 @@ def test(b):
raise RuntimeError('test assertion failed')
class ThrowerI(Test.Thrower):
- def shutdown_async(self, cb, current=None):
+ def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
- def supportsUndeclaredExceptions_async(self, cb, current=None):
- cb.ice_response(True)
+ def supportsUndeclaredExceptions(self, current=None):
+ return True
- def supportsAssertException_async(self, cb, current=None):
- cb.ice_response(False)
+ def supportsAssertException(self, current=None):
+ return False
- def throwAasA_async(self, cb, a, current=None):
+ def throwAasA(self, a, current=None):
ex = Test.A()
ex.aMem = a
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwAorDasAorD_async(self, cb, a, current=None):
+ def throwAorDasAorD(self, a, current=None):
+ f = Ice.Future()
if a > 0:
ex = Test.A()
ex.aMem = a
- cb.ice_exception(ex)
+ f.set_exception(ex)
else:
ex = Test.D()
ex.dMem = a
- cb.ice_exception(ex)
+ f.set_exception(ex)
+ return f
- def throwBasA_async(self, cb, a, b, current=None):
+ def throwBasA(self, a, b, current=None):
ex = Test.B()
ex.aMem = a
ex.bMem = b
raise ex
- #cb.ice_exception(ex)
- def throwCasA_async(self, cb, a, b, c, current=None):
+ def throwCasA(self, a, b, c, current=None):
ex = Test.C()
ex.aMem = a
ex.bMem = b
ex.cMem = c
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwBasB_async(self, cb, a, b, current=None):
+ def throwBasB(self, a, b, current=None):
ex = Test.B()
ex.aMem = a
ex.bMem = b
raise ex
- #cb.ice_exception(ex)
- def throwCasB_async(self, cb, a, b, c, current=None):
+ def throwCasB(self, a, b, c, current=None):
ex = Test.C()
ex.aMem = a
ex.bMem = b
ex.cMem = c
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwCasC_async(self, cb, a, b, c, current=None):
+ def throwCasC(self, a, b, c, current=None):
ex = Test.C()
ex.aMem = a
ex.bMem = b
ex.cMem = c
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwModA_async(self, cb, a, a2, current=None):
+ def throwModA(self, a, a2, current=None):
ex = Test.Mod.A()
ex.aMem = a
ex.a2Mem = a2
raise ex
- def throwUndeclaredA_async(self, cb, a, current=None):
+ def throwUndeclaredA(self, a, current=None):
ex = Test.A()
ex.aMem = a
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwUndeclaredB_async(self, cb, a, b, current=None):
+ def throwUndeclaredB(self, a, b, current=None):
ex = Test.B()
ex.aMem = a
ex.bMem = b
raise ex
- #cb.ice_exception(ex)
- def throwUndeclaredC_async(self, cb, a, b, c, current=None):
+ def throwUndeclaredC(self, a, b, c, current=None):
ex = Test.C()
ex.aMem = a
ex.bMem = b
ex.cMem = c
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def throwLocalException_async(self, cb, current=None):
- cb.ice_exception(Ice.TimeoutException())
+ def throwLocalException(self, current=None):
+ f = Ice.Future()
+ f.set_exception(Ice.TimeoutException())
+ return f
- def throwNonIceException_async(self, cb, current=None):
- # Python-specific: make sure the argument is validated.
- try:
- cb.ice_exception('foo')
- test(False)
- except TypeError:
- pass
+ def throwNonIceException(self, current=None):
+ f = Ice.Future()
+ f.set_exception(RuntimeError("12345"))
+ return f
- cb.ice_exception(RuntimeError("12345"))
-
- def throwAssertException_async(self, cb, current=None):
+ def throwAssertException(self, current=None):
raise RuntimeError("operation `throwAssertException' not supported")
- def throwMemoryLimitException_async(self, cb, seq, current=None):
- cb.ice_response(bytearray(20 * 1024))
+ def throwMemoryLimitException(self, seq, current=None):
+ return Ice.Future.completed(bytearray(20 * 1024))
- def throwLocalExceptionIdempotent_async(self, cb, current=None):
- cb.ice_exception(Ice.TimeoutException())
+ def throwLocalExceptionIdempotent(self, current=None):
+ f = Ice.Future()
+ f.set_exception(Ice.TimeoutException())
+ return f
- def throwAfterResponse_async(self, cb, current=None):
- cb.ice_response()
- raise RuntimeError("12345")
+ def throwAfterResponse(self, current=None):
+ # Cannot be implemented with Futures
+ return None
- def throwAfterException_async(self, cb, current=None):
- cb.ice_exception(Test.A())
- raise RuntimeError("12345")
+ def throwAfterException(self, current=None):
+ # Cannot be implemented with Futures
+ f = Ice.Future()
+ f.set_exception(Test.A())
+ return f
def run(args, communicator):
adapter = communicator.createObjectAdapter("TestAdapter")
diff --git a/python/test/Ice/faultTolerance/AllTests.py b/python/test/Ice/faultTolerance/AllTests.py
index 94263cf1602..c55c3a138da 100644
--- a/python/test/Ice/faultTolerance/AllTests.py
+++ b/python/test/Ice/faultTolerance/AllTests.py
@@ -22,37 +22,32 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
- def response(self):
- test(False)
-
- def exception(self, ex):
- test(False)
-
- def opPidI(self, pid):
- self._pid = pid
- self.called()
+ def opPidI(self, f):
+ try:
+ self._pid = f.result()
+ self.called()
+ except:
+ test(False)
- def opShutdownI(self):
+ def opShutdownI(self, f):
+ test(f.exception() is None)
self.called()
- def exceptAbortI(self, ex):
+ def exceptAbortI(self, f):
+ test(f.exception() is not None)
try:
- raise ex
+ f.result()
except Ice.ConnectionLostException:
pass
except Ice.ConnectFailedException:
@@ -102,7 +97,7 @@ def allTests(communicator, ports):
sys.stdout.write("testing server #%d with AMI... " % i)
sys.stdout.flush()
cb = Callback()
- obj.begin_pid(cb.opPidI, cb.exception)
+ obj.pidAsync().add_done_callback(cb.opPidI)
cb.check()
pid = cb.pid()
test(pid != oldPid)
@@ -119,7 +114,7 @@ def allTests(communicator, ports):
sys.stdout.write("shutting down server #%d with AMI... " % i)
sys.stdout.flush()
cb = Callback()
- obj.begin_shutdown(cb.opShutdownI, cb.exception)
+ obj.shutdownAsync().add_done_callback(cb.opShutdownI)
cb.check()
print("ok")
elif j == 1 or i + 1 > len(ports):
@@ -137,7 +132,7 @@ def allTests(communicator, ports):
sys.stdout.write("aborting server #%d with AMI... " % i)
sys.stdout.flush()
cb = Callback()
- obj.begin_abort(cb.response, cb.exceptAbortI)
+ obj.abortAsync().add_done_callback(cb.exceptAbortI)
cb.check()
print("ok")
elif j == 2 or j == 3:
@@ -155,7 +150,7 @@ def allTests(communicator, ports):
sys.stdout.write("aborting server #%d and #%d with idempotent AMI call... " % (i, i + 1))
sys.stdout.flush()
cb = Callback()
- obj.begin_idempotentAbort(cb.response, cb.exceptAbortI)
+ obj.idempotentAbortAsync().add_done_callback(cb.exceptAbortI)
cb.check()
print("ok")
diff --git a/python/test/Ice/location/Server.py b/python/test/Ice/location/Server.py
index 24cd82df2d8..debd8d06d28 100755
--- a/python/test/Ice/location/Server.py
+++ b/python/test/Ice/location/Server.py
@@ -24,24 +24,24 @@ class ServerLocatorRegistry(Test.TestLocatorRegistry):
self._adapters = {}
self._objects = {}
- def setAdapterDirectProxy_async(self, cb, adapter, obj, current=None):
+ def setAdapterDirectProxy(self, adapter, obj, current=None):
if obj:
self._adapters[adapter] = obj
else:
self._adapters.pop(adapter)
- cb.ice_response()
+ return None
- def setReplicatedAdapterDirectProxy_async(self, cb, adapter, replica, obj, current=None):
+ def setReplicatedAdapterDirectProxy(self, adapter, replica, obj, current=None):
if obj:
self._adapters[adapter] = obj
self._adapters[replica] = obj
else:
self._adapters.pop(adapter)
self._adapters.pop(replica)
- cb.ice_response()
+ return None
- def setServerProcessProxy_async(self, id, proxy, current=None):
- cb.ice_response()
+ def setServerProcessProxy(self, id, proxy, current=None):
+ return None
def addObject(self, obj, current=None):
self._objects[obj.ice_getIdentity()] = obj
@@ -63,13 +63,13 @@ class ServerLocator(Test.TestLocator):
self._registryPrx = registryPrx
self._requestCount = 0
- def findObjectById_async(self, response, id, current=None):
+ def findObjectById(self, id, current=None):
self._requestCount += 1
- response.ice_response(self._registry.getObject(id))
+ return Ice.Future.completed(self._registry.getObject(id))
- def findAdapterById_async(self, response, id, current=None):
+ def findAdapterById(self, id, current=None):
self._requestCount += 1
- response.ice_response(self._registry.getAdapter(id))
+ return Ice.Future.completed(self._registry.getAdapter(id))
def getRegistry(self, current=None):
return self._registryPrx
diff --git a/python/test/Ice/objects/AllTests.py b/python/test/Ice/objects/AllTests.py
index bedb4d6c437..8f129218307 100644
--- a/python/test/Ice/objects/AllTests.py
+++ b/python/test/Ice/objects/AllTests.py
@@ -113,7 +113,7 @@ def allTests(communicator):
sys.stdout.write("getting D1... ")
sys.stdout.flush()
- d1 = initial.getD1(Test.D1(Test.A1("a1"), Test.A1("a2"), Test.A1("a3"), Test.A1("a4")));
+ d1 = initial.getD1(Test.D1(Test.A1("a1"), Test.A1("a2"), Test.A1("a3"), Test.A1("a4")))
test(d1.a1.name == "a1")
test(d1.a2.name == "a2")
test(d1.a3.name == "a3")
@@ -225,9 +225,9 @@ def allTests(communicator):
sys.stdout.write("testing marshaled results...")
sys.stdout.flush()
b1 = initial.getMB()
- test(b1 != None and b1.theB == b1);
- b1 = initial.end_getAMDMB(initial.begin_getAMDMB());
- test(b1 != None and b1.theB == b1);
+ test(b1 != None and b1.theB == b1)
+ b1 = initial.getAMDMBAsync().result()
+ test(b1 != None and b1.theB == b1)
print("ok")
# Don't run this test with collocation, this should work with collocation
diff --git a/python/test/Ice/objects/TestI.py b/python/test/Ice/objects/TestI.py
index 8b0df2c1594..7c0be3ae8dd 100644
--- a/python/test/Ice/objects/TestI.py
+++ b/python/test/Ice/objects/TestI.py
@@ -124,10 +124,10 @@ class InitialI(Test.Initial):
return self._f
def getMB(self, current):
- return self._b1;
+ return self._b1
- def getAMDMB_async(self, cb, current):
- cb.ice_response(self._b1);
+ def getAMDMB(self, current):
+ return Ice.Future.completed(self._b1)
def getAll(self, current=None):
self._b1.preMarshalInvoked = False
diff --git a/python/test/Ice/operations/AllTests.py b/python/test/Ice/operations/AllTests.py
index 02a6480de4c..27a70ab62e2 100644
--- a/python/test/Ice/operations/AllTests.py
+++ b/python/test/Ice/operations/AllTests.py
@@ -7,8 +7,8 @@
#
# **********************************************************************
-import Ice, Test, Twoways, TwowaysAMI, Oneways, OnewaysAMI, BatchOneways, sys
-import BatchOnewaysAMI
+import Ice, Test, Twoways, TwowaysFuture, TwowaysAMI, Oneways, OnewaysFuture, OnewaysAMI, BatchOneways, sys
+import BatchOnewaysAMI, BatchOnewaysFuture
def test(b):
if not b:
@@ -32,23 +32,39 @@ def allTests(communicator):
Oneways.oneways(communicator, cl)
print("ok")
+ sys.stdout.write("testing twoway operations with futures... ")
+ sys.stdout.flush()
+ TwowaysFuture.twowaysFuture(communicator, cl)
+ print("ok")
+
sys.stdout.write("testing twoway operations with AMI... ")
sys.stdout.flush()
TwowaysAMI.twowaysAMI(communicator, cl)
print("ok")
-
+
+ sys.stdout.write("testing oneway operations with futures... ")
+ sys.stdout.flush()
+ OnewaysFuture.onewaysFuture(communicator, cl)
+ print("ok")
+
sys.stdout.write("testing oneway operations with AMI... ")
sys.stdout.flush()
OnewaysAMI.onewaysAMI(communicator, cl)
print("ok")
-
+
sys.stdout.write("testing batch oneway operations... ")
sys.stdout.flush()
BatchOneways.batchOneways(cl)
BatchOneways.batchOneways(derived)
print("ok")
-
- sys.stdout.write("testing batch AMI oneway operations... ")
+
+ sys.stdout.write("testing batch oneway operations with futures... ")
+ sys.stdout.flush()
+ BatchOnewaysFuture.batchOneways(cl)
+ BatchOnewaysFuture.batchOneways(derived)
+ print("ok")
+
+ sys.stdout.write("testing batch oneway operations with AMI... ")
sys.stdout.flush()
BatchOnewaysAMI.batchOneways(cl)
BatchOnewaysAMI.batchOneways(derived)
diff --git a/python/test/Ice/operations/BatchOnewaysAMI.py b/python/test/Ice/operations/BatchOnewaysAMI.py
index 5515185d572..cd53ee94470 100644
--- a/python/test/Ice/operations/BatchOnewaysAMI.py
+++ b/python/test/Ice/operations/BatchOnewaysAMI.py
@@ -19,19 +19,15 @@ class Callback:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
def batchOneways(p):
diff --git a/python/test/Ice/operations/BatchOnewaysFuture.py b/python/test/Ice/operations/BatchOnewaysFuture.py
new file mode 100644
index 00000000000..e03bddbcfd0
--- /dev/null
+++ b/python/test/Ice/operations/BatchOnewaysFuture.py
@@ -0,0 +1,88 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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.
+#
+# **********************************************************************
+
+import Ice, Test, array, sys, threading, time
+
+def test(b):
+ if not b:
+ raise RuntimeError('test assertion failed')
+
+class Callback:
+ def __init__(self):
+ self._called = False
+ self._cond = threading.Condition()
+
+ def check(self):
+ with self._cond:
+ while not self._called:
+ self._cond.wait()
+ self._called = False
+
+ def called(self):
+ with self._cond:
+ self._called = True
+ self._cond.notify()
+
+def batchOneways(p):
+
+ if sys.version_info[0] == 2:
+ bs1 = []
+ bs1[0:10 * 1024] = range(0, 10 * 1024) # add 100,000 entries.
+ bs1 = ['\x00' for x in bs1] # set them all to \x00
+ bs1 = ''.join(bs1) # make into a byte array
+ else:
+ bs1 = bytes([0 for x in range(0, 10 * 1024)])
+ batch = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway())
+
+ f = batch.ice_flushBatchRequestsAsync() # Empty flush
+ f.result()
+
+ test(batch.ice_flushBatchRequestsAsync().is_sent()) # Empty flush
+ test(batch.ice_flushBatchRequestsAsync().done()) # Empty flush
+ test(batch.ice_flushBatchRequestsAsync().sent_synchronously()) # Empty flush
+
+ for i in range(30):
+ batch.opByteSOnewayAsync(bs1)
+
+ count = 0
+ while count < 27: # 3 * 9 requests auto-flushed.
+ count += p.opByteSOnewayCallCount()
+ time.sleep(0.01)
+
+ if p.ice_getConnection():
+
+ batch1 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway())
+ batch2 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway())
+
+ batch1.ice_pingAsync()
+ batch2.ice_pingAsync()
+ batch1.ice_flushBatchRequestsAsync().result()
+ batch1.ice_getConnection().close(False)
+ batch1.ice_pingAsync()
+ batch2.ice_pingAsync()
+
+ batch1.ice_getConnection()
+ batch2.ice_getConnection()
+
+ batch1.ice_getConnection().close(False)
+
+ test(not batch1.ice_pingAsync().done())
+ test(not batch2.ice_pingAsync().done())
+
+ identity = Ice.Identity()
+ identity.name = "invalid";
+ batch3 = batch.ice_identity(identity)
+ batch3.ice_ping()
+ batch3.ice_flushBatchRequestsAsync().result()
+
+ # Make sure that a bogus batch request doesn't cause troubles to other ones.
+ batch3.ice_ping()
+ batch.ice_ping()
+ batch.ice_flushBatchRequestsAsync().result()
+ batch.ice_ping()
diff --git a/python/test/Ice/operations/OnewaysAMI.py b/python/test/Ice/operations/OnewaysAMI.py
index e0e1fac0cca..4c08b60f52f 100644
--- a/python/test/Ice/operations/OnewaysAMI.py
+++ b/python/test/Ice/operations/OnewaysAMI.py
@@ -19,19 +19,15 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
def sent(self, sentSynchronously):
diff --git a/python/test/Ice/operations/OnewaysFuture.py b/python/test/Ice/operations/OnewaysFuture.py
new file mode 100644
index 00000000000..ea5e6f06b90
--- /dev/null
+++ b/python/test/Ice/operations/OnewaysFuture.py
@@ -0,0 +1,54 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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.
+#
+# **********************************************************************
+
+import Ice, Test
+
+def test(b):
+ if not b:
+ raise RuntimeError('test assertion failed')
+
+def onewaysFuture(communicator, proxy):
+
+ p = Test.MyClassPrx.uncheckedCast(proxy.ice_oneway())
+
+ f = p.ice_pingAsync()
+ f.sent()
+
+ try:
+ p.ice_isAAsync(Test.MyClass.ice_staticId())
+ test(False)
+ except RuntimeError:
+ pass
+
+ try:
+ p.ice_idAsync()
+ test(False)
+ except RuntimeError:
+ pass
+
+ try:
+ p.ice_idsAsync()
+ test(False)
+ except RuntimeError:
+ pass
+
+ f = p.opVoidAsync()
+ f.sent()
+
+ f = p.opIdempotentAsync()
+ f.sent()
+
+ f = p.opNonmutatingAsync()
+ f.sent()
+
+ try:
+ p.opByteAsync(0xff, 0x0f)
+ test(False)
+ except RuntimeError:
+ pass
diff --git a/python/test/Ice/operations/ServerAMD.py b/python/test/Ice/operations/ServerAMD.py
index 05777bad2d7..3204be386dc 100755
--- a/python/test/Ice/operations/ServerAMD.py
+++ b/python/test/Ice/operations/ServerAMD.py
@@ -8,7 +8,11 @@
#
# **********************************************************************
-import os, sys, traceback, threading
+import os, sys, traceback, threading, time
+
+haveConcurrentFuture = sys.version_info.major > 3 or (sys.version_info.major == 3 and sys.version_info.minor >= 5)
+if haveConcurrentFuture:
+ import concurrent.futures
import Ice
slice_dir = Ice.getSliceDir()
@@ -23,18 +27,20 @@ def test(b):
if not b:
raise RuntimeError('test assertion failed')
-class Thread_opVoid(threading.Thread):
- def __init__(self, cb):
+class FutureThread(threading.Thread):
+ def __init__(self, f, r):
threading.Thread.__init__(self)
- self.cb = cb
+ self.future = f
+ self.result = r
def run(self):
- self.cb.ice_response()
+ time.sleep(0.01)
+ self.future.set_result(self.result)
class MyDerivedClassI(Test.MyDerivedClass):
def __init__(self):
- self.opVoidThread = None
- self.opVoidThreadLock = threading.Lock()
+ self.threads = []
+ self.threadLock = threading.Lock()
self.lock = threading.Lock()
self.opByteSOnewayCount = 0
@@ -54,56 +60,63 @@ class MyDerivedClassI(Test.MyDerivedClass):
test(current.mode == Ice.OperationMode.Nonmutating)
return Test.MyDerivedClass.ice_id(self, current)
- def shutdown_async(self, cb, current=None):
- self.opVoidThreadLock.acquire()
- if self.opVoidThread:
- self.opVoidThread.join()
- self.opVoidThread = None
- self.opVoidThreadLock.release()
+ def shutdown(self, current=None):
+ with self.threadLock:
+ for thread in self.threads:
+ thread.join()
+ self.threads = []
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
- def opVoid_async(self, cb, current=None):
+ def opVoid(self, current=None):
test(current.mode == Ice.OperationMode.Normal)
- self.opVoidThreadLock.acquire()
- if self.opVoidThread:
- self.opVoidThread.join()
- self.opVoidThread = None
+ f = Ice.Future()
+
+ with self.threadLock:
+ thread = FutureThread(f, None)
+ self.threads.append(thread)
+ thread.start()
- self.opVoidThread = Thread_opVoid(cb)
- self.opVoidThread.start()
- self.opVoidThreadLock.release()
+ return f
- def opByte_async(self, cb, p1, p2, current=None):
- cb.ice_response(p1, p1 ^ p2)
+ def opByte(self, p1, p2, current=None):
+ # Test the ability to use another Future type
+ if haveConcurrentFuture:
+ f = concurrent.futures.Future()
+ with self.threadLock:
+ thread = FutureThread(f, (p1, p1 ^ p2))
+ self.threads.append(thread)
+ thread.start()
+ else:
+ f = Ice.Future.completed((p1, p1 ^ p2))
+ return f
- def opBool_async(self, cb, p1, p2, current=None):
- cb.ice_response(p2, p1)
+ def opBool(self, p1, p2, current=None):
+ return Ice.Future.completed((p2, p1))
- def opShortIntLong_async(self, cb, p1, p2, p3, current=None):
- cb.ice_response(p3, p1, p2, p3)
+ def opShortIntLong(self, p1, p2, p3, current=None):
+ return Ice.Future.completed((p3, p1, p2, p3))
- def opFloatDouble_async(self, cb, p1, p2, current=None):
- cb.ice_response(p2, p1, p2)
+ def opFloatDouble(self, p1, p2, current=None):
+ return Ice.Future.completed((p2, p1, p2))
- def opString_async(self, cb, p1, p2, current=None):
- cb.ice_response(p1 + " " + p2, p2 + " " + p1)
+ def opString(self, p1, p2, current=None):
+ return Ice.Future.completed((p1 + " " + p2, p2 + " " + p1))
- def opMyEnum_async(self, cb, p1, current=None):
- cb.ice_response(Test.MyEnum.enum3, p1)
+ def opMyEnum(self, p1, current=None):
+ return Ice.Future.completed((Test.MyEnum.enum3, p1))
- def opMyClass_async(self, cb, p1, current=None):
+ def opMyClass(self, p1, current=None):
p2 = p1
p3 = Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(Ice.stringToIdentity("noSuchIdentity")))
- cb.ice_response(Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)), p2, p3)
+ return Ice.Future.completed((Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)), p2, p3))
- def opStruct_async(self, cb, p1, p2, current=None):
+ def opStruct(self, p1, p2, current=None):
p1.s.s = "a new string"
- cb.ice_response(p2, p1)
+ return Ice.Future.completed((p2, p1))
- def opByteS_async(self, cb, p1, p2, current=None):
+ def opByteS(self, p1, p2, current=None):
if sys.version_info[0] == 2:
# By default sequence<byte> maps to a string.
p3 = map(ord, p1)
@@ -113,323 +126,322 @@ class MyDerivedClassI(Test.MyDerivedClass):
else:
p3 = bytes(reversed(p1))
r = p1 + p2
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opBoolS_async(self, cb, p1, p2, current=None):
+ def opBoolS(self, p1, p2, current=None):
p3 = p1[0:]
p3.extend(p2)
r = p1[0:]
r.reverse();
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opShortIntLongS_async(self, cb, p1, p2, p3, current=None):
+ def opShortIntLongS(self, p1, p2, p3, current=None):
p4 = p1[0:]
p5 = p2[0:]
p5.reverse()
p6 = p3[0:]
p6.extend(p3)
- cb.ice_response(p3, p4, p5, p6)
+ return Ice.Future.completed((p3, p4, p5, p6))
- def opFloatDoubleS_async(self, cb, p1, p2, current=None):
+ def opFloatDoubleS(self, p1, p2, current=None):
p3 = p1[0:]
p4 = p2[0:]
p4.reverse()
r = p2[0:]
r.extend(p1)
- cb.ice_response(r, p3, p4)
+ return Ice.Future.completed((r, p3, p4))
- def opStringS_async(self, cb, p1, p2, current=None):
+ def opStringS(self, p1, p2, current=None):
p3 = p1[0:]
p3.extend(p2)
r = p1[0:]
r.reverse()
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opByteSS_async(self, cb, p1, p2, current=None):
+ def opByteSS(self, p1, p2, current=None):
p3 = p1[0:]
p3.reverse()
r = p1[0:]
r.extend(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opBoolSS_async(self, cb, p1, p2, current=None):
+ def opBoolSS(self, p1, p2, current=None):
p3 = p1[0:]
p3.extend(p2)
r = p1[0:]
r.reverse()
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opShortIntLongSS_async(self, cb, p1, p2, p3, current=None):
+ def opShortIntLongSS(self, p1, p2, p3, current=None):
p4 = p1[0:]
p5 = p2[0:]
p5.reverse()
p6 = p3[0:]
p6.extend(p3)
- cb.ice_response(p3, p4, p5, p6)
+ return Ice.Future.completed((p3, p4, p5, p6))
- def opFloatDoubleSS_async(self, cb, p1, p2, current=None):
+ def opFloatDoubleSS(self, p1, p2, current=None):
p3 = p1[0:]
p4 = p2[0:]
p4.reverse()
r = p2[0:]
r.extend(p2)
- cb.ice_response(r, p3, p4)
+ return Ice.Future.completed((r, p3, p4))
- def opStringSS_async(self, cb, p1, p2, current=None):
+ def opStringSS(self, p1, p2, current=None):
p3 = p1[0:]
p3.extend(p2)
r = p2[0:]
r.reverse()
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringSSS_async(self, cb, p1, p2, current=None):
+ def opStringSSS(self, p1, p2, current=None):
p3 = p1[0:]
p3.extend(p2)
r = p2[0:]
r.reverse()
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opByteBoolD_async(self, cb, p1, p2, current=None):
+ def opByteBoolD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opShortIntD_async(self, cb, p1, p2, current=None):
+ def opShortIntD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opLongFloatD_async(self, cb, p1, p2, current=None):
+ def opLongFloatD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringStringD_async(self, cb, p1, p2, current=None):
+ def opStringStringD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringMyEnumD_async(self, cb, p1, p2, current=None):
+ def opStringMyEnumD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opMyEnumStringD_async(self, cb, p1, p2, current=None):
+ def opMyEnumStringD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opMyStructMyEnumD_async(self, cb, p1, p2, current=None):
+ def opMyStructMyEnumD(self, p1, p2, current=None):
p3 = p1.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opByteBoolDS_async(self, cb, p1, p2, current=None):
+ def opByteBoolDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opShortIntDS_async(self, cb, p1, p2, current=None):
+ def opShortIntDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opLongFloatDS_async(self, cb, p1, p2, current=None):
+ def opLongFloatDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringStringDS_async(self, cb, p1, p2, current=None):
+ def opStringStringDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringMyEnumDS_async(self, cb, p1, p2, current=None):
+ def opStringMyEnumDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opMyEnumStringDS_async(self, cb, p1, p2, current=None):
+ def opMyEnumStringDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opMyStructMyEnumDS_async(self, cb, p1, p2, current=None):
+ def opMyStructMyEnumDS(self, p1, p2, current=None):
p3 = p2[0:]
p3.extend(p1)
r = p1[::-1]
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opByteByteSD_async(self, cb, p1, p2, current=None):
+ def opByteByteSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opBoolBoolSD_async(self, cb, p1, p2, current=None):
+ def opBoolBoolSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opShortShortSD_async(self, cb, p1, p2, current=None):
+ def opShortShortSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opIntIntSD_async(self, cb, p1, p2, current=None):
+ def opIntIntSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opLongLongSD_async(self, cb, p1, p2, current=None):
+ def opLongLongSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringFloatSD_async(self, cb, p1, p2, current=None):
+ def opStringFloatSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringDoubleSD_async(self, cb, p1, p2, current=None):
+ def opStringDoubleSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opStringStringSD_async(self, cb, p1, p2, current=None):
+ def opStringStringSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opMyEnumMyEnumSD_async(self, cb, p1, p2, current=None):
+ def opMyEnumMyEnumSD(self, p1, p2, current=None):
p3 = p2.copy()
r = p1.copy()
r.update(p2)
- cb.ice_response(r, p3)
+ return Ice.Future.completed((r, p3))
- def opIntS_async(self, cb, s, current=None):
- cb.ice_response([-x for x in s])
+ def opIntS(self, s, current=None):
+ return Ice.Future.completed([-x for x in s])
- def opByteSOneway_async(self, cb, s, current=None):
- self.lock.acquire()
- self.opByteSOnewayCount += 1
- self.lock.release()
- cb.ice_response()
+ def opByteSOneway(self, s, current=None):
+ with self.lock:
+ self.opByteSOnewayCount += 1
+ return Ice.Future.completed(None)
- def opByteSOnewayCallCount_async(self, cb, current=None):
- self.lock.acquire()
- count = self.opByteSOnewayCount
- self.opByteSOnewayCount = 0
- self.lock.release()
- cb.ice_response(count)
+ def opByteSOnewayCallCount(self, current=None):
+ with self.lock:
+ count = self.opByteSOnewayCount
+ self.opByteSOnewayCount = 0
+ return Ice.Future.completed(count)
- def opDoubleMarshaling_async(self, cb, p1, p2, current=None):
+ def opDoubleMarshaling(self, p1, p2, current=None):
d = 1278312346.0 / 13.0;
test(p1 == d)
for i in p2:
test(i == d)
- cb.ice_response()
+ return Ice.Future.completed(None)
- def opContext_async(self, cb, current=None):
- cb.ice_response(current.ctx)
+ def opContext(self, current=None):
+ return Ice.Future.completed(current.ctx)
- def opIdempotent_async(self, cb, current=None):
+ def opIdempotent(self, current=None):
test(current.mode == Ice.OperationMode.Idempotent)
- cb.ice_response()
+ return Ice.Future.completed(None)
- def opNonmutating_async(self, cb, current=None):
+ def opNonmutating(self, current=None):
test(current.mode == Ice.OperationMode.Nonmutating)
- cb.ice_response()
+ return Ice.Future.completed(None)
- def opDerived_async(self, cb, current=None):
- cb.ice_response()
+ def opDerived(self, current=None):
+ return Ice.Future.completed(None)
- def opByte1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opByte1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opShort1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opShort1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opInt1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opInt1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opLong1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opLong1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opFloat1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opFloat1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opDouble1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opDouble1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opString1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opString1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opStringS1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opStringS1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opByteBoolD1_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opByteBoolD1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opStringS2_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opStringS2(self, value, current=None):
+ return Ice.Future.completed(value)
- def opByteBoolD2_async(self, cb, value, current=None):
- cb.ice_response(value)
+ def opByteBoolD2(self, value, current=None):
+ return Ice.Future.completed(value)
- def opMyClass1_async(self, cb, value, current=None):
- return cb.ice_response(value)
+ def opMyClass1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opMyStruct1_async(self, cb, value, current=None):
- return cb.ice_response(value)
+ def opMyStruct1(self, value, current=None):
+ return Ice.Future.completed(value)
- def opStringLiterals_async(self, cb, current=None):
- return cb.ice_response([
+ def opStringLiterals(self, current=None):
+ return Ice.Future.completed([
Test.s0, Test.s1, Test.s2, Test.s3, Test.s4, Test.s5, Test.s6, Test.s7, Test.s8, Test.s9, Test.s10,
- Test.sw0, Test.sw1, Test.sw2, Test.sw3, Test.sw4, Test.sw5, Test.sw6, Test.sw7, Test.sw8, Test.sw9, Test.sw10,
+ Test.sw0, Test.sw1, Test.sw2, Test.sw3, Test.sw4, Test.sw5, Test.sw6, Test.sw7, Test.sw8, Test.sw9,
+ Test.sw10,
Test.ss0, Test.ss1, Test.ss2, Test.ss3, Test.ss4, Test.ss5,
Test.su0, Test.su1, Test.su2])
- def opWStringLiterals_async(self, cb, current=None):
- return self.opStringLiterals_async(cb, current)
+ def opWStringLiterals(self, current=None):
+ return self.opStringLiterals(current)
- def opMStruct1_async(self, cb, current):
- cb.ice_response(Test.Structure())
+ def opMStruct1(self, current):
+ return Ice.Future.completed(Test.Structure())
- def opMStruct2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMStruct2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def opMSeq1_async(self, cb, current):
- cb.ice_response([])
+ def opMSeq1(self, current):
+ return Ice.Future.completed([])
- def opMSeq2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMSeq2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def opMDict1_async(self, cb, current):
- cb.ice_response({})
+ def opMDict1(self, current):
+ return Ice.Future.completed({})
- def opMDict2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMDict2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
def run(args, communicator):
communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp")
diff --git a/python/test/Ice/operations/TestI.py b/python/test/Ice/operations/TestI.py
index 2901b2796ae..87b1e0b21bc 100644
--- a/python/test/Ice/operations/TestI.py
+++ b/python/test/Ice/operations/TestI.py
@@ -294,15 +294,13 @@ class MyDerivedClassI(Test.MyDerivedClass):
return [-x for x in s]
def opByteSOneway(self, s, current=None):
- self.lock.acquire()
- self.opByteSOnewayCount += 1
- self.lock.release()
+ with self.lock:
+ self.opByteSOnewayCount += 1
def opByteSOnewayCallCount(self, current=None):
- self.lock.acquire()
- count = self.opByteSOnewayCount
- self.opByteSOnewayCount = 0
- self.lock.release()
+ with self.lock:
+ count = self.opByteSOnewayCount
+ self.opByteSOnewayCount = 0
return count
def opContext(self, current=None):
diff --git a/python/test/Ice/operations/TwowaysAMI.py b/python/test/Ice/operations/TwowaysAMI.py
index cb356b3177f..a1cbc7642d4 100644
--- a/python/test/Ice/operations/TwowaysAMI.py
+++ b/python/test/Ice/operations/TwowaysAMI.py
@@ -19,19 +19,15 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
def __init__(self, communicator=None):
diff --git a/python/test/Ice/operations/TwowaysFuture.py b/python/test/Ice/operations/TwowaysFuture.py
new file mode 100644
index 00000000000..45720916adc
--- /dev/null
+++ b/python/test/Ice/operations/TwowaysFuture.py
@@ -0,0 +1,1354 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2016 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.
+#
+# **********************************************************************
+
+import Ice, Test, math, sys, threading
+
+def test(b):
+ if not b:
+ raise RuntimeError('test assertion failed')
+
+class CallbackBase:
+ def __init__(self):
+ self._called = False
+ self._cond = threading.Condition()
+
+ def check(self):
+ with self._cond:
+ while not self._called:
+ self._cond.wait()
+ self._called = False
+
+ def called(self):
+ with self._cond:
+ self._called = True
+ self._cond.notify()
+
+class Callback(CallbackBase):
+ def __init__(self, communicator=None):
+ CallbackBase.__init__(self)
+ self._communicator = communicator
+
+ def opByte(self, f):
+ try:
+ (r, b) = f.result()
+ test(b == 0xf0)
+ test(r == 0xff)
+ self.called()
+ except:
+ test(False)
+
+ def opBool(self, f):
+ try:
+ (r, b) = f.result()
+ test(b)
+ test(not r)
+ self.called()
+ except:
+ test(False)
+
+ def opShortIntLong(self, f):
+ try:
+ (r, s, i, l) = f.result()
+ test(s == 10)
+ test(i == 11)
+ test(l == 12)
+ test(r == 12)
+ self.called()
+ except:
+ test(False)
+
+ def opFloatDouble(self, fut):
+ try:
+ (r, f, d) = fut.result()
+ test(f - 3.14 < 0.001)
+ test(d == 1.1E10)
+ test(r == 1.1E10)
+ self.called()
+ except:
+ test(False)
+
+ def opString(self, f):
+ try:
+ (r, s) = f.result()
+ test(s == "world hello")
+ test(r == "hello world")
+ self.called()
+ except:
+ test(False)
+
+ def opMyEnum(self, f):
+ try:
+ (r, e) = f.result()
+ test(e == Test.MyEnum.enum2)
+ test(r == Test.MyEnum.enum3)
+ self.called()
+ except:
+ test(False)
+
+ def opMyClass(self, f):
+ try:
+ (r, c1, c2) = f.result()
+ test(c1.ice_getIdentity() == Ice.stringToIdentity("test"))
+ test(c2.ice_getIdentity() == Ice.stringToIdentity("noSuchIdentity"))
+ test(r.ice_getIdentity() == Ice.stringToIdentity("test"))
+ # We can't do the callbacks below in serialize mode
+ if self._communicator.getProperties().getPropertyAsInt("Ice.Client.ThreadPool.Serialize") == 0:
+ r.opVoid()
+ c1.opVoid()
+ try:
+ c2.opVoid()
+ test(False)
+ except Ice.ObjectNotExistException:
+ pass
+ self.called()
+ except:
+ test(False)
+
+ def opStruct(self, f):
+ try:
+ (rso, so) = f.result()
+ test(rso.p == None)
+ test(rso.e == Test.MyEnum.enum2)
+ test(rso.s.s == "def")
+ test(so.e == Test.MyEnum.enum3)
+ test(so.s.s == "a new string")
+ # We can't do the callbacks below in serialize mode.
+ if self._communicator.getProperties().getPropertyAsInt("Ice.ThreadPool.Client.Serialize") == 0:
+ so.p.opVoid()
+ self.called()
+ except:
+ test(False)
+
+ def opByteS(self, f):
+ try:
+ (rso, bso) = f.result()
+ test(len(bso) == 4)
+ test(len(rso) == 8)
+ if sys.version_info[0] == 2:
+ test(bso[0] == '\x22')
+ test(bso[1] == '\x12')
+ test(bso[2] == '\x11')
+ test(bso[3] == '\x01')
+ test(rso[0] == '\x01')
+ test(rso[1] == '\x11')
+ test(rso[2] == '\x12')
+ test(rso[3] == '\x22')
+ test(rso[4] == '\xf1')
+ test(rso[5] == '\xf2')
+ test(rso[6] == '\xf3')
+ test(rso[7] == '\xf4')
+ else:
+ test(bso[0] == 0x22)
+ test(bso[1] == 0x12)
+ test(bso[2] == 0x11)
+ test(bso[3] == 0x01)
+ test(rso[0] == 0x01)
+ test(rso[1] == 0x11)
+ test(rso[2] == 0x12)
+ test(rso[3] == 0x22)
+ test(rso[4] == 0xf1)
+ test(rso[5] == 0xf2)
+ test(rso[6] == 0xf3)
+ test(rso[7] == 0xf4)
+ self.called()
+ except:
+ test(False)
+
+ def opBoolS(self, f):
+ try:
+ (rso, bso) = f.result()
+ test(len(bso) == 4)
+ test(bso[0])
+ test(bso[1])
+ test(not bso[2])
+ test(not bso[3])
+ test(len(rso) == 3)
+ test(not rso[0])
+ test(rso[1])
+ test(rso[2])
+ self.called()
+ except:
+ test(False)
+
+ def opShortIntLongS(self, f):
+ try:
+ (rso, sso, iso, lso) = f.result()
+ test(len(sso) == 3)
+ test(sso[0] == 1)
+ test(sso[1] == 2)
+ test(sso[2] == 3)
+ test(len(iso) == 4)
+ test(iso[0] == 8)
+ test(iso[1] == 7)
+ test(iso[2] == 6)
+ test(iso[3] == 5)
+ test(len(lso) == 6)
+ test(lso[0] == 10)
+ test(lso[1] == 30)
+ test(lso[2] == 20)
+ test(lso[3] == 10)
+ test(lso[4] == 30)
+ test(lso[5] == 20)
+ test(len(rso) == 3)
+ test(rso[0] == 10)
+ test(rso[1] == 30)
+ test(rso[2] == 20)
+ self.called()
+ except:
+ test(False)
+
+ def opFloatDoubleS(self, f):
+ try:
+ (rso, fso, dso) = f.result()
+ test(len(fso) == 2)
+ test(fso[0] - 3.14 < 0.001)
+ test(fso[1] - 1.11 < 0.001)
+ test(len(dso) == 3)
+ test(dso[0] == 1.3E10)
+ test(dso[1] == 1.2E10)
+ test(dso[2] == 1.1E10)
+ test(len(rso) == 5)
+ test(rso[0] == 1.1E10)
+ test(rso[1] == 1.2E10)
+ test(rso[2] == 1.3E10)
+ test(rso[3] - 3.14 < 0.001)
+ test(rso[4] - 1.11 < 0.001)
+ self.called()
+ except:
+ test(False)
+
+ def opStringS(self, f):
+ try:
+ (rso, sso) = f.result()
+ test(len(sso) == 4)
+ test(sso[0] == "abc")
+ test(sso[1] == "de")
+ test(sso[2] == "fghi")
+ test(sso[3] == "xyz")
+ test(len(rso) == 3)
+ test(rso[0] == "fghi")
+ test(rso[1] == "de")
+ test(rso[2] == "abc")
+ self.called()
+ except:
+ test(False)
+
+ def opByteSS(self, f):
+ try:
+ (rso, bso) = f.result()
+ test(len(bso) == 2)
+ test(len(bso[0]) == 1)
+ test(len(bso[1]) == 3)
+ test(len(rso) == 4)
+ test(len(rso[0]) == 3)
+ test(len(rso[1]) == 1)
+ test(len(rso[2]) == 1)
+ test(len(rso[3]) == 2)
+ if sys.version_info[0] == 2:
+ test(bso[0][0] == '\xff')
+ test(bso[1][0] == '\x01')
+ test(bso[1][1] == '\x11')
+ test(bso[1][2] == '\x12')
+ test(rso[0][0] == '\x01')
+ test(rso[0][1] == '\x11')
+ test(rso[0][2] == '\x12')
+ test(rso[1][0] == '\xff')
+ test(rso[2][0] == '\x0e')
+ test(rso[3][0] == '\xf2')
+ test(rso[3][1] == '\xf1')
+ else:
+ test(bso[0][0] == 0xff)
+ test(bso[1][0] == 0x01)
+ test(bso[1][1] == 0x11)
+ test(bso[1][2] == 0x12)
+ test(rso[0][0] == 0x01)
+ test(rso[0][1] == 0x11)
+ test(rso[0][2] == 0x12)
+ test(rso[1][0] == 0xff)
+ test(rso[2][0] == 0x0e)
+ test(rso[3][0] == 0xf2)
+ test(rso[3][1] == 0xf1)
+ self.called()
+ except:
+ test(False)
+
+ def opBoolSS(self, f):
+ try:
+ (rso, bso) = f.result()
+ test(len(bso) == 4);
+ test(len(bso[0]) == 1);
+ test(bso[0][0]);
+ test(len(bso[1]) == 1);
+ test(not bso[1][0]);
+ test(len(bso[2]) == 2);
+ test(bso[2][0]);
+ test(bso[2][1]);
+ test(len(bso[3]) == 3);
+ test(not bso[3][0]);
+ test(not bso[3][1]);
+ test(bso[3][2]);
+ test(len(rso) == 3);
+ test(len(rso[0]) == 2);
+ test(rso[0][0]);
+ test(rso[0][1]);
+ test(len(rso[1]) == 1);
+ test(not rso[1][0]);
+ test(len(rso[2]) == 1);
+ test(rso[2][0]);
+ self.called();
+ except:
+ test(False)
+
+ def opShortIntLongSS(self, f):
+ try:
+ (rso, sso, iso, lso) = f.result()
+ test(len(rso) == 1);
+ test(len(rso[0]) == 2);
+ test(rso[0][0] == 496);
+ test(rso[0][1] == 1729);
+ test(len(sso) == 3);
+ test(len(sso[0]) == 3);
+ test(sso[0][0] == 1);
+ test(sso[0][1] == 2);
+ test(sso[0][2] == 5);
+ test(len(sso[1]) == 1);
+ test(sso[1][0] == 13);
+ test(len(sso[2]) == 0);
+ test(len(iso) == 2);
+ test(len(iso[0]) == 1);
+ test(iso[0][0] == 42);
+ test(len(iso[1]) == 2);
+ test(iso[1][0] == 24);
+ test(iso[1][1] == 98);
+ test(len(lso) == 2);
+ test(len(lso[0]) == 2);
+ test(lso[0][0] == 496);
+ test(lso[0][1] == 1729);
+ test(len(lso[1]) == 2);
+ test(lso[1][0] == 496);
+ test(lso[1][1] == 1729);
+ self.called();
+ except:
+ test(False)
+
+ def opFloatDoubleSS(self, f):
+ try:
+ (rso, fso, dso) = f.result()
+ test(len(fso) == 3)
+ test(len(fso[0]) == 1)
+ test(fso[0][0] - 3.14 < 0.001)
+ test(len(fso[1]) == 1)
+ test(fso[1][0] - 1.11 < 0.001)
+ test(len(fso[2]) == 0)
+ test(len(dso) == 1)
+ test(len(dso[0]) == 3)
+ test(dso[0][0] == 1.1E10)
+ test(dso[0][1] == 1.2E10)
+ test(dso[0][2] == 1.3E10)
+ test(len(rso) == 2)
+ test(len(rso[0]) == 3)
+ test(rso[0][0] == 1.1E10)
+ test(rso[0][1] == 1.2E10)
+ test(rso[0][2] == 1.3E10)
+ test(len(rso[1]) == 3)
+ test(rso[1][0] == 1.1E10)
+ test(rso[1][1] == 1.2E10)
+ test(rso[1][2] == 1.3E10)
+ self.called()
+ except:
+ test(False)
+
+ def opStringSS(self, f):
+ try:
+ (rso, sso) = f.result()
+ test(len(sso) == 5)
+ test(len(sso[0]) == 1)
+ test(sso[0][0] == "abc")
+ test(len(sso[1]) == 2)
+ test(sso[1][0] == "de")
+ test(sso[1][1] == "fghi")
+ test(len(sso[2]) == 0)
+ test(len(sso[3]) == 0)
+ test(len(sso[4]) == 1)
+ test(sso[4][0] == "xyz")
+ test(len(rso) == 3)
+ test(len(rso[0]) == 1)
+ test(rso[0][0] == "xyz")
+ test(len(rso[1]) == 0)
+ test(len(rso[2]) == 0)
+ self.called()
+ except:
+ test(False)
+
+ def opByteBoolD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {10: True, 100: False}
+ test(do == di1)
+ test(len(ro) == 4)
+ test(ro[10])
+ test(not ro[11])
+ test(not ro[100])
+ test(ro[101])
+ self.called()
+ except:
+ test(False)
+
+ def opShortIntD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {110: -1, 1100: 123123}
+ test(do == di1)
+ test(len(ro) == 4)
+ test(ro[110] == -1)
+ test(ro[111] == -100)
+ test(ro[1100] == 123123)
+ test(ro[1101] == 0)
+ self.called()
+ except:
+ test(False)
+
+ def opLongFloatD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {999999110: -1.1, 999999111: 123123.2}
+ for k in do:
+ test(math.fabs(do[k] - di1[k]) < 0.01)
+ test(len(ro) == 4)
+ test(ro[999999110] - -1.1 < 0.01)
+ test(ro[999999120] - -100.4 < 0.01)
+ test(ro[999999111] - 123123.2 < 0.01)
+ test(ro[999999130] - 0.5 < 0.01)
+ self.called()
+ except:
+ test(False)
+
+ def opStringStringD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {'foo': 'abc -1.1', 'bar': 'abc 123123.2'}
+ test(do == di1)
+ test(len(ro) == 4)
+ test(ro["foo"] == "abc -1.1")
+ test(ro["FOO"] == "abc -100.4")
+ test(ro["bar"] == "abc 123123.2")
+ test(ro["BAR"] == "abc 0.5")
+ self.called()
+ except:
+ test(False)
+
+ def opStringMyEnumD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {'abc': Test.MyEnum.enum1, '': Test.MyEnum.enum2}
+ test(do == di1)
+ test(len(ro) == 4)
+ test(ro["abc"] == Test.MyEnum.enum1)
+ test(ro["qwerty"] == Test.MyEnum.enum3)
+ test(ro[""] == Test.MyEnum.enum2)
+ test(ro["Hello!!"] == Test.MyEnum.enum2)
+ self.called()
+ except:
+ test(False)
+
+ def opMyEnumStringD(self, f):
+ try:
+ (ro, do) = f.result()
+ di1 = {Test.MyEnum.enum1: 'abc'}
+ test(do == di1)
+ test(len(ro) == 3)
+ test(ro[Test.MyEnum.enum1] == "abc")
+ test(ro[Test.MyEnum.enum2] == "Hello!!")
+ test(ro[Test.MyEnum.enum3] == "qwerty")
+ self.called()
+ except:
+ test(False)
+
+ def opMyStructMyEnumD(self, f):
+ try:
+ (ro, do) = f.result()
+ s11 = Test.MyStruct()
+ s11.i = 1
+ s11.j = 1
+ s12 = Test.MyStruct()
+ s12.i = 1
+ s12.j = 2
+ s22 = Test.MyStruct()
+ s22.i = 2
+ s22.j = 2
+ s23 = Test.MyStruct()
+ s23.i = 2
+ s23.j = 3
+ di1 = {s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2}
+ test(do == di1)
+ test(len(ro) == 4)
+ test(ro[s11] == Test.MyEnum.enum1)
+ test(ro[s12] == Test.MyEnum.enum2)
+ test(ro[s22] == Test.MyEnum.enum3)
+ test(ro[s23] == Test.MyEnum.enum2)
+ self.called()
+ except:
+ test(False)
+
+ def opByteBoolDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0][10])
+ test(not ro[0][11])
+ test(ro[0][101])
+ test(len(ro[1]) == 2)
+ test(ro[1][10])
+ test(not ro[1][100])
+ test(len(do) == 3)
+ test(len(do[0]) == 2)
+ test(not do[0][100])
+ test(not do[0][101])
+ test(len(do[1]) == 2)
+ test(do[1][10])
+ test(not do[1][100])
+ test(len(do[2]) == 3)
+ test(do[2][10])
+ test(not do[2][11])
+ test(do[2][101])
+ self.called()
+ except:
+ test(False)
+
+ def opShortIntDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0][110] == -1)
+ test(ro[0][111] == -100)
+ test(ro[0][1101] == 0)
+ test(len(ro[1]) == 2)
+ test(ro[1][110] == -1)
+ test(ro[1][1100] == 123123)
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0][100] == -1001)
+ test(len(do[1]) == 2)
+ test(do[1][110] == -1)
+ test(do[1][1100] == 123123)
+ test(len(do[2]) == 3)
+ test(do[2][110] == -1)
+ test(do[2][111] == -100)
+ test(do[2][1101] == 0)
+ self.called()
+ except:
+ test(False)
+
+ def opLongFloatDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0][999999110] - -1.1 < 0.01)
+ test(ro[0][999999120] - -100.4 < 0.01)
+ test(ro[0][999999130] - 0.5 < 0.01)
+ test(len(ro[1]) == 2)
+ test(ro[1][999999110] - -1.1 < 0.01)
+ test(ro[1][999999111] - 123123.2 < 0.01)
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0][999999140] - 3.14 < 0.01)
+ test(len(do[1]) == 2)
+ test(do[1][999999110] - -1.1 < 0.01)
+ test(do[1][999999111] - 123123.2 < 0.01)
+ test(len(do[2]) == 3)
+ test(do[2][999999110] - -1.1 < 0.01)
+ test(do[2][999999120] - -100.4 < 0.01)
+ test(do[2][999999130] - 0.5 < 0.01)
+ self.called()
+ except:
+ test(False)
+
+ def opStringStringDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0]["foo"] == "abc -1.1")
+ test(ro[0]["FOO"] == "abc -100.4")
+ test(ro[0]["BAR"] == "abc 0.5")
+ test(len(ro[1]) == 2)
+ test(ro[1]["foo"] == "abc -1.1")
+ test(ro[1]["bar"] == "abc 123123.2")
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0]["f00"] == "ABC -3.14")
+ test(len(do[1]) == 2)
+ test(do[1]["foo"] == "abc -1.1")
+ test(do[1]["bar"] == "abc 123123.2")
+ test(len(do[2]) == 3)
+ test(do[2]["foo"] == "abc -1.1")
+ test(do[2]["FOO"] == "abc -100.4")
+ test(do[2]["BAR"] == "abc 0.5")
+ self.called()
+ except:
+ test(False)
+
+ def opStringMyEnumDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0]["abc"] == Test.MyEnum.enum1)
+ test(ro[0]["qwerty"] == Test.MyEnum.enum3)
+ test(ro[0]["Hello!!"] == Test.MyEnum.enum2)
+ test(len(ro[1]) == 2)
+ test(ro[1]["abc"] == Test.MyEnum.enum1)
+ test(ro[1][""] == Test.MyEnum.enum2)
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0]["Goodbye"] == Test.MyEnum.enum1)
+ test(len(do[1]) == 2)
+ test(do[1]["abc"] == Test.MyEnum.enum1)
+ test(do[1][""] == Test.MyEnum.enum2)
+ test(len(do[2]) == 3)
+ test(do[2]["abc"] == Test.MyEnum.enum1)
+ test(do[2]["qwerty"] == Test.MyEnum.enum3)
+ test(do[2]["Hello!!"] == Test.MyEnum.enum2)
+ self.called()
+ except:
+ test(False)
+
+ def opMyEnumStringDS(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(ro) == 2)
+ test(len(ro[0]) == 2)
+ test(ro[0][Test.MyEnum.enum2] == "Hello!!")
+ test(ro[0][Test.MyEnum.enum3] == "qwerty")
+ test(len(ro[1]) == 1)
+ test(ro[1][Test.MyEnum.enum1] == "abc")
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0][Test.MyEnum.enum1] == "Goodbye")
+ test(len(do[1]) == 1)
+ test(do[1][Test.MyEnum.enum1] == "abc")
+ test(len(do[2]) == 2)
+ test(do[2][Test.MyEnum.enum2] == "Hello!!")
+ test(do[2][Test.MyEnum.enum3] == "qwerty")
+ self.called()
+ except:
+ test(False)
+
+ def opMyStructMyEnumDS(self, f):
+ try:
+ (ro, do) = f.result()
+ s11 = Test.MyStruct(1, 1)
+ s12 = Test.MyStruct(1, 2)
+ s22 = Test.MyStruct(2, 2)
+ s23 = Test.MyStruct(2, 3)
+ test(len(ro) == 2)
+ test(len(ro[0]) == 3)
+ test(ro[0][s11] == Test.MyEnum.enum1)
+ test(ro[0][s22] == Test.MyEnum.enum3)
+ test(ro[0][s23] == Test.MyEnum.enum2)
+ test(len(ro[1]) == 2)
+ test(ro[1][s11] == Test.MyEnum.enum1)
+ test(ro[1][s12] == Test.MyEnum.enum2)
+ test(len(do) == 3)
+ test(len(do[0]) == 1)
+ test(do[0][s23] == Test.MyEnum.enum3)
+ test(len(do[1]) == 2)
+ test(do[1][s11] == Test.MyEnum.enum1)
+ test(do[1][s12] == Test.MyEnum.enum2)
+ test(len(do[2]) == 3)
+ test(do[2][s11] == Test.MyEnum.enum1)
+ test(do[2][s22] == Test.MyEnum.enum3)
+ test(do[2][s23] == Test.MyEnum.enum2)
+ self.called()
+ except:
+ test(False)
+
+ def opByteByteSD(self, f):
+ try:
+ (ro, do) = f.result()
+ if sys.version_info[0] == 2:
+ test(len(do) == 1)
+ test(len(do[0xf1]) == 2)
+ test(do[0xf1][0] == '\xf2')
+ test(do[0xf1][1] == '\xf3')
+ test(len(ro) == 3)
+ test(len(ro[0x01]) == 2)
+ test(ro[0x01][0] == '\x01')
+ test(ro[0x01][1] == '\x11')
+ test(len(ro[0x22]) == 1)
+ test(ro[0x22][0] == '\x12')
+ test(len(ro[0xf1]) == 2)
+ test(ro[0xf1][0] == '\xf2')
+ test(ro[0xf1][1] == '\xf3')
+ else:
+ test(len(do) == 1)
+ test(len(do[0xf1]) == 2)
+ test(do[0xf1][0] == 0xf2)
+ test(do[0xf1][1] == 0xf3)
+ test(len(ro) == 3)
+ test(len(ro[0x01]) == 2)
+ test(ro[0x01][0] == 0x01)
+ test(ro[0x01][1] == 0x11)
+ test(len(ro[0x22]) == 1)
+ test(ro[0x22][0] == 0x12)
+ test(len(ro[0xf1]) == 2)
+ test(ro[0xf1][0] == 0xf2)
+ test(ro[0xf1][1] == 0xf3)
+ self.called()
+ except:
+ test(False)
+
+ def opBoolBoolSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[False]) == 2)
+ test(do[False][0])
+ test(not do[False][1])
+ test(len(ro) == 2)
+ test(len(ro[False]) == 2)
+ test(ro[False][0])
+ test(not ro[False][1])
+ test(len(ro[True]) == 3)
+ test(not ro[True][0])
+ test(ro[True][1])
+ test(ro[True][2])
+ self.called()
+ except:
+ test(False)
+
+ def opShortShortSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[4]) == 2)
+ test(do[4][0] == 6)
+ test(do[4][1] == 7)
+ test(len(ro) == 3)
+ test(len(ro[1]) == 3)
+ test(ro[1][0] == 1)
+ test(ro[1][1] == 2)
+ test(ro[1][2] == 3)
+ test(len(ro[2]) == 2)
+ test(ro[2][0] == 4)
+ test(ro[2][1] == 5)
+ test(len(ro[4]) == 2)
+ test(ro[4][0] == 6)
+ test(ro[4][1] == 7)
+ self.called()
+ except:
+ test(False)
+
+ def opIntIntSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[400]) == 2)
+ test(do[400][0] == 600)
+ test(do[400][1] == 700)
+ test(len(ro) == 3)
+ test(len(ro[100]) == 3)
+ test(ro[100][0] == 100)
+ test(ro[100][1] == 200)
+ test(ro[100][2] == 300)
+ test(len(ro[200]) == 2)
+ test(ro[200][0] == 400)
+ test(ro[200][1] == 500)
+ test(len(ro[400]) == 2)
+ test(ro[400][0] == 600)
+ test(ro[400][1] == 700)
+ self.called()
+ except:
+ test(False)
+
+ def opLongLongSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[999999992]) == 2)
+ test(do[999999992][0] == 999999110)
+ test(do[999999992][1] == 999999120)
+ test(len(ro) == 3)
+ test(len(ro[999999990]) == 3)
+ test(ro[999999990][0] == 999999110)
+ test(ro[999999990][1] == 999999111)
+ test(ro[999999990][2] == 999999110)
+ test(len(ro[999999991]) == 2)
+ test(ro[999999991][0] == 999999120)
+ test(ro[999999991][1] == 999999130)
+ test(len(ro[999999992]) == 2)
+ test(ro[999999992][0] == 999999110)
+ test(ro[999999992][1] == 999999120)
+ self.called()
+ except:
+ test(False)
+
+ def opStringFloatSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do["aBc"]) == 2)
+ test(do["aBc"][0] - -3.14 < 0.10)
+ test(do["aBc"][1] - 3.14 < 0.10)
+ test(len(ro) == 3)
+ test(len(ro["abc"]) == 3)
+ test(ro["abc"][0] - -1.1 < 0.10)
+ test(ro["abc"][1] - 123123.2 < 0.10)
+ test(ro["abc"][2] - 100.0 < 0.10)
+ test(len(ro["ABC"]) == 2)
+ test(ro["ABC"][0] - 42.24 < 0.10)
+ test(ro["ABC"][1] - -1.61 < 0.10)
+ test(len(ro["aBc"]) == 2)
+ test(ro["aBc"][0] - -3.14 < 0.10)
+ test(ro["aBc"][1] - 3.14 < 0.10)
+ self.called()
+ except:
+ test(False)
+
+ def opStringDoubleSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[""]) == 2)
+ test(do[""][0] == 1.6E10)
+ test(do[""][1] == 1.7E10)
+ test(len(ro) == 3)
+ test(len(ro["Hello!!"]) == 3)
+ test(ro["Hello!!"][0] == 1.1E10)
+ test(ro["Hello!!"][1] == 1.2E10)
+ test(ro["Hello!!"][2] == 1.3E10)
+ test(len(ro["Goodbye"]) == 2)
+ test(ro["Goodbye"][0] == 1.4E10)
+ test(ro["Goodbye"][1] == 1.5E10)
+ test(len(ro[""]) == 2)
+ test(ro[""][0] == 1.6E10)
+ test(ro[""][1] == 1.7E10)
+ self.called()
+ except:
+ test(False)
+
+ def opStringStringSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do["ghi"]) == 2)
+ test(do["ghi"][0] == "and")
+ test(do["ghi"][1] == "xor")
+ test(len(ro) == 3)
+ test(len(ro["abc"]) == 3)
+ test(ro["abc"][0] == "abc")
+ test(ro["abc"][1] == "de")
+ test(ro["abc"][2] == "fghi")
+ test(len(ro["def"]) == 2)
+ test(ro["def"][0] == "xyz")
+ test(ro["def"][1] == "or")
+ test(len(ro["ghi"]) == 2)
+ test(ro["ghi"][0] == "and")
+ test(ro["ghi"][1] == "xor")
+ self.called()
+ except:
+ test(False)
+
+ def opMyEnumMyEnumSD(self, f):
+ try:
+ (ro, do) = f.result()
+ test(len(do) == 1)
+ test(len(do[Test.MyEnum.enum1]) == 2)
+ test(do[Test.MyEnum.enum1][0] == Test.MyEnum.enum3)
+ test(do[Test.MyEnum.enum1][1] == Test.MyEnum.enum3)
+ test(len(ro) == 3)
+ test(len(ro[Test.MyEnum.enum3]) == 3)
+ test(ro[Test.MyEnum.enum3][0] == Test.MyEnum.enum1)
+ test(ro[Test.MyEnum.enum3][1] == Test.MyEnum.enum1)
+ test(ro[Test.MyEnum.enum3][2] == Test.MyEnum.enum2)
+ test(len(ro[Test.MyEnum.enum2]) == 2)
+ test(ro[Test.MyEnum.enum2][0] == Test.MyEnum.enum1)
+ test(ro[Test.MyEnum.enum2][1] == Test.MyEnum.enum2)
+ test(len(ro[Test.MyEnum.enum1]) == 2)
+ test(ro[Test.MyEnum.enum1][0] == Test.MyEnum.enum3)
+ test(ro[Test.MyEnum.enum1][1] == Test.MyEnum.enum3)
+ self.called()
+ except:
+ test(False)
+
+ def opIntS(self, f):
+ try:
+ r = f.result()
+ for j in range(0, len(r)):
+ test(r[j] == -j)
+ self.called()
+ except:
+ test(False)
+
+ def opIdempotent(self, f):
+ self.called()
+
+ def opNonmutating(self, f):
+ self.called()
+
+ def opDerived(self, f):
+ self.called()
+
+def twowaysFuture(communicator, p):
+ f = p.ice_pingAsync()
+ test(f.result() is None)
+
+ f = p.ice_isAAsync(Test.MyClass.ice_staticId())
+ test(f.result())
+
+ f = p.ice_idAsync()
+ test(f.result() == "::Test::MyDerivedClass")
+
+ f = p.ice_idsAsync()
+ test(len(f.result()) == 3)
+
+ f = p.opVoidAsync()
+ test(f.result() is None)
+
+ cb = Callback()
+ p.opVoidAsync().add_done_callback(lambda f: cb.called())
+ cb.check()
+
+ f = p.opByteAsync(0xff, 0x0f)
+ (ret, p3) = f.result()
+ test(p3 == 0xf0)
+ test(ret == 0xff)
+
+ cb = Callback()
+ p.opByteAsync(0xff, 0x0f).add_done_callback(cb.opByte)
+ cb.check()
+
+ cb = Callback()
+ p.opBoolAsync(True, False).add_done_callback(cb.opBool)
+ cb.check()
+
+ cb = Callback()
+ p.opShortIntLongAsync(10, 11, 12).add_done_callback(cb.opShortIntLong)
+ cb.check()
+
+ cb = Callback()
+ p.opFloatDoubleAsync(3.14, 1.1E10).add_done_callback(cb.opFloatDouble)
+ cb.check()
+
+ cb = Callback()
+ p.opStringAsync("hello", "world").add_done_callback(cb.opString)
+ cb.check()
+
+ cb = Callback()
+ p.opMyEnumAsync(Test.MyEnum.enum2).add_done_callback(cb.opMyEnum)
+ cb.check()
+
+ cb = Callback(communicator)
+ p.opMyClassAsync(p).add_done_callback(cb.opMyClass)
+ cb.check()
+
+ si1 = Test.Structure()
+ si1.p = p
+ si1.e = Test.MyEnum.enum3
+ si1.s = Test.AnotherStruct()
+ si1.s.s = "abc"
+ si2 = Test.Structure()
+ si2.p = None
+ si2.e = Test.MyEnum.enum2
+ si2.s = Test.AnotherStruct()
+ si2.s.s = "def"
+
+ cb = Callback(communicator)
+ p.opStructAsync(si1, si2).add_done_callback(cb.opStruct)
+ cb.check()
+
+ bsi1 = (0x01, 0x11, 0x12, 0x22)
+ bsi2 = (0xf1, 0xf2, 0xf3, 0xf4)
+
+ cb = Callback()
+ p.opByteSAsync(bsi1, bsi2).add_done_callback(cb.opByteS)
+ cb.check()
+
+ bsi1 = (True, True, False)
+ bsi2 = (False,)
+
+ cb = Callback()
+ p.opBoolSAsync(bsi1, bsi2).add_done_callback(cb.opBoolS)
+ cb.check()
+
+ ssi = (1, 2, 3)
+ isi = (5, 6, 7, 8)
+ lsi = (10, 30, 20)
+
+ cb = Callback()
+ p.opShortIntLongSAsync(ssi, isi, lsi).add_done_callback(cb.opShortIntLongS)
+ cb.check()
+
+ fsi = (3.14, 1.11)
+ dsi = (1.1E10, 1.2E10, 1.3E10)
+
+ cb = Callback()
+ p.opFloatDoubleSAsync(fsi, dsi).add_done_callback(cb.opFloatDoubleS)
+ cb.check()
+
+ ssi1 = ('abc', 'de', 'fghi')
+ ssi2 = ('xyz',)
+
+ cb = Callback()
+ p.opStringSAsync(ssi1, ssi2).add_done_callback(cb.opStringS)
+ cb.check()
+
+ bsi1 = ((0x01, 0x11, 0x12), (0xff,))
+ bsi2 = ((0x0e,), (0xf2, 0xf1))
+
+ cb = Callback()
+ p.opByteSSAsync(bsi1, bsi2).add_done_callback(cb.opByteSS)
+ cb.check()
+
+ bsi1 = ((True,), (False,), (True, True),)
+ bsi2 = ((False, False, True),)
+
+ cb = Callback()
+ p.opBoolSSAsync(bsi1, bsi2).add_done_callback(cb.opBoolSS)
+ cb.check();
+
+ ssi = ((1,2,5), (13,), ())
+ isi = ((24, 98), (42,))
+ lsi = ((496, 1729),)
+
+ cb = Callback()
+ p.opShortIntLongSSAsync(ssi, isi, lsi).add_done_callback(cb.opShortIntLongSS)
+ cb.check()
+
+ fsi = ((3.14,), (1.11,), ())
+ dsi = ((1.1E10, 1.2E10, 1.3E10),)
+
+ cb = Callback()
+ p.opFloatDoubleSSAsync(fsi, dsi).add_done_callback(cb.opFloatDoubleSS)
+ cb.check()
+
+ ssi1 = (('abc',), ('de', 'fghi'))
+ ssi2 = ((), (), ('xyz',))
+
+ cb = Callback()
+ p.opStringSSAsync(ssi1, ssi2).add_done_callback(cb.opStringSS)
+ cb.check()
+
+ di1 = {10: True, 100: False}
+ di2 = {10: True, 11: False, 101: True}
+
+ cb = Callback()
+ p.opByteBoolDAsync(di1, di2).add_done_callback(cb.opByteBoolD)
+ cb.check()
+
+ di1 = {110: -1, 1100: 123123}
+ di2 = {110: -1, 111: -100, 1101: 0}
+
+ cb = Callback()
+ p.opShortIntDAsync(di1, di2).add_done_callback(cb.opShortIntD)
+ cb.check()
+
+ di1 = {999999110: -1.1, 999999111: 123123.2}
+ di2 = {999999110: -1.1, 999999120: -100.4, 999999130: 0.5}
+
+ cb = Callback()
+ p.opLongFloatDAsync(di1, di2).add_done_callback(cb.opLongFloatD)
+ cb.check()
+
+ di1 = {'foo': 'abc -1.1', 'bar': 'abc 123123.2'}
+ di2 = {'foo': 'abc -1.1', 'FOO': 'abc -100.4', 'BAR': 'abc 0.5'}
+
+ cb = Callback()
+ p.opStringStringDAsync(di1, di2).add_done_callback(cb.opStringStringD)
+ cb.check()
+
+ di1 = {'abc': Test.MyEnum.enum1, '': Test.MyEnum.enum2}
+ di2 = {'abc': Test.MyEnum.enum1, 'qwerty': Test.MyEnum.enum3, 'Hello!!': Test.MyEnum.enum2}
+
+ cb = Callback()
+ p.opStringMyEnumDAsync(di1, di2).add_done_callback(cb.opStringMyEnumD)
+ cb.check()
+
+ di1 = {Test.MyEnum.enum1: 'abc'}
+ di2 = {Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'}
+
+ cb = Callback()
+ p.opMyEnumStringDAsync(di1, di2).add_done_callback(cb.opMyEnumStringD)
+ cb.check()
+
+ s11 = Test.MyStruct()
+ s11.i = 1
+ s11.j = 1
+ s12 = Test.MyStruct()
+ s12.i = 1
+ s12.j = 2
+ s22 = Test.MyStruct()
+ s22.i = 2
+ s22.j = 2
+ s23 = Test.MyStruct()
+ s23.i = 2
+ s23.j = 3
+ di1 = {s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2}
+ di2 = {s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2}
+
+ cb = Callback()
+ p.opMyStructMyEnumDAsync(di1, di2).add_done_callback(cb.opMyStructMyEnumD)
+ cb.check()
+
+ dsi1 = ({ 10: True, 100: False }, { 10: True, 11: False, 101: True })
+ dsi2 = ({ 100: False, 101: False },)
+
+ cb = Callback()
+ p.opByteBoolDSAsync(dsi1, dsi2).add_done_callback(cb.opByteBoolDS)
+ cb.check()
+
+ dsi1 = ({ 110: -1, 1100: 123123 }, { 110: -1, 111: -100, 1101: 0 })
+ dsi2 = ({ 100: -1001 },)
+
+ cb = Callback()
+ p.opShortIntDSAsync(dsi1, dsi2).add_done_callback(cb.opShortIntDS)
+ cb.called()
+
+ dsi1 = ({ 999999110: -1.1, 999999111: 123123.2 }, { 999999110: -1.1, 999999120: -100.4, 999999130: 0.5 })
+ dsi2 = ({ 999999140: 3.14 },)
+
+ cb = Callback()
+ p.opLongFloatDSAsync(dsi1, dsi2).add_done_callback(cb.opLongFloatDS)
+ cb.called()
+
+ dsi1 = ({ "foo": "abc -1.1", "bar": "abc 123123.2" }, { "foo": "abc -1.1", "FOO": "abc -100.4", "BAR": "abc 0.5" })
+ dsi2 = ({ "f00": "ABC -3.14" },)
+
+ cb = Callback()
+ p.opStringStringDSAsync(dsi1, dsi2).add_done_callback(cb.opStringStringDS)
+ cb.called()
+
+ dsi1 = (
+ { "abc": Test.MyEnum.enum1, "": Test.MyEnum.enum2 },
+ { "abc": Test.MyEnum.enum1, "qwerty": Test.MyEnum.enum3, "Hello!!": Test.MyEnum.enum2 }
+ )
+
+ dsi2 = ({ "Goodbye": Test.MyEnum.enum1 },)
+
+ cb = Callback()
+ p.opStringMyEnumDSAsync(dsi1, dsi2).add_done_callback(cb.opStringMyEnumDS)
+ cb.called()
+
+ dsi1 = ({ Test.MyEnum.enum1: 'abc' }, { Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'})
+ dsi2 = ({ Test.MyEnum.enum1: 'Goodbye' },)
+
+ cb = Callback()
+ p.opMyEnumStringDSAsync(dsi1, dsi2).add_done_callback(cb.opMyEnumStringDS)
+ cb.called()
+
+ s11 = Test.MyStruct(1, 1)
+ s12 = Test.MyStruct(1, 2)
+
+ s22 = Test.MyStruct(2, 2)
+ s23 = Test.MyStruct(2, 3)
+
+ dsi1 = (
+ { s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2 },
+ { s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2 }
+ )
+ dsi2 = ({ s23: Test.MyEnum.enum3 },)
+
+ cb = Callback()
+ p.opMyStructMyEnumDSAsync(dsi1, dsi2).add_done_callback(cb.opMyStructMyEnumDS)
+ cb.called()
+
+ sdi1 = { 0x01: (0x01, 0x11), 0x22: (0x12,) }
+ sdi2 = { 0xf1: (0xf2, 0xf3) }
+
+ cb = Callback()
+ p.opByteByteSDAsync(sdi1, sdi2).add_done_callback(cb.opByteByteSD)
+ cb.called()
+
+ sdi1 = { False: (True, False), True: (False, True, True) }
+ sdi2 = { False: (True, False) }
+
+ cb = Callback()
+ p.opBoolBoolSDAsync(sdi1, sdi2).add_done_callback(cb.opBoolBoolSD)
+ cb.called()
+
+ sdi1 = { 1: (1, 2, 3), 2: (4, 5) }
+ sdi2 = { 4: (6, 7) }
+
+ cb = Callback()
+ p.opShortShortSDAsync(sdi1, sdi2).add_done_callback(cb.opShortShortSD)
+ cb.called()
+
+ sdi1 = { 100: (100, 200, 300), 200: (400, 500) }
+ sdi2 = { 400: (600, 700) }
+
+ cb = Callback()
+ p.opIntIntSDAsync(sdi1, sdi2).add_done_callback(cb.opIntIntSD)
+ cb.called()
+
+ sdi1 = { 999999990: (999999110, 999999111, 999999110), 999999991: (999999120, 999999130) }
+ sdi2 = { 999999992: (999999110, 999999120) }
+
+ cb = Callback()
+ p.opLongLongSDAsync(sdi1, sdi2).add_done_callback(cb.opLongLongSD)
+ cb.called()
+
+ sdi1 = { "abc": (-1.1, 123123.2, 100.0), "ABC": (42.24, -1.61) }
+ sdi2 = { "aBc": (-3.14, 3.14) }
+
+ cb = Callback()
+ p.opStringFloatSDAsync(sdi1, sdi2).add_done_callback(cb.opStringFloatSD)
+ cb.called()
+
+ sdi1 = { "Hello!!": (1.1E10, 1.2E10, 1.3E10), "Goodbye": (1.4E10, 1.5E10) }
+ sdi2 = { "": (1.6E10, 1.7E10) }
+
+ cb = Callback()
+ p.opStringDoubleSDAsync(sdi1, sdi2).add_done_callback(cb.opStringDoubleSD)
+ cb.called()
+
+ sdi1 = { "abc": ("abc", "de", "fghi") , "def": ("xyz", "or") }
+ sdi2 = { "ghi": ("and", "xor") }
+
+ cb = Callback()
+ p.opStringStringSDAsync(sdi1, sdi2).add_done_callback(cb.opStringStringSD)
+ cb.called()
+
+ sdi1 = {
+ Test.MyEnum.enum3: (Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2),
+ Test.MyEnum.enum2: (Test.MyEnum.enum1, Test.MyEnum.enum2)
+ }
+ sdi2 = { Test.MyEnum.enum1: (Test.MyEnum.enum3, Test.MyEnum.enum3) }
+
+ cb = Callback()
+ p.opMyEnumMyEnumSDAsync(sdi1, sdi2).add_done_callback(cb.opMyEnumMyEnumSD)
+ cb.called()
+
+ lengths = ( 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 )
+ for l in lengths:
+ s = []
+ for i in range(l):
+ s.append(i)
+ cb = Callback(l)
+ p.opIntSAsync(s).add_done_callback(cb.opIntS)
+ cb.check()
+
+ ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'}
+
+ test(len(p.ice_getContext()) == 0)
+ f = p.opContextAsync()
+ c = f.result()
+ test(c != ctx)
+
+ test(len(p.ice_getContext()) == 0)
+ f = p.opContextAsync(_ctx=ctx)
+ c = f.result()
+ test(c == ctx)
+
+ p2 = Test.MyClassPrx.checkedCast(p.ice_context(ctx))
+ test(p2.ice_getContext() == ctx)
+ f = p2.opContextAsync()
+ c = f.result()
+ test(c == ctx)
+
+ f = p2.opContextAsync(_ctx=ctx)
+ c = f.result()
+ test(c == ctx)
+
+ #
+ # Test implicit context propagation
+ #
+ if p.ice_getConnection():
+ impls = ( 'Shared', 'PerThread' )
+ for i in impls:
+ initData = Ice.InitializationData()
+ initData.properties = communicator.getProperties().clone()
+ initData.properties.setProperty('Ice.ImplicitContext', i)
+ ic = Ice.initialize(data=initData)
+
+ ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'}
+
+ p3 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy("test:default -p 12010"))
+
+ ic.getImplicitContext().setContext(ctx)
+ test(ic.getImplicitContext().getContext() == ctx)
+ f = p3.opContextAsync()
+ c = f.result()
+ test(c == ctx)
+
+ ic.getImplicitContext().put('zero', 'ZERO')
+
+ ctx = ic.getImplicitContext().getContext()
+ f = p3.opContextAsync()
+ c = f.result()
+ test(c == ctx)
+
+ prxContext = {'one': 'UN', 'four': 'QUATRE'}
+
+ combined = {}
+ combined.update(ctx)
+ combined.update(prxContext)
+ test(combined['one'] == 'UN')
+
+ p3 = Test.MyClassPrx.uncheckedCast(p3.ice_context(prxContext))
+ ic.getImplicitContext().setContext({})
+ f = p3.opContextAsync()
+ c = f.result()
+ test(c == prxContext)
+
+ ic.getImplicitContext().setContext(ctx)
+ f = p3.opContextAsync()
+ c = f.result()
+ test(c == combined)
+
+ ic.destroy()
+
+ cb = Callback()
+ p.opIdempotentAsync().add_done_callback(cb.opIdempotent)
+ cb.check()
+
+ cb = Callback()
+ p.opNonmutatingAsync().add_done_callback(cb.opNonmutating)
+ cb.check()
+
+ derived = Test.MyDerivedClassPrx.checkedCast(p)
+ test(derived)
+ cb = Callback()
+ derived.opDerivedAsync().add_done_callback(cb.opDerived)
+ cb.check()
+
+ f = p.opByte1Async(0xFF)
+ test(f.result() == 0xFF)
+
+ f = p.opShort1Async(0x7FFF)
+ test(f.result() == 0x7FFF)
+
+ f = p.opInt1Async(0x7FFFFFFF)
+ test(f.result() == 0x7FFFFFFF)
+
+ f = p.opLong1Async(0x7FFFFFFFFFFFFFFF)
+ test(f.result() == 0x7FFFFFFFFFFFFFFF)
+
+ f = p.opFloat1Async(1.0)
+ test(f.result() == 1.0)
+
+ f = p.opDouble1Async(1.0)
+ test(f.result() == 1.0)
+
+ f = p.opString1Async("opString1")
+ test(f.result() == "opString1")
+
+ f = p.opStringS1Async(None)
+ test(len(f.result()) == 0)
+
+ f = p.opByteBoolD1Async(None)
+ test(len(f.result()) == 0)
+
+ f = p.opStringS2Async(None)
+ test(len(f.result()) == 0)
+
+ f = p.opByteBoolD2Async(None)
+ test(len(f.result()) == 0)
diff --git a/python/test/Ice/optional/AllTests.py b/python/test/Ice/optional/AllTests.py
index 6f2a610e8f3..8219fe6f428 100644
--- a/python/test/Ice/optional/AllTests.py
+++ b/python/test/Ice/optional/AllTests.py
@@ -456,72 +456,72 @@ def allTests(communicator):
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opByte(56)
test(p2 == 56 and p3 == 56)
- r = initial.begin_opByte(56)
- (p2, p3) = initial.end_opByte(r)
+ f = initial.opByteAsync(56)
+ (p2, p3) = f.result()
test(p2 == 56 and p3 == 56)
(p2, p3) = initial.opBool(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opBool(True)
test(p2 == True and p3 == True)
- r = initial.begin_opBool(True)
- (p2, p3) = initial.end_opBool(r)
+ f = initial.opBoolAsync(True)
+ (p2, p3) = f.result()
test(p2 == True and p3 == True)
(p2, p3) = initial.opShort(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opShort(56)
test(p2 == 56 and p3 == 56)
- r = initial.begin_opShort(56)
- (p2, p3) = initial.end_opShort(r)
+ f = initial.opShortAsync(56)
+ (p2, p3) = f.result()
test(p2 == 56 and p3 == 56)
(p2, p3) = initial.opInt(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opInt(56)
test(p2 == 56 and p3 == 56)
- r = initial.begin_opInt(56)
- (p2, p3) = initial.end_opInt(r)
+ f = initial.opIntAsync(56)
+ (p2, p3) = f.result()
test(p2 == 56 and p3 == 56)
(p2, p3) = initial.opLong(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opLong(56)
test(p2 == 56 and p3 == 56)
- r = initial.begin_opLong(56)
- (p2, p3) = initial.end_opLong(r)
+ f = initial.opLongAsync(56)
+ (p2, p3) = f.result()
test(p2 == 56 and p3 == 56)
(p2, p3) = initial.opFloat(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opFloat(1.0)
test(p2 == 1.0 and p3 == 1.0)
- r = initial.begin_opFloat(1.0)
- (p2, p3) = initial.end_opFloat(r)
+ f = initial.opFloatAsync(1.0)
+ (p2, p3) = f.result()
test(p2 == 1.0 and p3 == 1.0)
(p2, p3) = initial.opDouble(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opDouble(1.0)
test(p2 == 1.0 and p3 == 1.0)
- r = initial.begin_opDouble(1.0)
- (p2, p3) = initial.end_opDouble(r)
+ f = initial.opDoubleAsync(1.0)
+ (p2, p3) = f.result()
test(p2 == 1.0 and p3 == 1.0)
(p2, p3) = initial.opString(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opString("test")
test(p2 == "test" and p3 == "test")
- r = initial.begin_opString("test")
- (p2, p3) = initial.end_opString(r)
+ f = initial.opStringAsync("test")
+ (p2, p3) = f.result()
test(p2 == "test" and p3 == "test")
(p2, p3) = initial.opMyEnum(Ice.Unset)
test(p2 is Ice.Unset and p3 is Ice.Unset)
(p2, p3) = initial.opMyEnum(Test.MyEnum.MyEnumMember)
test(p2 == Test.MyEnum.MyEnumMember and p3 == Test.MyEnum.MyEnumMember)
- r = initial.begin_opMyEnum(Test.MyEnum.MyEnumMember)
- (p2, p3) = initial.end_opMyEnum(r)
+ f = initial.opMyEnumAsync(Test.MyEnum.MyEnumMember)
+ (p2, p3) = f.result()
test(p2 == Test.MyEnum.MyEnumMember and p3 == Test.MyEnum.MyEnumMember)
(p2, p3) = initial.opSmallStruct(Ice.Unset)
@@ -531,8 +531,8 @@ def allTests(communicator):
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opSmallStruct(None) # Test null struct
test(p2.m == 0 and p3.m == 0)
- r = initial.begin_opSmallStruct(p1)
- (p2, p3) = initial.end_opSmallStruct(r)
+ f = initial.opSmallStructAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opFixedStruct(Ice.Unset)
@@ -540,8 +540,8 @@ def allTests(communicator):
p1 = Test.FixedStruct(56)
(p2, p3) = initial.opFixedStruct(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opFixedStruct(p1)
- (p2, p3) = initial.end_opFixedStruct(r)
+ f = initial.opFixedStructAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opVarStruct(Ice.Unset)
@@ -549,8 +549,8 @@ def allTests(communicator):
p1 = Test.VarStruct("test")
(p2, p3) = initial.opVarStruct(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opVarStruct(p1)
- (p2, p3) = initial.end_opVarStruct(r)
+ f = initial.opVarStructAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opOneOptional(Ice.Unset)
@@ -558,8 +558,8 @@ def allTests(communicator):
p1 = Test.OneOptional(58)
(p2, p3) = initial.opOneOptional(p1)
test(p2.a == p1.a and p3.a == p1.a)
- r = initial.begin_opOneOptional(p1)
- (p2, p3) = initial.end_opOneOptional(r)
+ f = initial.opOneOptionalAsync(p1)
+ (p2, p3) = f.result()
test(p2.a == p1.a and p3.a == p1.a)
(p2, p3) = initial.opOneOptionalProxy(Ice.Unset)
@@ -567,8 +567,8 @@ def allTests(communicator):
p1 = Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))
(p2, p3) = initial.opOneOptionalProxy(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opOneOptionalProxy(p1)
- (p2, p3) = initial.end_opOneOptionalProxy(r)
+ f = initial.opOneOptionalProxyAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opByteSeq(Ice.Unset)
@@ -582,8 +582,8 @@ def allTests(communicator):
else:
test(p2[0] == 0x38)
test(p3[0] == 0x38)
- r = initial.begin_opByteSeq(p1)
- (p2, p3) = initial.end_opByteSeq(r)
+ f = initial.opByteSeqAsync(p1)
+ (p2, p3) = f.result()
test(len(p2) == len(p1) and len(p3) == len(p1))
if sys.version_info[0] == 2:
test(p2[0] == '\x38')
@@ -597,8 +597,8 @@ def allTests(communicator):
p1 = [True for x in range(100)]
(p2, p3) = initial.opBoolSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opBoolSeq(p1)
- (p2, p3) = initial.end_opBoolSeq(r)
+ f = initial.opBoolSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opShortSeq(Ice.Unset)
@@ -606,8 +606,8 @@ def allTests(communicator):
p1 = [56 for x in range(100)]
(p2, p3) = initial.opShortSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opShortSeq(p1)
- (p2, p3) = initial.end_opShortSeq(r)
+ f = initial.opShortSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opIntSeq(Ice.Unset)
@@ -615,8 +615,8 @@ def allTests(communicator):
p1 = [56 for x in range(100)]
(p2, p3) = initial.opIntSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opIntSeq(p1)
- (p2, p3) = initial.end_opIntSeq(r)
+ f = initial.opIntSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opLongSeq(Ice.Unset)
@@ -624,8 +624,8 @@ def allTests(communicator):
p1 = [56 for x in range(100)]
(p2, p3) = initial.opLongSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opLongSeq(p1)
- (p2, p3) = initial.end_opLongSeq(r)
+ f = initial.opLongSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opFloatSeq(Ice.Unset)
@@ -633,8 +633,8 @@ def allTests(communicator):
p1 = [1.0 for x in range(100)]
(p2, p3) = initial.opFloatSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opFloatSeq(p1)
- (p2, p3) = initial.end_opFloatSeq(r)
+ f = initial.opFloatSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opDoubleSeq(Ice.Unset)
@@ -642,8 +642,8 @@ def allTests(communicator):
p1 = [1.0 for x in range(100)]
(p2, p3) = initial.opDoubleSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opDoubleSeq(p1)
- (p2, p3) = initial.end_opDoubleSeq(r)
+ f = initial.opDoubleSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opStringSeq(Ice.Unset)
@@ -651,8 +651,8 @@ def allTests(communicator):
p1 = ["test1" for x in range(100)]
(p2, p3) = initial.opStringSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opStringSeq(p1)
- (p2, p3) = initial.end_opStringSeq(r)
+ f = initial.opStringSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opSmallStructSeq(Ice.Unset)
@@ -660,8 +660,8 @@ def allTests(communicator):
p1 = [Test.SmallStruct(1) for x in range(10)]
(p2, p3) = initial.opSmallStructSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opSmallStructSeq(p1)
- (p2, p3) = initial.end_opSmallStructSeq(r)
+ f = initial.opSmallStructSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opSmallStructList(Ice.Unset)
@@ -669,8 +669,8 @@ def allTests(communicator):
p1 = tuple([Test.SmallStruct(1) for x in range(10)])
(p2, p3) = initial.opSmallStructList(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opSmallStructList(p1)
- (p2, p3) = initial.end_opSmallStructList(r)
+ f = initial.opSmallStructListAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opFixedStructSeq(Ice.Unset)
@@ -678,8 +678,8 @@ def allTests(communicator):
p1 = [Test.FixedStruct(1) for x in range(10)]
(p2, p3) = initial.opFixedStructSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opFixedStructSeq(p1)
- (p2, p3) = initial.end_opFixedStructSeq(r)
+ f = initial.opFixedStructSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opFixedStructList(Ice.Unset)
@@ -687,8 +687,8 @@ def allTests(communicator):
p1 = tuple([Test.FixedStruct(1) for x in range(10)])
(p2, p3) = initial.opFixedStructList(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opFixedStructList(p1)
- (p2, p3) = initial.end_opFixedStructList(r)
+ f = initial.opFixedStructListAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opVarStructSeq(Ice.Unset)
@@ -696,8 +696,8 @@ def allTests(communicator):
p1 = [Test.VarStruct("test") for x in range(10)]
(p2, p3) = initial.opVarStructSeq(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opVarStructSeq(p1)
- (p2, p3) = initial.end_opVarStructSeq(r)
+ f = initial.opVarStructSeqAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opIntIntDict(Ice.Unset)
@@ -705,8 +705,8 @@ def allTests(communicator):
p1 = {1:2, 2:3}
(p2, p3) = initial.opIntIntDict(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opIntIntDict(p1)
- (p2, p3) = initial.end_opIntIntDict(r)
+ f = initial.opIntIntDictAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opStringIntDict(Ice.Unset)
@@ -714,8 +714,8 @@ def allTests(communicator):
p1 = {"1":2, "2":3}
(p2, p3) = initial.opStringIntDict(p1)
test(p2 == p1 and p3 == p1)
- r = initial.begin_opStringIntDict(p1)
- (p2, p3) = initial.end_opStringIntDict(r)
+ f = initial.opStringIntDictAsync(p1)
+ (p2, p3) = f.result()
test(p2 == p1 and p3 == p1)
(p2, p3) = initial.opIntOneOptionalDict(Ice.Unset)
@@ -723,8 +723,8 @@ def allTests(communicator):
p1 = {1:Test.OneOptional(58), 2:Test.OneOptional(59)}
(p2, p3) = initial.opIntOneOptionalDict(p1)
test(p2[1].a == 58 and p3[1].a == 58);
- r = initial.begin_opIntOneOptionalDict(p1)
- (p2, p3) = initial.end_opIntOneOptionalDict(r)
+ f = initial.opIntOneOptionalDictAsync(p1)
+ (p2, p3) = f.result()
test(p2[1].a == 58 and p3[1].a == 58);
print("ok")
diff --git a/python/test/Ice/optional/ServerAMD.py b/python/test/Ice/optional/ServerAMD.py
index 15f4ca42867..a9bbda70c9b 100755
--- a/python/test/Ice/optional/ServerAMD.py
+++ b/python/test/Ice/optional/ServerAMD.py
@@ -16,20 +16,23 @@ import Test
class InitialI(Test.Initial):
- def shutdown_async(self, cb, current=None):
+ def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
- def pingPong_async(self, cb, o, current=None):
- cb.ice_response(o)
+ def pingPong(self, o, current=None):
+ return Ice.Future.completed(o)
- def opOptionalException_async(self, cb, a, b, o, current=None):
- cb.ice_exception(Test.OptionalException(False, a, b, o))
+ def opOptionalException(self, a, b, o, current=None):
+ f = Ice.Future()
+ f.set_exception(Test.OptionalException(False, a, b, o))
+ return f
- def opDerivedException_async(self, cb, a, b, o, current=None):
- cb.ice_exception(Test.DerivedException(False, a, b, o, b, o))
+ def opDerivedException(self, a, b, o, current=None):
+ f = Ice.Future()
+ f.set_exception(Test.DerivedException(False, a, b, o, b, o))
+ return f
- def opRequiredException_async(self, cb, a, b, o, current=None):
+ def opRequiredException(self, a, b, o, current=None):
e = Test.RequiredException()
e.a = a
e.b = b
@@ -38,154 +41,156 @@ class InitialI(Test.Initial):
e.ss = b
if o is not Ice.Unset:
e.o2 = o
- cb.ice_exception(e)
+ f = Ice.Future()
+ f.set_exception(e)
+ return f
- def opByte_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opByte(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opBool_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opBool(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opShort_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opShort(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opInt_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opInt(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opLong_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opLong(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opFloat_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opFloat(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opDouble_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opDouble(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opString_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opString(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opMyEnum_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opMyEnum(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opSmallStruct_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opSmallStruct(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opFixedStruct_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opFixedStruct(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opVarStruct_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opVarStruct(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opOneOptional_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opOneOptional(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opOneOptionalProxy_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opOneOptionalProxy(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opByteSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opByteSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opBoolSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opBoolSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opShortSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opShortSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opIntSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opIntSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opLongSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opLongSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opFloatSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opFloatSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opDoubleSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opDoubleSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opStringSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opStringSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opSmallStructSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opSmallStructSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opSmallStructList_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opSmallStructList(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opFixedStructSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opFixedStructSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opFixedStructList_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opFixedStructList(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opVarStructSeq_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opVarStructSeq(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opSerializable_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opSerializable(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opIntIntDict_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opIntIntDict(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opStringIntDict_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opStringIntDict(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opIntOneOptionalDict_async(self, cb, p1, current=None):
- cb.ice_response(p1, p1)
+ def opIntOneOptionalDict(self, p1, current=None):
+ return Ice.Future.completed((p1, p1))
- def opClassAndUnknownOptional_async(self, cb, p, current=None):
- cb.ice_response()
+ def opClassAndUnknownOptional(self, p, current=None):
+ return Ice.Future.completed(None)
- def sendOptionalClass_async(self, cb, req, o, current=None):
- cb.ice_response()
+ def sendOptionalClass(self, req, o, current=None):
+ return Ice.Future.completed(None)
- def returnOptionalClass_async(self, cb, req, current=None):
- cb.ice_response(Test.OneOptional(53))
+ def returnOptionalClass(self, req, current=None):
+ return Ice.Future.completed(Test.OneOptional(53))
- def opG_async(self, cb, g, current=None):
- cb.ice_response(g)
+ def opG(self, g, current=None):
+ return Ice.Future.completed(g)
- def opVoid_async(self, cb, current=None):
- cb.ice_response()
+ def opVoid(self, current=None):
+ return Ice.Future.completed(None)
- def opMStruct1_async(self, cb, current):
- cb.ice_response(Test.SmallStruct())
+ def opMStruct1(self, current):
+ return Ice.Future.completed(Test.SmallStruct())
- def opMStruct2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMStruct2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def opMSeq1_async(self, cb, current):
- cb.ice_response([])
+ def opMSeq1(self, current):
+ return Ice.Future.completed([])
- def opMSeq2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMSeq2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def opMDict1_async(self, cb, current):
- cb.ice_response({})
+ def opMDict1(self, current):
+ return Ice.Future.completed({})
- def opMDict2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMDict2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def opMG1_async(self, cb, current):
- cb.ice_response(Test.G())
+ def opMG1(self, current):
+ return Ice.Future.completed(Test.G())
- def opMG2_async(self, cb, p1, current):
- cb.ice_response(p1, p1)
+ def opMG2(self, p1, current):
+ return Ice.Future.completed((p1, p1))
- def supportsRequiredParams_async(self, cb, current=None):
- cb.ice_response(False)
+ def supportsRequiredParams(self, current=None):
+ return Ice.Future.completed(False)
- def supportsJavaSerializable_async(self, cb, current=None):
- cb.ice_response(True)
+ def supportsJavaSerializable(self, current=None):
+ return Ice.Future.completed(True)
- def supportsCsharpSerializable_async(self, cb, current=None):
- cb.ice_response(False)
+ def supportsCsharpSerializable(self, current=None):
+ return Ice.Future.completed(False)
- def supportsCppStringView_async(self, cb, current=None):
- cb.ice_response(False)
+ def supportsCppStringView(self, current=None):
+ return Ice.Future.completed(False)
- def supportsNullOptional_async(self, cb, current=None):
- cb.ice_response(True)
+ def supportsNullOptional(self, current=None):
+ return Ice.Future.completed(True)
def run(args, communicator):
communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp")
diff --git a/python/test/Ice/proxy/ServerAMD.py b/python/test/Ice/proxy/ServerAMD.py
index 35804df3068..218e8f7d596 100755
--- a/python/test/Ice/proxy/ServerAMD.py
+++ b/python/test/Ice/proxy/ServerAMD.py
@@ -23,15 +23,14 @@ class MyDerivedClassI(Test.MyDerivedClass):
def __init__(self):
self.ctx = None
- def shutdown_async(self, cb, current=None):
+ def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
- def getContext_async(self, cb, current):
- return cb.ice_response(self.ctx)
+ def getContext(self, current):
+ return Ice.Future.completed(self.ctx)
- def echo_async(self, cb, obj, current):
- return cb.ice_response(obj)
+ def echo(self, obj, current):
+ return Ice.Future.completed(obj)
def ice_isA(self, s, current):
self.ctx = current.ctx
diff --git a/python/test/Ice/servantLocator/TestAMDI.py b/python/test/Ice/servantLocator/TestAMDI.py
index 22d87341375..219ce7f3ebc 100644
--- a/python/test/Ice/servantLocator/TestAMDI.py
+++ b/python/test/Ice/servantLocator/TestAMDI.py
@@ -16,61 +16,74 @@ def test(b):
class TestI(Test.TestIntf):
- def requestFailedException_async(self, cb, current=None):
- cb.ice_response()
+ def requestFailedException(self, current=None):
+ return None
- def unknownUserException_async(self, cb, current=None):
- cb.ice_response()
+ def unknownUserException(self, current=None):
+ return None
- def unknownLocalException_async(self, cb, current=None):
- cb.ice_response()
+ def unknownLocalException(self, current=None):
+ return None
- def unknownException_async(self, cb, current=None):
- cb.ice_response()
+ def unknownException(self, current=None):
+ return None
- def localException_async(self, cb, current=None):
- cb.ice_response()
+ def localException(self, current=None):
+ return None
- def userException_async(self, cb, current=None):
- cb.ice_response()
+ def userException(self, current=None):
+ return None
- def pythonException_async(self, cb, current=None):
- cb.ice_response()
+ def pythonException(self, current=None):
+ return None
- def unknownExceptionWithServantException_async(self, cb, current=None):
- cb.ice_exception(Ice.ObjectNotExistException())
+ def unknownExceptionWithServantException(self, current=None):
+ f = Ice.Future()
+ f.set_exception(Ice.ObjectNotExistException())
+ return f
- def impossibleException_async(self, cb, throw, current=None):
+ def impossibleException(self, throw, current=None):
+ f = Ice.Future()
if throw:
- cb.ice_exception(Test.TestImpossibleException())
+ f.set_exception(Test.TestImpossibleException())
else:
#
# Return a value so we can be sure that the stream position
# is reset correctly if finished() throws.
#
- cb.ice_response("Hello")
+ f.set_result("Hello")
+ return f
- def intfUserException_async(self, cb, throw, current=None):
+ def intfUserException(self, throw, current=None):
+ f = Ice.Future()
if throw:
- cb.ice_exception(Test.TestIntfUserException())
+ f.set_exception(Test.TestIntfUserException())
else:
#
# Return a value so we can be sure that the stream position
# is reset correctly if finished() throws.
#
- cb.ice_response("Hello")
+ f.set_result("Hello")
+ return f
- def asyncResponse_async(self, cb, current=None):
- cb.ice_response()
+ def asyncResponse(self, current=None):
+ #
+ # We can't do this with futures.
+ #
+ #return Ice.Future.completed(None)
raise Ice.ObjectNotExistException()
- def asyncException_async(self, cb, current=None):
- cb.ice_exception(Test.TestIntfUserException())
+ def asyncException(self, current=None):
+ #
+ # We can't do this with futures.
+ #
+ #f = Ice.Future()
+ #f.set_exception(Test.TestIntfUserException())
+ #return f
raise Ice.ObjectNotExistException()
- def shutdown_async(self, cb, current=None):
+ def shutdown(self, current=None):
current.adapter.deactivate()
- cb.ice_response()
class CookieI(Test.Cookie):
def message(self):
diff --git a/python/test/Ice/slicing/exceptions/AllTests.py b/python/test/Ice/slicing/exceptions/AllTests.py
index b3fa67dd502..5419f08e33e 100644
--- a/python/test/Ice/slicing/exceptions/AllTests.py
+++ b/python/test/Ice/slicing/exceptions/AllTests.py
@@ -23,27 +23,21 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
- def response(self):
- test(False)
-
- def exception_baseAsBase(self, exc):
+ def exception_baseAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.Base as b:
test(b.b == "Base.b")
test(b.ice_id() == "::Test::Base")
@@ -51,9 +45,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_unknownDerivedAsBase(self, exc):
+ def exception_unknownDerivedAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.Base as b:
test(b.b == "UnknownDerived.b")
test(b.ice_id() == "::Test::Base")
@@ -61,9 +56,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownDerivedAsBase(self, exc):
+ def exception_knownDerivedAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownDerived as k:
test(k.b == "KnownDerived.b")
test(k.kd == "KnownDerived.kd")
@@ -72,9 +68,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownDerivedAsKnownDerived(self, exc):
+ def exception_knownDerivedAsKnownDerived(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownDerived as k:
test(k.b == "KnownDerived.b")
test(k.kd == "KnownDerived.kd")
@@ -83,9 +80,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_unknownIntermediateAsBase(self, exc):
+ def exception_unknownIntermediateAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.Base as b:
test(b.b == "UnknownIntermediate.b")
test(b.ice_id() == "::Test::Base")
@@ -93,9 +91,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownIntermediateAsBase(self, exc):
+ def exception_knownIntermediateAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownIntermediate as ki:
test(ki.b == "KnownIntermediate.b")
test(ki.ki == "KnownIntermediate.ki")
@@ -104,9 +103,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownMostDerivedAsBase(self, exc):
+ def exception_knownMostDerivedAsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownMostDerived as kmd:
test(kmd.b == "KnownMostDerived.b")
test(kmd.ki == "KnownMostDerived.ki")
@@ -116,9 +116,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownIntermediateAsKnownIntermediate(self, exc):
+ def exception_knownIntermediateAsKnownIntermediate(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownIntermediate as ki:
test(ki.b == "KnownIntermediate.b")
test(ki.ki == "KnownIntermediate.ki")
@@ -127,9 +128,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownMostDerivedAsKnownMostDerived(self, exc):
+ def exception_knownMostDerivedAsKnownMostDerived(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownMostDerived as kmd:
test(kmd.b == "KnownMostDerived.b")
test(kmd.ki == "KnownMostDerived.ki")
@@ -139,9 +141,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_knownMostDerivedAsKnownIntermediate(self, exc):
+ def exception_knownMostDerivedAsKnownIntermediate(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownMostDerived as kmd:
test(kmd.b == "KnownMostDerived.b")
test(kmd.ki == "KnownMostDerived.ki")
@@ -151,9 +154,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_unknownMostDerived1AsBase(self, exc):
+ def exception_unknownMostDerived1AsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownIntermediate as ki:
test(ki.b == "UnknownMostDerived1.b")
test(ki.ki == "UnknownMostDerived1.ki")
@@ -162,9 +166,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_unknownMostDerived1AsKnownIntermediate(self, exc):
+ def exception_unknownMostDerived1AsKnownIntermediate(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.KnownIntermediate as ki:
test(ki.b == "UnknownMostDerived1.b")
test(ki.ki == "UnknownMostDerived1.ki")
@@ -173,9 +178,10 @@ class Callback(CallbackBase):
test(False)
self.called()
- def exception_unknownMostDerived2AsBase(self, exc):
+ def exception_unknownMostDerived2AsBase(self, f):
try:
- raise exc
+ f.result()
+ test(False)
except Test.Base as b:
test(b.b == "UnknownMostDerived2.b")
test(b.ice_id() == "::Test::Base")
@@ -235,7 +241,7 @@ def allTests(communicator):
sys.stdout.write("base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_baseAsBase(cb.response, cb.exception_baseAsBase)
+ t.baseAsBaseAsync().add_done_callback(cb.exception_baseAsBase)
cb.check()
print("ok")
@@ -254,7 +260,7 @@ def allTests(communicator):
sys.stdout.write("slicing of unknown derived (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_unknownDerivedAsBase(cb.response, cb.exception_unknownDerivedAsBase)
+ t.unknownDerivedAsBaseAsync().add_done_callback(cb.exception_unknownDerivedAsBase)
cb.check()
print("ok")
@@ -274,7 +280,7 @@ def allTests(communicator):
sys.stdout.write("non-slicing of known derived as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownDerivedAsBase(cb.response, cb.exception_knownDerivedAsBase)
+ t.knownDerivedAsBaseAsync().add_done_callback(cb.exception_knownDerivedAsBase)
cb.check()
print("ok")
@@ -294,7 +300,7 @@ def allTests(communicator):
sys.stdout.write("non-slicing of known derived as derived (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownDerivedAsKnownDerived(cb.response, cb.exception_knownDerivedAsKnownDerived)
+ t.knownDerivedAsKnownDerivedAsync().add_done_callback(cb.exception_knownDerivedAsKnownDerived)
cb.check()
print("ok")
@@ -313,7 +319,7 @@ def allTests(communicator):
sys.stdout.write("slicing of unknown intermediate as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_unknownIntermediateAsBase(cb.response, cb.exception_unknownIntermediateAsBase)
+ t.unknownIntermediateAsBaseAsync().add_done_callback(cb.exception_unknownIntermediateAsBase)
cb.check()
print("ok")
@@ -333,7 +339,7 @@ def allTests(communicator):
sys.stdout.write("slicing of known intermediate as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownIntermediateAsBase(cb.response, cb.exception_knownIntermediateAsBase)
+ t.knownIntermediateAsBaseAsync().add_done_callback(cb.exception_knownIntermediateAsBase)
cb.check()
print("ok")
@@ -354,7 +360,7 @@ def allTests(communicator):
sys.stdout.write("slicing of known most derived as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownMostDerivedAsBase(cb.response, cb.exception_knownMostDerivedAsBase)
+ t.knownMostDerivedAsBaseAsync().add_done_callback(cb.exception_knownMostDerivedAsBase)
cb.check()
print("ok")
@@ -374,7 +380,7 @@ def allTests(communicator):
sys.stdout.write("non-slicing of known intermediate as intermediate (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownIntermediateAsKnownIntermediate(cb.response, cb.exception_knownIntermediateAsKnownIntermediate)
+ t.knownIntermediateAsKnownIntermediateAsync().add_done_callback(cb.exception_knownIntermediateAsKnownIntermediate)
cb.check()
print("ok")
@@ -395,7 +401,7 @@ def allTests(communicator):
sys.stdout.write("non-slicing of known most derived as intermediate (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownMostDerivedAsKnownIntermediate(cb.response, cb.exception_knownMostDerivedAsKnownIntermediate)
+ t.knownMostDerivedAsKnownIntermediateAsync().add_done_callback(cb.exception_knownMostDerivedAsKnownIntermediate)
cb.check()
print("ok")
@@ -416,7 +422,7 @@ def allTests(communicator):
sys.stdout.write("non-slicing of known most derived as most derived (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_knownMostDerivedAsKnownMostDerived(cb.response, cb.exception_knownMostDerivedAsKnownMostDerived)
+ t.knownMostDerivedAsKnownMostDerivedAsync().add_done_callback(cb.exception_knownMostDerivedAsKnownMostDerived)
cb.check()
print("ok")
@@ -436,7 +442,7 @@ def allTests(communicator):
sys.stdout.write("slicing of unknown most derived, known intermediate as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_unknownMostDerived1AsBase(cb.response, cb.exception_unknownMostDerived1AsBase)
+ t.unknownMostDerived1AsBaseAsync().add_done_callback(cb.exception_unknownMostDerived1AsBase)
cb.check()
print("ok")
@@ -456,7 +462,8 @@ def allTests(communicator):
sys.stdout.write("slicing of unknown most derived, known intermediate as intermediate (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_unknownMostDerived1AsKnownIntermediate(cb.response, cb.exception_unknownMostDerived1AsKnownIntermediate)
+ t.unknownMostDerived1AsKnownIntermediateAsync().add_done_callback(
+ cb.exception_unknownMostDerived1AsKnownIntermediate)
cb.check()
print("ok")
@@ -475,7 +482,7 @@ def allTests(communicator):
sys.stdout.write("slicing of unknown most derived, unknown intermediate as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_unknownMostDerived2AsBase(cb.response, cb.exception_unknownMostDerived2AsBase)
+ t.unknownMostDerived2AsBaseAsync().add_done_callback(cb.exception_unknownMostDerived2AsBase)
cb.check()
print("ok")
diff --git a/python/test/Ice/slicing/exceptions/ServerAMD.py b/python/test/Ice/slicing/exceptions/ServerAMD.py
index 9b3004e1d6e..5dd7386d670 100755
--- a/python/test/Ice/slicing/exceptions/ServerAMD.py
+++ b/python/test/Ice/slicing/exceptions/ServerAMD.py
@@ -15,159 +15,202 @@ Ice.loadSlice('-I. --all ServerPrivateAMD.ice')
import Test
class TestI(Test.TestIntf):
- def shutdown_async(self, cb, current=None):
+ def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
- def baseAsBase_async(self, cb, current=None):
+ def baseAsBase(self, current=None):
b = Test.Base()
b.b = "Base.b"
- cb.ice_exception(b)
+ f = Ice.Future()
+ f.set_exception(b)
+ return f
- def unknownDerivedAsBase_async(self, cb, current=None):
+ def unknownDerivedAsBase(self, current=None):
d = Test.UnknownDerived()
d.b = "UnknownDerived.b"
d.ud = "UnknownDerived.ud"
- cb.ice_exception(d)
+ f = Ice.Future()
+ f.set_exception(d)
+ return f
- def knownDerivedAsBase_async(self, cb, current=None):
+ def knownDerivedAsBase(self, current=None):
d = Test.KnownDerived()
d.b = "KnownDerived.b"
d.kd = "KnownDerived.kd"
- cb.ice_exception(d)
+ f = Ice.Future()
+ f.set_exception(d)
+ return f
- def knownDerivedAsKnownDerived_async(self, cb, current=None):
+ def knownDerivedAsKnownDerived(self, current=None):
d = Test.KnownDerived()
d.b = "KnownDerived.b"
d.kd = "KnownDerived.kd"
- cb.ice_exception(d)
+ f = Ice.Future()
+ f.set_exception(d)
+ return f
- def unknownIntermediateAsBase_async(self, cb, current=None):
+ def unknownIntermediateAsBase(self, current=None):
ui = Test.UnknownIntermediate()
ui.b = "UnknownIntermediate.b"
ui.ui = "UnknownIntermediate.ui"
- cb.ice_exception(ui)
+ f = Ice.Future()
+ f.set_exception(ui)
+ return f
- def knownIntermediateAsBase_async(self, cb, current=None):
+ def knownIntermediateAsBase(self, current=None):
ki = Test.KnownIntermediate()
ki.b = "KnownIntermediate.b"
ki.ki = "KnownIntermediate.ki"
- cb.ice_exception(ki)
+ f = Ice.Future()
+ f.set_exception(ki)
+ return f
- def knownMostDerivedAsBase_async(self, cb, current=None):
+ def knownMostDerivedAsBase(self, current=None):
kmd = Test.KnownMostDerived()
kmd.b = "KnownMostDerived.b"
kmd.ki = "KnownMostDerived.ki"
kmd.kmd = "KnownMostDerived.kmd"
- cb.ice_exception(kmd)
+ f = Ice.Future()
+ f.set_exception(kmd)
+ return f
- def knownIntermediateAsKnownIntermediate_async(self, cb, current=None):
+ def knownIntermediateAsKnownIntermediate(self, current=None):
ki = Test.KnownIntermediate()
ki.b = "KnownIntermediate.b"
ki.ki = "KnownIntermediate.ki"
- cb.ice_exception(ki)
+ f = Ice.Future()
+ f.set_exception(ki)
+ return f
- def knownMostDerivedAsKnownIntermediate_async(self, cb, current=None):
+ def knownMostDerivedAsKnownIntermediate(self, current=None):
kmd = Test.KnownMostDerived()
kmd.b = "KnownMostDerived.b"
kmd.ki = "KnownMostDerived.ki"
kmd.kmd = "KnownMostDerived.kmd"
- cb.ice_exception(kmd)
+ f = Ice.Future()
+ f.set_exception(kmd)
+ return f
- def knownMostDerivedAsKnownMostDerived_async(self, cb, current=None):
+ def knownMostDerivedAsKnownMostDerived(self, current=None):
kmd = Test.KnownMostDerived()
kmd.b = "KnownMostDerived.b"
kmd.ki = "KnownMostDerived.ki"
kmd.kmd = "KnownMostDerived.kmd"
- cb.ice_exception(kmd)
+ f = Ice.Future()
+ f.set_exception(kmd)
+ return f
- def unknownMostDerived1AsBase_async(self, cb, current=None):
+ def unknownMostDerived1AsBase(self, current=None):
umd1 = Test.UnknownMostDerived1()
umd1.b = "UnknownMostDerived1.b"
umd1.ki = "UnknownMostDerived1.ki"
umd1.umd1 = "UnknownMostDerived1.umd1"
- cb.ice_exception(umd1)
+ f = Ice.Future()
+ f.set_exception(umd1)
+ return f
- def unknownMostDerived1AsKnownIntermediate_async(self, cb, current=None):
+ def unknownMostDerived1AsKnownIntermediate(self, current=None):
umd1 = Test.UnknownMostDerived1()
umd1.b = "UnknownMostDerived1.b"
umd1.ki = "UnknownMostDerived1.ki"
umd1.umd1 = "UnknownMostDerived1.umd1"
- cb.ice_exception(umd1)
+ f = Ice.Future()
+ f.set_exception(umd1)
+ return f
- def unknownMostDerived2AsBase_async(self, cb, current=None):
+ def unknownMostDerived2AsBase(self, current=None):
umd2 = Test.UnknownMostDerived2()
umd2.b = "UnknownMostDerived2.b"
umd2.ui = "UnknownMostDerived2.ui"
umd2.umd2 = "UnknownMostDerived2.umd2"
- cb.ice_exception(umd2)
+ f = Ice.Future()
+ f.set_exception(umd2)
+ return f
- def unknownMostDerived2AsBaseCompact_async(self, cb, current=None):
+ def unknownMostDerived2AsBaseCompact(self, current=None):
umd2 = Test.UnknownMostDerived2()
umd2.b = "UnknownMostDerived2.b"
umd2.ui = "UnknownMostDerived2.ui"
umd2.umd2 = "UnknownMostDerived2.umd2"
- cb.ice_exception(umd2)
+ f = Ice.Future()
+ f.set_exception(umd2)
+ return f
- def knownPreservedAsBase_async(self, cb, r, current=None):
+ def knownPreservedAsBase(self, r, current=None):
ex = Test.KnownPreservedDerived()
ex.b = "base"
ex.kp = "preserved"
ex.kpd = "derived"
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def knownPreservedAsKnownPreserved_async(self, cb, r, current=None):
+ def knownPreservedAsKnownPreserved(self, r, current=None):
ex = Test.KnownPreservedDerived()
ex.b = "base"
ex.kp = "preserved"
ex.kpd = "derived"
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def relayKnownPreservedAsBase_async(self, cb, r, current=None):
+ def relayKnownPreservedAsBase(self, r, current=None):
+ f = Ice.Future()
try:
r.knownPreservedAsBase()
test(False)
except Ice.Exception as ex:
- cb.ice_exception(ex)
+ f.set_exception(ex)
+ return f
- def relayKnownPreservedAsKnownPreserved_async(self, cb, r, current=None):
+ def relayKnownPreservedAsKnownPreserved(self, r, current=None):
+ f = Ice.Future()
try:
r.knownPreservedAsKnownPreserved()
test(False)
except Ice.Exception as ex:
- cb.ice_exception(ex)
+ f.set_exception(ex)
+ return f
- def unknownPreservedAsBase_async(self, cb, r, current=None):
+ def unknownPreservedAsBase(self, r, current=None):
ex = Test.SPreserved2()
ex.b = "base"
ex.kp = "preserved"
ex.kpd = "derived"
ex.p1 = Test.SPreservedClass("bc", "spc")
ex.p2 = ex.p1
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def unknownPreservedAsKnownPreserved_async(self, cb, r, current=None):
+ def unknownPreservedAsKnownPreserved(self, r, current=None):
ex = Test.SPreserved2()
ex.b = "base"
ex.kp = "preserved"
ex.kpd = "derived"
ex.p1 = Test.SPreservedClass("bc", "spc")
ex.p2 = ex.p1
- cb.ice_exception(ex)
+ f = Ice.Future()
+ f.set_exception(ex)
+ return f
- def relayUnknownPreservedAsBase_async(self, cb, r, current=None):
+ def relayUnknownPreservedAsBase(self, r, current=None):
+ f = Ice.Future()
try:
r.unknownPreservedAsBase()
test(False)
except Ice.Exception as ex:
- cb.ice_exception(ex)
+ f.set_exception(ex)
+ return f
- def relayUnknownPreservedAsKnownPreserved_async(self, cb, r, current=None):
+ def relayUnknownPreservedAsKnownPreserved(self, r, current=None):
+ f = Ice.Future()
try:
r.unknownPreservedAsKnownPreserved()
test(False)
except Ice.Exception as ex:
- cb.ice_exception(ex)
+ f.set_exception(ex)
+ return f
def run(args, communicator):
properties = communicator.getProperties()
diff --git a/python/test/Ice/slicing/objects/AllTests.py b/python/test/Ice/slicing/objects/AllTests.py
index 44cd9af1665..cc3a321d5fd 100644
--- a/python/test/Ice/slicing/objects/AllTests.py
+++ b/python/test/Ice/slicing/objects/AllTests.py
@@ -23,22 +23,19 @@ class CallbackBase:
self._cond = threading.Condition()
def check(self):
- self._cond.acquire()
- try:
+ with self._cond:
while not self._called:
self._cond.wait()
self._called = False
- finally:
- self._cond.release()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
class Callback(CallbackBase):
- def response_SBaseAsObject(self, o):
+ def response_SBaseAsObject(self, f):
+ o = f.result()
test(o)
test(o.ice_id() == "::Test::SBase")
sb = o
@@ -46,54 +43,53 @@ class Callback(CallbackBase):
test(sb.sb == "SBase.sb")
self.called()
- def response_SBaseAsSBase(self, sb):
+ def response_SBaseAsSBase(self, f):
+ sb = f.result()
test(sb.sb == "SBase.sb")
self.called()
- def response_SBSKnownDerivedAsSBase(self, sb):
- sbskd = sb
+ def response_SBSKnownDerivedAsSBase(self, f):
+ sbskd = f.result()
test(isinstance(sbskd, Test.SBSKnownDerived))
test(sbskd.sbskd == "SBSKnownDerived.sbskd")
self.called()
- def response_SBSKnownDerivedAsSBSKnownDerived(self, sbskd):
+ def response_SBSKnownDerivedAsSBSKnownDerived(self, f):
+ sbskd = f.result()
test(sbskd.sbskd == "SBSKnownDerived.sbskd")
self.called()
- def response_SBSUnknownDerivedAsSBase(self, sb):
+ def response_SBSUnknownDerivedAsSBase(self, f):
+ sb = f.result()
test(sb.sb == "SBSUnknownDerived.sb")
self.called()
- def response_SBSUnknownDerivedAsSBaseCompact(self, sb):
- test(False)
-
- def exception_SBSUnknownDerivedAsSBaseCompact(self, ex):
- test(isinstance(ex, Ice.NoValueFactoryException))
+ def exception_SBSUnknownDerivedAsSBaseCompact(self, f):
+ test(f.exception() is not None)
+ test(isinstance(f.exception(), Ice.NoValueFactoryException))
self.called()
- def response_SUnknownAsObject10(self, o):
- test(False)
-
- def exception_SUnknownAsObject10(self, exc):
- test(exc.ice_id() == "::Ice::NoValueFactoryException")
+ def exception_SUnknownAsObject10(self, f):
+ test(f.exception() is not None)
+ test(f.exception().ice_id() == "::Ice::NoValueFactoryException")
self.called()
- def response_SUnknownAsObject11(self, o):
+ def response_SUnknownAsObject11(self, f):
+ o = f.result()
test(isinstance(o, Ice.UnknownSlicedObject))
test(o.unknownTypeId == "::Test::SUnknown")
self.called()
- def exception_SUnknownAsObject11(self, exc):
- test(False)
-
- def response_oneElementCycle(self, b):
+ def response_oneElementCycle(self, f):
+ b = f.result()
test(b)
test(b.ice_id() == "::Test::B")
test(b.sb == "B1.sb")
test(b.pb == b)
self.called()
- def response_twoElementCycle(self, b1):
+ def response_twoElementCycle(self, f):
+ b1 = f.result()
test(b1)
test(b1.ice_id() == "::Test::B")
test(b1.sb == "B1.sb")
@@ -105,7 +101,8 @@ class Callback(CallbackBase):
test(b2.pb == b1)
self.called()
- def response_D1AsB(self, b1):
+ def response_D1AsB(self, f):
+ b1 = f.result()
test(b1)
test(b1.ice_id() == "::Test::D1")
test(b1.sb == "D1.sb")
@@ -125,7 +122,8 @@ class Callback(CallbackBase):
test(b2.ice_id() == "::Test::B")
self.called()
- def response_D1AsD1(self, d1):
+ def response_D1AsD1(self, f):
+ d1 = f.result()
test(d1)
test(d1.ice_id() == "::Test::D1")
test(d1.sb == "D1.sb")
@@ -139,7 +137,8 @@ class Callback(CallbackBase):
test(b2.pb == d1)
self.called()
- def response_D2AsB(self, b2):
+ def response_D2AsB(self, f):
+ b2 = f.result()
test(b2)
test(b2.ice_id() == "::Test::B")
test(b2.sb == "D2.sb")
@@ -157,7 +156,8 @@ class Callback(CallbackBase):
test(d1.pd1 == b2)
self.called()
- def response_paramTest1(self, b1, b2):
+ def response_paramTest1(self, f):
+ (b1, b2) = f.result()
test(b1)
test(b1.ice_id() == "::Test::D1")
test(b1.sb == "D1.sb")
@@ -173,19 +173,23 @@ class Callback(CallbackBase):
test(b2.pb == b1)
self.called()
- def response_returnTest1(self, r, p1, p2):
+ def response_returnTest1(self, f):
+ (r, p1, p2) = f.result()
test(r == p1)
self.called()
- def response_returnTest2(self, r, p1, p2):
+ def response_returnTest2(self, f):
+ (r, p1, p2) = f.result()
test(r == p1)
self.called()
- def response_returnTest3(self, b):
+ def response_returnTest3(self, f):
+ b = f.result()
self.r = b
self.called()
- def response_paramTest3(self, ret, p1, p2):
+ def response_paramTest3(self, f):
+ (ret, p1, p2) = f.result()
test(p1)
test(p1.sb == "D2.sb (p1 1)")
test(p1.pb == None)
@@ -202,7 +206,8 @@ class Callback(CallbackBase):
test(ret.ice_id() == "::Test::D1")
self.called()
- def response_paramTest4(self, ret, b):
+ def response_paramTest4(self, f):
+ (ret, b) = f.result()
test(b)
test(b.sb == "D4.sb (1)")
test(b.pb == None)
@@ -214,16 +219,20 @@ class Callback(CallbackBase):
test(ret.ice_id() == "::Test::B")
self.called()
- def response_sequenceTest(self, ss):
+ def response_sequenceTest(self, f):
+ ss = f.result()
self.r = ss
self.called()
- def response_dictionaryTest(self, r, bout):
+ def response_dictionaryTest(self, f):
+ (r, bout) = f.result()
self.r = r
self.bout = bout
self.called()
- def exception_throwBaseAsBase(self, ex):
+ def exception_throwBaseAsBase(self, f):
+ ex = f.exception()
+ test(ex is not None)
test(ex.ice_id() == "::Test::BaseException")
e = ex
test(isinstance(e, Test.BaseException))
@@ -233,7 +242,9 @@ class Callback(CallbackBase):
test(e.pb.pb == e.pb)
self.called()
- def exception_throwDerivedAsBase(self, ex):
+ def exception_throwDerivedAsBase(self, f):
+ ex = f.exception()
+ test(ex is not None)
test(ex.ice_id() == "::Test::DerivedException")
e = ex
test(isinstance(e, Test.DerivedException))
@@ -249,7 +260,9 @@ class Callback(CallbackBase):
test(e.pd1.pd1 == e.pd1)
self.called()
- def exception_throwDerivedAsDerived(self, ex):
+ def exception_throwDerivedAsDerived(self, f):
+ ex = f.exception()
+ test(ex is not None)
test(ex.ice_id() == "::Test::DerivedException")
e = ex
test(isinstance(e, Test.DerivedException))
@@ -265,7 +278,9 @@ class Callback(CallbackBase):
test(e.pd1.pd1 == e.pd1)
self.called()
- def exception_throwUnknownDerivedAsBase(self, ex):
+ def exception_throwUnknownDerivedAsBase(self, f):
+ ex = f.exception()
+ test(ex is not None)
test(ex.ice_id() == "::Test::BaseException")
e = ex
test(isinstance(e, Test.BaseException))
@@ -276,10 +291,12 @@ class Callback(CallbackBase):
self.called()
def response_useForward(self, f):
- test(f)
+ fwd = f.result()
+ test(fwd)
self.called()
- def response_preserved1(self, r):
+ def response_preserved1(self, f):
+ r = f.result()
test(r)
test(isinstance(r, Test.PDerived))
test(r.pi == 3)
@@ -287,30 +304,34 @@ class Callback(CallbackBase):
test(r.pb == r)
self.called()
- def response_preserved2(self, r):
+ def response_preserved2(self, f):
+ r = f.result()
test(r)
test(not isinstance(r, Test.PCUnknown))
test(r.pi == 3)
self.called()
- def response_preserved3(self, r):
+ def response_preserved3(self, f):
#
# Encoding 1.0
#
+ r = f.result()
test(not isinstance(r, Test.PCDerived))
test(r.pi == 3)
self.called()
- def response_preserved4(self, r):
+ def response_preserved4(self, f):
#
# Encoding > 1.0
#
+ r = f.result()
test(isinstance(r, Test.PCDerived))
test(r.pi == 3)
test(r.pbs[0] == r)
self.called()
- def response_preserved5(self, r):
+ def response_preserved5(self, f):
+ r = f.result()
test(isinstance(r, Test.PCDerived3))
test(r.pi == 3)
for i in range(0, 300):
@@ -324,32 +345,25 @@ class Callback(CallbackBase):
test(r.pcd3 == r.pbs[10])
self.called()
- def response_compactPreserved1(self, r):
+ def response_compactPreserved1(self, f):
#
# Encoding 1.0
#
+ r = f.result()
test(not isinstance(r, Test.CompactPCDerived))
test(r.pi == 3)
self.called()
- def response_compactPreserved2(self, r):
+ def response_compactPreserved2(self, f):
#
# Encoding > 1.0
#
+ r = f.result()
test(isinstance(r, Test.CompactPCDerived))
test(r.pi == 3)
test(r.pbs[0] == r)
self.called()
- def response(self):
- test(False)
-
- def exception(self, exc):
- if(isinstance(exc, Ice.OperationNotExistException)):
- self.called()
- return
- test(False)
-
class PNodeI(Test.PNode):
counter = 0
@@ -400,7 +414,7 @@ def allTests(communicator):
sys.stdout.write("base as Object (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_SBaseAsObject(cb.response_SBaseAsObject, cb.exception)
+ t.SBaseAsObjectAsync().add_done_callback(cb.response_SBaseAsObject)
cb.check()
print("ok")
@@ -416,7 +430,7 @@ def allTests(communicator):
sys.stdout.write("base as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_SBaseAsSBase(cb.response_SBaseAsSBase, cb.exception)
+ t.SBaseAsSBaseAsync().add_done_callback(cb.response_SBaseAsSBase)
cb.check()
print("ok")
@@ -436,7 +450,7 @@ def allTests(communicator):
sys.stdout.write("base with known derived as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_SBSKnownDerivedAsSBase(cb.response_SBSKnownDerivedAsSBase, cb.exception)
+ t.SBSKnownDerivedAsSBaseAsync().add_done_callback(cb.response_SBSKnownDerivedAsSBase)
cb.check()
print("ok")
@@ -452,7 +466,7 @@ def allTests(communicator):
sys.stdout.write("base with known derived as known derived (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_SBSKnownDerivedAsSBSKnownDerived(cb.response_SBSKnownDerivedAsSBSKnownDerived, cb.exception)
+ t.SBSKnownDerivedAsSBSKnownDerivedAsync().add_done_callback(cb.response_SBSKnownDerivedAsSBSKnownDerived)
cb.check()
print("ok")
@@ -494,14 +508,14 @@ def allTests(communicator):
sys.stdout.write("base with unknown derived as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_SBSUnknownDerivedAsSBase(cb.response_SBSUnknownDerivedAsSBase, cb.exception)
+ t.SBSUnknownDerivedAsSBaseAsync().add_done_callback(cb.response_SBSUnknownDerivedAsSBase)
cb.check()
if t.ice_getEncodingVersion() == Ice.Encoding_1_0:
#
# This test succeeds for the 1.0 encoding.
#
cb = Callback()
- t.begin_SBSUnknownDerivedAsSBaseCompact(cb.response_SBSUnknownDerivedAsSBase, cb.exception)
+ t.SBSUnknownDerivedAsSBaseCompactAsync().add_done_callback(cb.response_SBSUnknownDerivedAsSBase)
cb.check()
else:
#
@@ -509,8 +523,7 @@ def allTests(communicator):
# be sliced to a known type.
#
cb = Callback()
- t.begin_SBSUnknownDerivedAsSBaseCompact(cb.response_SBSUnknownDerivedAsSBaseCompact,
- cb.exception_SBSUnknownDerivedAsSBaseCompact)
+ t.SBSUnknownDerivedAsSBaseCompactAsync().add_done_callback(cb.exception_SBSUnknownDerivedAsSBaseCompact)
cb.check()
print("ok")
@@ -533,9 +546,9 @@ def allTests(communicator):
try:
cb = Callback()
if t.ice_getEncodingVersion() == Ice.Encoding_1_0:
- t.begin_SUnknownAsObject(cb.response_SUnknownAsObject10, cb.exception_SUnknownAsObject10)
+ t.SUnknownAsObjectAsync().add_done_callback(cb.exception_SUnknownAsObject10)
else:
- t.begin_SUnknownAsObject(cb.response_SUnknownAsObject11, cb.exception_SUnknownAsObject11)
+ t.SUnknownAsObjectAsync().add_done_callback(cb.response_SUnknownAsObject11)
cb.check()
except Ice.Exception:
test(False)
@@ -556,7 +569,7 @@ def allTests(communicator):
sys.stdout.write("one-element cycle (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_oneElementCycle(cb.response_oneElementCycle, cb.exception)
+ t.oneElementCycleAsync().add_done_callback(cb.response_oneElementCycle)
cb.check()
print("ok")
@@ -580,7 +593,7 @@ def allTests(communicator):
sys.stdout.write("two-element cycle (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_twoElementCycle(cb.response_twoElementCycle, cb.exception)
+ t.twoElementCycleAsync().add_done_callback(cb.response_twoElementCycle)
cb.check()
print("ok")
@@ -612,7 +625,7 @@ def allTests(communicator):
sys.stdout.write("known derived pointer slicing as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_D1AsB(cb.response_D1AsB, cb.exception)
+ t.D1AsBAsync().add_done_callback(cb.response_D1AsB)
cb.check()
print("ok")
@@ -638,7 +651,7 @@ def allTests(communicator):
sys.stdout.write("known derived pointer slicing as derived (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_D1AsD1(cb.response_D1AsD1, cb.exception)
+ t.D1AsD1Async().add_done_callback(cb.response_D1AsD1)
cb.check()
print("ok")
@@ -668,7 +681,7 @@ def allTests(communicator):
sys.stdout.write("unknown derived pointer slicing as base (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_D2AsB(cb.response_D2AsB, cb.exception)
+ t.D2AsBAsync().add_done_callback(cb.response_D2AsB)
cb.check()
print("ok")
@@ -697,7 +710,7 @@ def allTests(communicator):
sys.stdout.write("param ptr slicing with known first (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_paramTest1(cb.response_paramTest1, cb.exception)
+ t.paramTest1Async().add_done_callback(cb.response_paramTest1)
cb.check()
print("ok")
@@ -735,7 +748,7 @@ def allTests(communicator):
sys.stdout.write("return value identity with known first (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_returnTest1(cb.response_returnTest1, cb.exception)
+ t.returnTest1Async().add_done_callback(cb.response_returnTest1)
cb.check()
print("ok")
@@ -751,7 +764,7 @@ def allTests(communicator):
sys.stdout.write("return value identity with unknown first (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_returnTest2(cb.response_returnTest2, cb.exception)
+ t.returnTest2Async().add_done_callback(cb.response_returnTest2)
cb.check()
print("ok")
@@ -810,7 +823,7 @@ def allTests(communicator):
d1.pd1 = d3
cb = Callback()
- t.begin_returnTest3(d1, d3, cb.response_returnTest3, cb.exception)
+ t.returnTest3Async(d1, d3).add_done_callback(cb.response_returnTest3)
cb.check()
b1 = cb.r
@@ -893,7 +906,7 @@ def allTests(communicator):
d1.pd1 = d3
cb = Callback()
- t.begin_returnTest3(d3, d1, cb.response_returnTest3, cb.exception)
+ t.returnTest3Async(d3, d1).add_done_callback(cb.response_returnTest3)
cb.check()
b1 = cb.r
@@ -947,7 +960,7 @@ def allTests(communicator):
sys.stdout.write("remainder unmarshaling (3 instances) (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_paramTest3(cb.response_paramTest3, cb.exception)
+ t.paramTest3Async().add_done_callback(cb.response_paramTest3)
cb.check()
print("ok")
@@ -972,7 +985,7 @@ def allTests(communicator):
sys.stdout.write("remainder unmarshaling (4 instances) (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_paramTest4(cb.response_paramTest4, cb.exception)
+ t.paramTest4Async().add_done_callback(cb.response_paramTest4)
cb.check()
print("ok")
@@ -1021,7 +1034,7 @@ def allTests(communicator):
b2.pb = b1
cb = Callback()
- t.begin_returnTest3(d3, b2, cb.response_returnTest3, cb.exception)
+ t.returnTest3Async(d3, b2).add_done_callback(cb.response_returnTest3)
cb.check()
r = cb.r
@@ -1085,7 +1098,7 @@ def allTests(communicator):
d12.pd1 = d11
cb = Callback()
- t.begin_returnTest3(d3, d12, cb.response_returnTest3, cb.exception)
+ t.returnTest3Async(d3, d12).add_done_callback(cb.response_returnTest3)
cb.check()
r = cb.r
@@ -1218,7 +1231,7 @@ def allTests(communicator):
ss2.s = (ss2b, ss2d1, ss2d3)
cb = Callback()
- t.begin_sequenceTest(ss1, ss2, cb.response_sequenceTest, cb.exception)
+ t.sequenceTestAsync(ss1, ss2).add_done_callback(cb.response_sequenceTest)
cb.check()
ss = cb.r
@@ -1310,7 +1323,7 @@ def allTests(communicator):
bin[i] = d1
cb = Callback()
- t.begin_dictionaryTest(bin, cb.response_dictionaryTest, cb.exception)
+ t.dictionaryTestAsync(bin).add_done_callback(cb.response_dictionaryTest)
cb.check()
bout = cb.bout
r = cb.r
@@ -1362,7 +1375,7 @@ def allTests(communicator):
sys.stdout.write("base exception thrown as base exception (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_throwBaseAsBase(cb.response, cb.exception_throwBaseAsBase)
+ t.throwBaseAsBaseAsync().add_done_callback(cb.exception_throwBaseAsBase)
cb.check()
print("ok")
@@ -1390,7 +1403,7 @@ def allTests(communicator):
sys.stdout.write("derived exception thrown as base exception (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_throwDerivedAsBase(cb.response, cb.exception_throwDerivedAsBase)
+ t.throwDerivedAsBaseAsync().add_done_callback(cb.exception_throwDerivedAsBase)
cb.check()
print("ok")
@@ -1418,7 +1431,7 @@ def allTests(communicator):
sys.stdout.write("derived exception thrown as derived exception (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_throwDerivedAsDerived(cb.response, cb.exception_throwDerivedAsDerived)
+ t.throwDerivedAsDerivedAsync().add_done_callback(cb.exception_throwDerivedAsDerived)
cb.check()
print("ok")
@@ -1440,7 +1453,7 @@ def allTests(communicator):
sys.stdout.write("unknown derived exception thrown as base exception (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_throwUnknownDerivedAsBase(cb.response, cb.exception_throwUnknownDerivedAsBase)
+ t.throwUnknownDerivedAsBaseAsync().add_done_callback(cb.exception_throwUnknownDerivedAsBase)
cb.check()
print("ok")
@@ -1456,7 +1469,7 @@ def allTests(communicator):
sys.stdout.write("forward-declared class (AMI)... ")
sys.stdout.flush()
cb = Callback()
- t.begin_useForward(cb.response_useForward, cb.exception)
+ t.useForwardAsync().add_done_callback(cb.response_useForward)
cb.check()
print("ok")
@@ -1586,7 +1599,7 @@ def allTests(communicator):
pd.pb = pd
cb = Callback()
- t.begin_exchangePBase(pd, cb.response_preserved1, cb.exception)
+ t.exchangePBaseAsync(pd).add_done_callback(cb.response_preserved1)
cb.check()
#
@@ -1597,7 +1610,7 @@ def allTests(communicator):
pu.pu = "preserved"
cb = Callback()
- t.begin_exchangePBase(pu, cb.response_preserved2, cb.exception)
+ t.exchangePBaseAsync(pu).add_done_callback(cb.response_preserved2)
cb.check()
#
@@ -1610,9 +1623,9 @@ def allTests(communicator):
cb = Callback()
if t.ice_getEncodingVersion() == Ice.Encoding_1_0:
- t.begin_exchangePBase(pcd, cb.response_preserved3, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_preserved3)
else:
- t.begin_exchangePBase(pcd, cb.response_preserved4, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_preserved4)
cb.check()
#
@@ -1625,9 +1638,9 @@ def allTests(communicator):
cb = Callback()
if t.ice_getEncodingVersion() == Ice.Encoding_1_0:
- t.begin_exchangePBase(pcd, cb.response_compactPreserved1, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_compactPreserved1)
else:
- t.begin_exchangePBase(pcd, cb.response_compactPreserved2, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_compactPreserved2)
cb.check()
#
@@ -1651,9 +1664,9 @@ def allTests(communicator):
cb = Callback()
if t.ice_getEncodingVersion() == Ice.Encoding_1_0:
- t.begin_exchangePBase(pcd, cb.response_preserved3, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_preserved3)
else:
- t.begin_exchangePBase(pcd, cb.response_preserved5, cb.exception)
+ t.exchangePBaseAsync(pcd).add_done_callback(cb.response_preserved5)
cb.check()
print("ok")
diff --git a/python/test/Ice/slicing/objects/Server.py b/python/test/Ice/slicing/objects/Server.py
index e785fe0f8ab..53b522a6462 100755
--- a/python/test/Ice/slicing/objects/Server.py
+++ b/python/test/Ice/slicing/objects/Server.py
@@ -244,7 +244,7 @@ class TestI(Test.TestIntf):
test(p.psu == "unknown")
test(not p.graph)
- def PBSUnknownAsPreservedWithGraph_async(self, cb, current=None):
+ def PBSUnknownAsPreservedWithGraph(self, current=None):
r = Test.PSUnknown()
r.pi = 5
r.ps = "preserved"
@@ -253,8 +253,8 @@ class TestI(Test.TestIntf):
r.graph.next = Test.PNode()
r.graph.next.next = Test.PNode()
r.graph.next.next.next = r.graph
- cb.ice_response(r)
- r.graph.next.next.next = None # Break the cycle.
+ return Ice.Future.completed(r)
+ #r.graph.next.next.next = None # Break the cycle.
def checkPBSUnknownWithGraph(self, p, current=None):
if current.encoding == Ice.Encoding_1_0:
@@ -271,13 +271,13 @@ class TestI(Test.TestIntf):
test(p.graph.next.next.next == p.graph)
p.graph.next.next.next = None # Break the cycle.
- def PBSUnknown2AsPreservedWithGraph_async(self, cb, current=None):
+ def PBSUnknown2AsPreservedWithGraph(self, current=None):
r = Test.PSUnknown2()
r.pi = 5
r.ps = "preserved"
r.pb = r
- cb.ice_response(r)
- r.pb = None # Break the cycle.
+ return Ice.Future.completed(r)
+ #r.pb = None # Break the cycle.
def checkPBSUnknown2WithGraph(self, p, current=None):
if current.encoding == Ice.Encoding_1_0:
@@ -344,14 +344,16 @@ class TestI(Test.TestIntf):
ude.pd2 = d2
raise ude
- def throwPreservedException_async(self, cb, current=None):
+ def throwPreservedException(self, current=None):
ue = Test.PSUnknownException()
ue.p = Test.PSUnknown2()
ue.p.pi = 5
ue.p.ps = "preserved"
ue.p.pb = ue.p
- cb.ice_exception(ue)
- ue.p.pb = None # Break the cycle.
+ f = Ice.Future()
+ f.set_exception(ue)
+ return f
+ #ue.p.pb = None # Break the cycle.
def useForward(self, current=None):
f = Test.Forward()
diff --git a/python/test/Ice/slicing/objects/ServerAMD.py b/python/test/Ice/slicing/objects/ServerAMD.py
index d42a174b213..fc5f63ca732 100755
--- a/python/test/Ice/slicing/objects/ServerAMD.py
+++ b/python/test/Ice/slicing/objects/ServerAMD.py
@@ -19,69 +19,69 @@ def test(b):
raise RuntimeError('test assertion failed')
class TestI(Test.TestIntf):
- def SBaseAsObject_async(self, cb, current=None):
+ def SBaseAsObject(self, current=None):
sb = Test.SBase()
sb.sb = "SBase.sb"
- cb.ice_response(sb)
+ return Ice.Future.completed(sb)
- def SBaseAsSBase_async(self, cb, current=None):
+ def SBaseAsSBase(self, current=None):
sb = Test.SBase()
sb.sb = "SBase.sb"
- cb.ice_response(sb)
+ return Ice.Future.completed(sb)
- def SBSKnownDerivedAsSBase_async(self, cb, current=None):
+ def SBSKnownDerivedAsSBase(self, current=None):
sbskd = Test.SBSKnownDerived()
sbskd.sb = "SBSKnownDerived.sb"
sbskd.sbskd = "SBSKnownDerived.sbskd"
- cb.ice_response(sbskd)
+ return Ice.Future.completed(sbskd)
- def SBSKnownDerivedAsSBSKnownDerived_async(self, cb, current=None):
+ def SBSKnownDerivedAsSBSKnownDerived(self, current=None):
sbskd = Test.SBSKnownDerived()
sbskd.sb = "SBSKnownDerived.sb"
sbskd.sbskd = "SBSKnownDerived.sbskd"
- cb.ice_response(sbskd)
+ return Ice.Future.completed(sbskd)
- def SBSUnknownDerivedAsSBase_async(self, cb, current=None):
+ def SBSUnknownDerivedAsSBase(self, current=None):
sbsud = Test.SBSUnknownDerived()
sbsud.sb = "SBSUnknownDerived.sb"
sbsud.sbsud = "SBSUnknownDerived.sbsud"
- cb.ice_response(sbsud)
+ return Ice.Future.completed(sbsud)
- def SBSUnknownDerivedAsSBaseCompact_async(self, cb, current=None):
+ def SBSUnknownDerivedAsSBaseCompact(self, current=None):
sbsud = Test.SBSUnknownDerived()
sbsud.sb = "SBSUnknownDerived.sb"
sbsud.sbsud = "SBSUnknownDerived.sbsud"
- cb.ice_response(sbsud)
+ return Ice.Future.completed(sbsud)
- def SUnknownAsObject_async(self, cb, current=None):
+ def SUnknownAsObject(self, current=None):
su = Test.SUnknown()
su.su = "SUnknown.su"
- cb.ice_response(su)
+ return Ice.Future.completed(su)
- def checkSUnknown_async(self, cb, obj, current=None):
+ def checkSUnknown(self, obj, current=None):
if current.encoding == Ice.Encoding_1_0:
test(not isinstance(obj, Test.SUnknown))
else:
test(isinstance(obj, Test.SUnknown))
test(obj.su == "SUnknown.su")
- cb.ice_response()
+ return Ice.Future.completed(None)
- def oneElementCycle_async(self, cb, current=None):
+ def oneElementCycle(self, current=None):
b = Test.B()
b.sb = "B1.sb"
b.pb = b
- cb.ice_response(b)
+ return Ice.Future.completed(b)
- def twoElementCycle_async(self, cb, current=None):
+ def twoElementCycle(self, current=None):
b1 = Test.B()
b1.sb = "B1.sb"
b2 = Test.B()
b2.sb = "B2.sb"
b2.pb = b1
b1.pb = b2
- cb.ice_response(b1)
+ return Ice.Future.completed(b1)
- def D1AsB_async(self, cb, current=None):
+ def D1AsB(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -92,9 +92,9 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d1)
+ return Ice.Future.completed(d1)
- def D1AsD1_async(self, cb, current=None):
+ def D1AsD1(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -105,9 +105,9 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d1)
+ return Ice.Future.completed(d1)
- def D2AsB_async(self, cb, current=None):
+ def D2AsB(self, current=None):
d2 = Test.D2()
d2.sb = "D2.sb"
d2.sd2 = "D2.sd2"
@@ -118,9 +118,9 @@ class TestI(Test.TestIntf):
d1.pd1 = d2
d2.pb = d1
d2.pd2 = d1
- cb.ice_response(d2)
+ return Ice.Future.completed(d2)
- def paramTest1_async(self, cb, current=None):
+ def paramTest1(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -131,9 +131,9 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d1, d2)
+ return Ice.Future.completed((d1, d2))
- def paramTest2_async(self, cb, current=None):
+ def paramTest2(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -144,9 +144,9 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d2, d1)
+ return Ice.Future.completed((d2, d1))
- def paramTest3_async(self, cb, current=None):
+ def paramTest3(self, current=None):
d2 = Test.D2()
d2.sb = "D2.sb (p1 1)"
d2.pb = None
@@ -171,9 +171,9 @@ class TestI(Test.TestIntf):
d3.pd1 = None
d4.pd2 = d3
- cb.ice_response(d3, d2, d4)
+ return Ice.Future.completed((d3, d2, d4))
- def paramTest4_async(self, cb, current=None):
+ def paramTest4(self, current=None):
d4 = Test.D4()
d4.sb = "D4.sb (1)"
d4.pb = None
@@ -183,9 +183,9 @@ class TestI(Test.TestIntf):
d4.p2 = Test.B()
d4.p2.sb = "B.sb (2)"
d4.p2.pb = None
- cb.ice_response(d4.p2, d4)
+ return Ice.Future.completed((d4.p2, d4))
- def returnTest1_async(self, cb, current=None):
+ def returnTest1(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -196,9 +196,9 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d2, d2, d1)
+ return Ice.Future.completed((d2, d2, d1))
- def returnTest2_async(self, cb, current=None):
+ def returnTest2(self, current=None):
d1 = Test.D1()
d1.sb = "D1.sb"
d1.sd1 = "D1.sd1"
@@ -209,18 +209,18 @@ class TestI(Test.TestIntf):
d2.pd2 = d1
d1.pb = d2
d1.pd1 = d2
- cb.ice_response(d1, d1, d2)
+ return Ice.Future.completed((d1, d1, d2))
- def returnTest3_async(self, cb, p1, p2, current=None):
- cb.ice_response(p1)
+ def returnTest3(self, p1, p2, current=None):
+ return Ice.Future.completed(p1)
- def sequenceTest_async(self, cb, p1, p2, current=None):
+ def sequenceTest(self, p1, p2, current=None):
ss = Test.SS3()
ss.c1 = p1
ss.c2 = p2
- cb.ice_response(ss)
+ return Ice.Future.completed(ss)
- def dictionaryTest_async(self, cb, bin, current=None):
+ def dictionaryTest(self, bin, current=None):
bout = {}
for i in range(0, 10):
b = bin[i]
@@ -244,20 +244,20 @@ class TestI(Test.TestIntf):
d1.pd1 = d1
r[i * 20] = d1
- cb.ice_response(r, bout)
+ return Ice.Future.completed((r, bout))
- def exchangePBase_async(self, cb, pb, current=None):
- cb.ice_response(pb)
+ def exchangePBase(self, pb, current=None):
+ return Ice.Future.completed(pb)
- def PBSUnknownAsPreserved_async(self, cb, current=None):
+ def PBSUnknownAsPreserved(self, current=None):
r = Test.PSUnknown()
r.pi = 5
r.ps = "preserved"
r.psu = "unknown"
r.graph = None
- cb.ice_response(r)
+ return Ice.Future.completed(r)
- def checkPBSUnknown_async(self, cb, p, current=None):
+ def checkPBSUnknown(self, p, current=None):
if current.encoding == Ice.Encoding_1_0:
test(not isinstance(p, Test.PSUnknown))
test(p.pi == 5)
@@ -268,9 +268,9 @@ class TestI(Test.TestIntf):
test(p.ps == "preserved")
test(p.psu == "unknown")
test(not p.graph)
- cb.ice_response()
+ return Ice.Future.completed(None)
- def PBSUnknownAsPreservedWithGraph_async(self, cb, current=None):
+ def PBSUnknownAsPreservedWithGraph(self, current=None):
r = Test.PSUnknown()
r.pi = 5
r.ps = "preserved"
@@ -279,10 +279,10 @@ class TestI(Test.TestIntf):
r.graph.next = Test.PNode()
r.graph.next.next = Test.PNode()
r.graph.next.next.next = r.graph
- cb.ice_response(r)
- r.graph.next.next.next = None # Break the cycle.
+ return Ice.Future.completed(r)
+ #r.graph.next.next.next = None # Break the cycle.
- def checkPBSUnknownWithGraph_async(self, cb, p, current=None):
+ def checkPBSUnknownWithGraph(self, p, current=None):
if current.encoding == Ice.Encoding_1_0:
test(not isinstance(p, Test.PSUnknown))
test(p.pi == 5)
@@ -296,17 +296,17 @@ class TestI(Test.TestIntf):
test(p.graph.next != p.graph.next.next)
test(p.graph.next.next.next == p.graph)
p.graph.next.next.next = None # Break the cycle.
- cb.ice_response()
+ return Ice.Future.completed(None)
- def PBSUnknown2AsPreservedWithGraph_async(self, cb, current=None):
+ def PBSUnknown2AsPreservedWithGraph(self, current=None):
r = Test.PSUnknown2()
r.pi = 5
r.ps = "preserved"
r.pb = r
- cb.ice_response(r)
- r.pb = None # Break the cycle.
+ return Ice.Future.completed(r)
+ #r.pb = None # Break the cycle.
- def checkPBSUnknown2WithGraph_async(self, cb, p, current=None):
+ def checkPBSUnknown2WithGraph(self, p, current=None):
if current.encoding == Ice.Encoding_1_0:
test(not isinstance(p, Test.PSUnknown2))
test(p.pi == 5)
@@ -317,20 +317,22 @@ class TestI(Test.TestIntf):
test(p.ps == "preserved")
test(p.pb == p)
p.pb = None # Break the cycle.
- cb.ice_response()
+ return Ice.Future.completed(None)
- def exchangePNode_async(self, cb, pn, current=None):
- cb.ice_response(pn)
+ def exchangePNode(self, pn, current=None):
+ return Ice.Future.completed(pn)
- def throwBaseAsBase_async(self, cb, current=None):
+ def throwBaseAsBase(self, current=None):
be = Test.BaseException()
be.sbe = "sbe"
be.pb = Test.B()
be.pb.sb = "sb"
be.pb.pb = be.pb
- cb.ice_exception(be)
+ f = Ice.Future()
+ f.set_exception(be)
+ return f
- def throwDerivedAsBase_async(self, cb, current=None):
+ def throwDerivedAsBase(self, current=None):
de = Test.DerivedException()
de.sbe = "sbe"
de.pb = Test.B()
@@ -342,9 +344,11 @@ class TestI(Test.TestIntf):
de.pd1.pb = de.pd1
de.pd1.sd1 = "sd2"
de.pd1.pd1 = de.pd1
- cb.ice_exception(de)
+ f = Ice.Future()
+ f.set_exception(de)
+ return f
- def throwDerivedAsDerived_async(self, cb, current=None):
+ def throwDerivedAsDerived(self, current=None):
de = Test.DerivedException()
de.sbe = "sbe"
de.pb = Test.B()
@@ -356,9 +360,11 @@ class TestI(Test.TestIntf):
de.pd1.pb = de.pd1
de.pd1.sd1 = "sd2"
de.pd1.pd1 = de.pd1
- cb.ice_exception(de)
+ f = Ice.Future()
+ f.set_exception(de)
+ return f
- def throwUnknownDerivedAsBase_async(self, cb, current=None):
+ def throwUnknownDerivedAsBase(self, current=None):
d2 = Test.D2()
d2.sb = "sb d2"
d2.pb = d2
@@ -370,26 +376,29 @@ class TestI(Test.TestIntf):
ude.pb = d2
ude.sude = "sude"
ude.pd2 = d2
- cb.ice_exception(ude)
+ f = Ice.Future()
+ f.set_exception(ude)
+ return f
- def throwPreservedException_async(self, cb, current=None):
+ def throwPreservedException(self, current=None):
ue = Test.PSUnknownException()
ue.p = Test.PSUnknown2()
ue.p.pi = 5
ue.p.ps = "preserved"
ue.p.pb = ue.p
- cb.ice_exception(ue)
- ue.p.pb = None # Break the cycle.
-
- def useForward_async(self, cb, current=None):
- f = Test.Forward()
- f.h = Test.Hidden()
- f.h.f = f
- cb.ice_response(f)
-
- def shutdown_async(self, cb, current=None):
+ f = Ice.Future()
+ f.set_exception(ue)
+ return f
+ #ue.p.pb = None # Break the cycle.
+
+ def useForward(self, current=None):
+ fwd = Test.Forward()
+ fwd.h = Test.Hidden()
+ fwd.h.f = fwd
+ return Ice.Future.completed(fwd)
+
+ def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
- cb.ice_response()
def run(args, communicator):
properties = communicator.getProperties()
diff --git a/python/test/Ice/timeout/AllTests.py b/python/test/Ice/timeout/AllTests.py
index fd90bdad679..16d3d0484f8 100644
--- a/python/test/Ice/timeout/AllTests.py
+++ b/python/test/Ice/timeout/AllTests.py
@@ -19,17 +19,16 @@ class CallbackBase:
self._cond = threading.Condition()
def called(self):
- self._cond.acquire()
- self._called = True
- self._cond.notify()
- self._cond.release()
+ with self._cond:
+ self._called = True
+ self._cond.notify()
def check(self):
- self._cond.acquire()
- while not self._called:
- self._cond.wait()
- self._called = False
- return True
+ with self._cond:
+ while not self._called:
+ self._cond.wait()
+ self._called = False
+ return True
class Callback(CallbackBase):
def response(self):
diff --git a/python/test/Slice/keyword/Client.py b/python/test/Slice/keyword/Client.py
index a81722b544d..4bbb984634f 100755
--- a/python/test/Slice/keyword/Client.py
+++ b/python/test/Slice/keyword/Client.py
@@ -23,7 +23,7 @@ Ice.loadSlice('Key.ice')
import _and
class delI(_and._del):
- def _elif_async(self, _cb, _else, current=None):
+ def _elifAsync(self, _else, current=None):
pass
class execI(_and._exec):
@@ -35,7 +35,7 @@ class forI(_and._for):
pass
class ifI(_and._if):
- def _elif_async(self, _cb, _else, current=None):
+ def _elifAsync(self, _else, current=None):
pass
def _finally(self, current=None):
pass