diff options
Diffstat (limited to 'py/modules/IcePy')
-rw-r--r-- | py/modules/IcePy/Operation.cpp | 44 | ||||
-rw-r--r-- | py/modules/IcePy/Operation.h | 23 | ||||
-rw-r--r-- | py/modules/IcePy/Proxy.cpp | 112 |
3 files changed, 177 insertions, 2 deletions
diff --git a/py/modules/IcePy/Operation.cpp b/py/modules/IcePy/Operation.cpp index 327be1c130c..ac5221029fd 100644 --- a/py/modules/IcePy/Operation.cpp +++ b/py/modules/IcePy/Operation.cpp @@ -16,6 +16,7 @@ #include <Proxy.h> #include <Thread.h> #include <Types.h> +#include <Connection.h> #include <Util.h> #include <Ice/Communicator.h> #include <Ice/IncomingAsync.h> @@ -2549,7 +2550,7 @@ IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) memcpy(buf, &out[0], sz); } #endif - + if(PyTuple_SET_ITEM(result.get(), 1, op.get()) < 0) { throwPythonException(); @@ -3618,7 +3619,7 @@ IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, { throwPythonException(); } - + PyObjectHandle ip; #if PY_VERSION_HEX >= 0x03000000 @@ -4010,6 +4011,45 @@ IcePy::FlushCallback::sent(bool sentSynchronously) } } +IcePy::GetConnectionCallback::GetConnectionCallback(const Ice::CommunicatorPtr& communicator, + PyObject* response, PyObject* ex, const string& op) : + _communicator(communicator), _response(response), _ex(ex), _op(op) +{ + assert(_response); + Py_INCREF(_response); + Py_XINCREF(_ex); +} + +IcePy::GetConnectionCallback::~GetConnectionCallback() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_response); + Py_XDECREF(_ex); +} + +void +IcePy::GetConnectionCallback::response(const Ice::ConnectionPtr& conn) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle pyConn = createConnection(conn, _communicator); + PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), pyConn.get()); + PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } +} + +void +IcePy::GetConnectionCallback::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callException(_ex, ex); +} + // // ServantWrapper implementation. // diff --git a/py/modules/IcePy/Operation.h b/py/modules/IcePy/Operation.h index 98d20f23463..e9691c63f8f 100644 --- a/py/modules/IcePy/Operation.h +++ b/py/modules/IcePy/Operation.h @@ -14,6 +14,7 @@ #include <Ice/Current.h> #include <Ice/Object.h> #include <Ice/OutgoingAsyncF.h> +#include <Ice/CommunicatorF.h> namespace IcePy { @@ -40,6 +41,28 @@ PyObject* createAsyncResult(const Ice::AsyncResultPtr&, PyObject*, PyObject*, Py Ice::AsyncResultPtr getAsyncResult(PyObject*); // +// Used as the callback for getConnection operation. +// +class GetConnectionCallback : public IceUtil::Shared +{ +public: + + GetConnectionCallback(const Ice::CommunicatorPtr&, PyObject*, PyObject*, const std::string&); + ~GetConnectionCallback(); + + void response(const Ice::ConnectionPtr&); + void exception(const Ice::Exception&); + +protected: + + Ice::CommunicatorPtr _communicator; + PyObject* _response; + PyObject* _ex; + std::string _op; +}; +typedef IceUtil::Handle<GetConnectionCallback> GetConnectionCallbackPtr; + +// // Used as the callback for the various flushBatchRequest operations. // class FlushCallback : public IceUtil::Shared diff --git a/py/modules/IcePy/Proxy.cpp b/py/modules/IcePy/Proxy.cpp index 90cf02923b7..cbdbeb8297a 100644 --- a/py/modules/IcePy/Proxy.cpp +++ b/py/modules/IcePy/Proxy.cpp @@ -1735,6 +1735,114 @@ proxyIceGetConnection(ProxyObject* self) extern "C" #endif static PyObject* +proxyBeginIceGetConnection(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + assert(self->proxy); + + static char* argNames[] = + { + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + 0 + }; + + PyObject* response = Py_None; + PyObject* ex = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &response, &ex)) + { + return 0; + } + + if(response == Py_None) + { + response = 0; + } + if(ex == Py_None) + { + ex = 0; + } + + if(!response && ex) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("response callback must also be provided when exception callback is used")); + return 0; + } + + Ice::Callback_Object_ice_getConnectionPtr cb; + if(response || ex) + { + GetConnectionCallbackPtr d = new GetConnectionCallback(*self->communicator, response, ex, "ice_getConnection"); + cb = Ice::newCallback_Object_ice_getConnection(d, &GetConnectionCallback::response, + &GetConnectionCallback::exception); + } + + Ice::AsyncResultPtr result; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + + if(cb) + { + result = (*self->proxy)->begin_ice_getConnection(cb); + } + else + { + result = (*self->proxy)->begin_ice_getConnection(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle communicator = getCommunicatorWrapper(*self->communicator); + return createAsyncResult(result, reinterpret_cast<PyObject*>(self), 0, communicator.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceGetConnection(ProxyObject* self, PyObject* args) +{ + assert(self->proxy); + + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + Ice::AsyncResultPtr r = getAsyncResult(result); + Ice::ConnectionPtr con; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + con = (*self->proxy)->end_ice_getConnection(r); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(con) + { + return createConnection(con, *self->communicator); + } + else + { + Py_INCREF(Py_None); + return Py_None; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* proxyIceGetCachedConnection(ProxyObject* self) { assert(self->proxy); @@ -2438,6 +2546,10 @@ 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("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, + PyDoc_STR(STRCAST("end_ice_getConnection(Ice.AsyncResult) -> Ice.Connection")) }, { STRCAST("ice_getCachedConnection"), reinterpret_cast<PyCFunction>(proxyIceGetCachedConnection), METH_NOARGS, PyDoc_STR(STRCAST("ice_getCachedConnection() -> Ice.Connection")) }, { STRCAST("ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyIceFlushBatchRequests), METH_NOARGS, |