summaryrefslogtreecommitdiff
path: root/python/modules
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2017-01-30 13:45:21 -0800
committerMark Spruiell <mes@zeroc.com>2017-01-30 13:45:21 -0800
commit61270a10f980933cf582edb766f10c8ac6d86e8a (patch)
tree45ab4a7c2986954054fce613bc3c8f7967e7951e /python/modules
parentFix slice2cpp build failure (diff)
downloadice-61270a10f980933cf582edb766f10c8ac6d86e8a.tar.bz2
ice-61270a10f980933cf582edb766f10c8ac6d86e8a.tar.xz
ice-61270a10f980933cf582edb766f10c8ac6d86e8a.zip
merging IceBridge into master
Diffstat (limited to 'python/modules')
-rw-r--r--python/modules/IcePy/Connection.cpp233
-rw-r--r--python/modules/IcePy/Util.cpp4
2 files changed, 226 insertions, 11 deletions
diff --git a/python/modules/IcePy/Connection.cpp b/python/modules/IcePy/Connection.cpp
index ec1e4f8db68..8e9e9286d02 100644
--- a/python/modules/IcePy/Connection.cpp
+++ b/python/modules/IcePy/Connection.cpp
@@ -37,18 +37,18 @@ struct ConnectionObject
Ice::CommunicatorPtr* communicator;
};
-class CloseCallbackI : public Ice::CloseCallback
+class CloseCallbackWrapper : public Ice::CloseCallback
{
public:
- CloseCallbackI(PyObject* cb, PyObject* con) :
+ CloseCallbackWrapper(PyObject* cb, PyObject* con) :
_cb(cb), _con(con)
{
Py_INCREF(cb);
Py_INCREF(con);
}
- virtual ~CloseCallbackI()
+ virtual ~CloseCallbackWrapper()
{
AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
@@ -94,18 +94,18 @@ private:
PyObject* _con;
};
-class HeartbeatCallbackI : public Ice::HeartbeatCallback
+class HeartbeatCallbackWrapper : public Ice::HeartbeatCallback
{
public:
- HeartbeatCallbackI(PyObject* cb, PyObject* con) :
+ HeartbeatCallbackWrapper(PyObject* cb, PyObject* con) :
_cb(cb), _con(con)
{
Py_INCREF(cb);
Py_INCREF(con);
}
- virtual ~HeartbeatCallbackI()
+ virtual ~HeartbeatCallbackWrapper()
{
AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
@@ -151,6 +151,62 @@ private:
PyObject* _con;
};
+class HeartbeatAsyncCallback : public IceUtil::Shared
+{
+public:
+
+ HeartbeatAsyncCallback(PyObject* ex, PyObject* sent, const string& op) :
+ _ex(ex), _sent(sent), _op(op)
+ {
+ assert(_ex);
+ Py_INCREF(_ex);
+ Py_XINCREF(_sent);
+ }
+
+ ~HeartbeatAsyncCallback()
+ {
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ Py_DECREF(_ex);
+ Py_XDECREF(_sent);
+ }
+
+ void exception(const Ice::Exception& ex)
+ {
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+
+ PyObjectHandle exh = convertException(ex);
+ assert(exh.get());
+ PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), exh.get());
+ PyObjectHandle tmp = PyObject_Call(_ex, args.get(), 0);
+ if(PyErr_Occurred())
+ {
+ throwPythonException(); // Callback raised an exception.
+ }
+ }
+
+ void sent(bool sentSynchronously)
+ {
+ if(_sent)
+ {
+ AdoptThread adoptThread; // Ensure the current thread is able to call into Python.
+ PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), sentSynchronously ? getTrue() : getFalse());
+ PyObjectHandle tmp = PyObject_Call(_sent, args.get(), 0);
+ if(PyErr_Occurred())
+ {
+ throwPythonException(); // Callback raised an exception.
+ }
+ }
+ }
+
+protected:
+
+ PyObject* _ex;
+ PyObject* _sent;
+ std::string _op;
+};
+typedef IceUtil::Handle<HeartbeatAsyncCallback> HeartbeatAsyncCallbackPtr;
+
}
#ifdef WIN32
@@ -241,17 +297,22 @@ extern "C"
static PyObject*
connectionClose(ConnectionObject* self, PyObject* args)
{
- int force;
- if(!PyArg_ParseTuple(args, STRCAST("i"), &force))
+ PyObject* closeType = lookupType("Ice.ConnectionClose");
+ PyObject* mode;
+ if(!PyArg_ParseTuple(args, STRCAST("O!"), closeType, &mode))
{
return 0;
}
+ PyObjectHandle v = PyObject_GetAttrString(mode, STRCAST("_value"));
+ assert(v.get());
+ Ice::ConnectionClose cc = static_cast<Ice::ConnectionClose>(PyLong_AsLong(v.get()));
+
assert(self->connection);
try
{
AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations.
- (*self->connection)->close(force > 0);
+ (*self->connection)->close(cc);
}
catch(const Ice::Exception& ex)
{
@@ -532,7 +593,7 @@ connectionSetCloseCallback(ConnectionObject* self, PyObject* args)
return 0;
}
- Ice::CloseCallbackPtr wrapper = new CloseCallbackI(cb, reinterpret_cast<PyObject*>(self));
+ Ice::CloseCallbackPtr wrapper = new CloseCallbackWrapper(cb, reinterpret_cast<PyObject*>(self));
try
{
AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations.
@@ -563,7 +624,7 @@ connectionSetHeartbeatCallback(ConnectionObject* self, PyObject* args)
return 0;
}
- Ice::HeartbeatCallbackPtr wrapper = new HeartbeatCallbackI(cb, reinterpret_cast<PyObject*>(self));
+ Ice::HeartbeatCallbackPtr wrapper = new HeartbeatCallbackWrapper(cb, reinterpret_cast<PyObject*>(self));
try
{
AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations.
@@ -583,6 +644,127 @@ connectionSetHeartbeatCallback(ConnectionObject* self, PyObject* args)
extern "C"
#endif
static PyObject*
+connectionHeartbeat(ConnectionObject* self)
+{
+ assert(self->connection);
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+ (*self->connection)->heartbeat();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
+connectionBeginHeartbeat(ConnectionObject* self, PyObject* args, PyObject* kwds)
+{
+ assert(self->connection);
+
+ static char* argNames[] =
+ {
+ const_cast<char*>("_ex"),
+ const_cast<char*>("_sent"),
+ 0
+ };
+ PyObject* ex = Py_None;
+ PyObject* sent = Py_None;
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &ex, &sent))
+ {
+ return 0;
+ }
+
+ if(ex == Py_None)
+ {
+ ex = 0;
+ }
+ if(sent == Py_None)
+ {
+ sent = 0;
+ }
+
+ if(!ex && sent)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ STRCAST("exception callback must also be provided when sent callback is used"));
+ return 0;
+ }
+
+ Ice::Callback_Connection_heartbeatPtr cb;
+ if(ex || sent)
+ {
+ HeartbeatAsyncCallbackPtr d = new HeartbeatAsyncCallback(ex, sent, "heartbeat");
+ cb = Ice::newCallback_Connection_heartbeat(d, &HeartbeatAsyncCallback::exception,
+ &HeartbeatAsyncCallback::sent);
+ }
+
+ Ice::AsyncResultPtr result;
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations.
+
+ if(cb)
+ {
+ result = (*self->connection)->begin_heartbeat(cb);
+ }
+ else
+ {
+ result = (*self->connection)->begin_heartbeat();
+ }
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ PyObjectHandle communicator = getCommunicatorWrapper(*self->communicator);
+ return createAsyncResult(result, 0, reinterpret_cast<PyObject*>(self), communicator.get());
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
+connectionEndHeartbeat(ConnectionObject* self, PyObject* args)
+{
+ assert(self->connection);
+
+ PyObject* result;
+ if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result))
+ {
+ return 0;
+ }
+
+ Ice::AsyncResultPtr r = getAsyncResult(result);
+ try
+ {
+ AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations.
+ (*self->connection)->end_flushBatchRequests(r);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
connectionSetACM(ConnectionObject* self, PyObject* args)
{
assert(self->connection);
@@ -853,6 +1035,27 @@ connectionSetBufferSize(ConnectionObject* self, PyObject* args)
return Py_None;
}
+#ifdef WIN32
+extern "C"
+#endif
+static PyObject*
+connectionThrowException(ConnectionObject* self)
+{
+ assert(self->connection);
+ try
+ {
+ (*self->connection)->throwException();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ setPythonException(ex);
+ return 0;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyMethodDef ConnectionMethods[] =
{
{ STRCAST("close"), reinterpret_cast<PyCFunction>(connectionClose), METH_VARARGS,
@@ -875,6 +1078,12 @@ static PyMethodDef ConnectionMethods[] =
PyDoc_STR(STRCAST("setCloseCallback(Ice.CloseCallback) -> None")) },
{ STRCAST("setHeartbeatCallback"), reinterpret_cast<PyCFunction>(connectionSetHeartbeatCallback), METH_VARARGS,
PyDoc_STR(STRCAST("setHeartbeatCallback(Ice.HeartbeatCallback) -> None")) },
+ { STRCAST("heartbeat"), reinterpret_cast<PyCFunction>(connectionHeartbeat), METH_NOARGS,
+ PyDoc_STR(STRCAST("heartbeat() -> None")) },
+ { STRCAST("begin_heartbeat"), reinterpret_cast<PyCFunction>(connectionBeginHeartbeat),
+ METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_heartbeat([_ex][, _sent]) -> Ice.AsyncResult")) },
+ { STRCAST("end_heartbeat"), reinterpret_cast<PyCFunction>(connectionEndHeartbeat), METH_VARARGS,
+ PyDoc_STR(STRCAST("end_heartbeat(Ice.AsyncResult) -> None")) },
{ STRCAST("setACM"), reinterpret_cast<PyCFunction>(connectionSetACM), METH_VARARGS,
PyDoc_STR(STRCAST("setACM(int, Ice.ACMClose, Ice.ACMHeartbeat) -> None")) },
{ STRCAST("getACM"), reinterpret_cast<PyCFunction>(connectionGetACM), METH_NOARGS,
@@ -891,6 +1100,8 @@ static PyMethodDef ConnectionMethods[] =
PyDoc_STR(STRCAST("getEndpoint() -> Ice.Endpoint")) },
{ STRCAST("setBufferSize"), reinterpret_cast<PyCFunction>(connectionSetBufferSize), METH_VARARGS,
PyDoc_STR(STRCAST("setBufferSize(int, int) -> None")) },
+ { STRCAST("throwException"), reinterpret_cast<PyCFunction>(connectionThrowException), METH_NOARGS,
+ PyDoc_STR(STRCAST("throwException() -> None")) },
{ 0, 0 } /* sentinel */
};
diff --git a/python/modules/IcePy/Util.cpp b/python/modules/IcePy/Util.cpp
index 953bbee84a0..c3b8f18462c 100644
--- a/python/modules/IcePy/Util.cpp
+++ b/python/modules/IcePy/Util.cpp
@@ -857,6 +857,10 @@ convertLocalException(const Ice::LocalException& ex, PyObject* p)
IcePy::PyObjectHandle m = IcePy::createString(e.reason);
PyObject_SetAttrString(p, STRCAST("reason"), m.get());
}
+ catch(const Ice::ConnectionManuallyClosedException& e)
+ {
+ PyObject_SetAttrString(p, STRCAST("graceful"), e.graceful ? IcePy::getTrue() : IcePy::getFalse());
+ }
catch(const Ice::LocalException&)
{
//