From c1e512e1cb17ed06f4d5c84ec4b7807976e68ca3 Mon Sep 17 00:00:00 2001 From: Jose Date: Mon, 29 Jan 2024 20:29:23 +0100 Subject: [PATCH] Upgrade Python extension to use the new C++ mapping (#1727) --- cpp/include/Ice/AsyncResult.h | 2 - cpp/include/Ice/Communicator.h | 2 + cpp/include/Ice/OutgoingAsync.h | 2 - cpp/include/Ice/Proxy.h | 6 +- cpp/src/Ice/CommunicatorI.cpp | 10 +- cpp/src/Ice/CommunicatorI.h | 4 + cpp/src/Ice/OutgoingAsync.cpp | 33 - cpp/src/Ice/ThreadPool.cpp | 27 + cpp/src/Ice/ThreadPool.h | 1 + .../modules/IcePy/BatchRequestInterceptor.cpp | 6 +- .../modules/IcePy/BatchRequestInterceptor.h | 9 +- python/modules/IcePy/Communicator.cpp | 123 +- python/modules/IcePy/Connection.cpp | 97 +- python/modules/IcePy/ConnectionInfo.cpp | 38 +- python/modules/IcePy/Current.cpp | 6 +- python/modules/IcePy/Dispatcher.cpp | 16 +- python/modules/IcePy/Dispatcher.h | 6 +- python/modules/IcePy/Endpoint.cpp | 12 +- python/modules/IcePy/EndpointInfo.cpp | 28 +- python/modules/IcePy/Logger.cpp | 8 +- python/modules/IcePy/Logger.h | 4 +- python/modules/IcePy/Makefile.mk | 11 +- python/modules/IcePy/ObjectAdapter.cpp | 33 +- python/modules/IcePy/Operation.cpp | 1119 ++++++----------- python/modules/IcePy/Operation.h | 50 +- python/modules/IcePy/Proxy.cpp | 194 +-- python/modules/IcePy/Proxy.h | 6 +- python/modules/IcePy/Thread.cpp | 47 +- python/modules/IcePy/Thread.h | 16 +- python/modules/IcePy/Types.cpp | 459 ++----- python/modules/IcePy/Types.h | 111 +- python/modules/IcePy/msbuild/icepy.vcxproj | 14 +- python/msbuild/ice.proj | 2 +- python/python/Ice/__init__.py | 44 +- python/python/IceBox/__init__.py | 1 - python/test/Ice/ami/AllTests.py | 34 +- python/test/Ice/thread/AllTests.py | 5 +- python/test/Ice/thread/Test.ice | 3 - python/test/Ice/thread/TestI.py | 35 +- 39 files changed, 1003 insertions(+), 1621 deletions(-) diff --git a/cpp/include/Ice/AsyncResult.h b/cpp/include/Ice/AsyncResult.h index 672ef1af7b8..00c8de73588 100644 --- a/cpp/include/Ice/AsyncResult.h +++ b/cpp/include/Ice/AsyncResult.h @@ -137,8 +137,6 @@ class ICE_API AsyncResult : private IceUtil::noncopyable, public Ice::LocalObjec virtual void run() = 0; }; typedef IceUtil::Handle CallbackPtr; - - virtual void _scheduleCallback(const CallbackPtr&) = 0; /// \endcond protected: diff --git a/cpp/include/Ice/Communicator.h b/cpp/include/Ice/Communicator.h index 4f0563e0b75..14551dc8665 100644 --- a/cpp/include/Ice/Communicator.h +++ b/cpp/include/Ice/Communicator.h @@ -436,6 +436,8 @@ class ICE_CLASS(ICE_API) Communicator */ virtual dispatch_queue_t getServerDispatchQueue() const = 0; #endif + + virtual void postToClientThreadPool(::std::function call) = 0; }; } diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h index 24be3e76f59..a85a97635b0 100644 --- a/cpp/include/Ice/OutgoingAsync.h +++ b/cpp/include/Ice/OutgoingAsync.h @@ -102,8 +102,6 @@ class ICE_API OutgoingAsyncBase : public virtual OutgoingAsyncCompletionCallback 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/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h index 72f1344a0d8..4e50063e533 100644 --- a/cpp/include/Ice/Proxy.h +++ b/cpp/include/Ice/Proxy.h @@ -187,7 +187,8 @@ class InvokePromiseOutgoing : public InvokeOutgoingAsyncT, public PromiseInvo { if(this->_is.b.empty()) { - this->_promise.set_value(R { ok, { 0, 0 }}); + std::vector encaps; + this->_promise.set_value(R { ok, encaps}); } else { @@ -200,7 +201,8 @@ class InvokePromiseOutgoing : public InvokeOutgoingAsyncT, public PromiseInvo { if(done) { - this->_promise.set_value(R { true, { 0, 0 }}); + std::vector encaps; + this->_promise.set_value(R { true, encaps}); } return false; } diff --git a/cpp/src/Ice/CommunicatorI.cpp b/cpp/src/Ice/CommunicatorI.cpp index 362041766ce..f774cc8a66e 100644 --- a/cpp/src/Ice/CommunicatorI.cpp +++ b/cpp/src/Ice/CommunicatorI.cpp @@ -13,12 +13,10 @@ #include #include #include +#include #include #include #include -#ifdef ICE_SWIFT -# include -#endif using namespace std; using namespace Ice; @@ -377,6 +375,12 @@ Ice::CommunicatorI::getServerDispatchQueue() const #endif +void +Ice::CommunicatorI::postToClientThreadPool(function call) +{ + _instance->clientThreadPool()->dispatch(call); +} + namespace { diff --git a/cpp/src/Ice/CommunicatorI.h b/cpp/src/Ice/CommunicatorI.h index b46b1eaf024..7c404639b25 100644 --- a/cpp/src/Ice/CommunicatorI.h +++ b/cpp/src/Ice/CommunicatorI.h @@ -13,6 +13,8 @@ #include #include +#include + namespace IceInternal { @@ -98,6 +100,8 @@ class CommunicatorI : public Communicator virtual dispatch_queue_t getServerDispatchQueue() const; #endif + virtual void postToClientThreadPool(::std::function call); + #ifdef ICE_CPP11_MAPPING virtual ::std::function flushBatchRequestsAsync(CompressBatch, diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp index 58ce51ceeaa..1572ddf97d8 100644 --- a/cpp/src/Ice/OutgoingAsync.cpp +++ b/cpp/src/Ice/OutgoingAsync.cpp @@ -525,39 +525,6 @@ OutgoingAsyncBase::_throwUserException() } } -void -OutgoingAsyncBase::_scheduleCallback(const CallbackPtr& cb) -{ - // - // NOTE: for internal use only. This should only be called when the invocation has - // completed. Accessing _cachedConnection is not safe otherwise. - // - - class WorkItem : public DispatchWorkItem - { - public: - - WorkItem(const ConnectionPtr& connection, const CallbackPtr& cb) : - DispatchWorkItem(connection), _cb(cb) - { - } - - virtual void run() - { - _cb->run(); - } - - private: - - CallbackPtr _cb; - }; - - // - // CommunicatorDestroyedException is the only exception that can propagate directly from this method. - // - _instance->clientThreadPool()->dispatch(new WorkItem(_cachedConnection, cb)); -} - #endif void diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp index e4d8c7c2931..7324af12853 100644 --- a/cpp/src/Ice/ThreadPool.cpp +++ b/cpp/src/Ice/ThreadPool.cpp @@ -622,6 +622,33 @@ IceInternal::ThreadPool::dispatch(const DispatchWorkItemPtr& workItem) _workQueue->queue(workItem); } +void +IceInternal::ThreadPool::dispatch(function call) +{ + class WorkItem final : public IceInternal::DispatchWorkItem + { + public: + + WorkItem(function call) + : _call(std::move(call)) + { + } + + void run() final + { + _call(); + } + + private: + + function _call; + + }; + + DispatchWorkItemPtr workItem = new WorkItem(std::move(call)); + dispatch(workItem); +} + void IceInternal::ThreadPool::joinWithAllThreads() { diff --git a/cpp/src/Ice/ThreadPool.h b/cpp/src/Ice/ThreadPool.h index a07b63c4238..73d0d4c907f 100644 --- a/cpp/src/Ice/ThreadPool.h +++ b/cpp/src/Ice/ThreadPool.h @@ -105,6 +105,7 @@ class ThreadPool : public IceUtil::Shared, private IceUtil::Monitor); void joinWithAllThreads(); diff --git a/python/modules/IcePy/BatchRequestInterceptor.cpp b/python/modules/IcePy/BatchRequestInterceptor.cpp index 3fe3c57c08b..a9daea32974 100644 --- a/python/modules/IcePy/BatchRequestInterceptor.cpp +++ b/python/modules/IcePy/BatchRequestInterceptor.cpp @@ -107,7 +107,7 @@ batchRequestGetProxy(BatchRequestObject* self, PyObject* /*args*/) assert(self->request); if(!self->proxy) { - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = self->request->getProxy(); @@ -227,7 +227,7 @@ IcePy::initBatchRequest(PyObject* module) return true; } -IcePy::BatchRequestInterceptor::BatchRequestInterceptor(PyObject* interceptor) : _interceptor(interceptor) +IcePy::BatchRequestInterceptorWrapper::BatchRequestInterceptorWrapper(PyObject* interceptor) : _interceptor(interceptor) { if(!PyCallable_Check(interceptor) && !PyObject_HasAttrString(interceptor, STRCAST("enqueue"))) { @@ -239,7 +239,7 @@ IcePy::BatchRequestInterceptor::BatchRequestInterceptor(PyObject* interceptor) : } void -IcePy::BatchRequestInterceptor::enqueue(const Ice::BatchRequest& request, int queueCount, int queueSize) +IcePy::BatchRequestInterceptorWrapper::enqueue(const Ice::BatchRequest& request, int queueCount, int queueSize) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. diff --git a/python/modules/IcePy/BatchRequestInterceptor.h b/python/modules/IcePy/BatchRequestInterceptor.h index 40463621e05..76c3a3dbc91 100644 --- a/python/modules/IcePy/BatchRequestInterceptor.h +++ b/python/modules/IcePy/BatchRequestInterceptor.h @@ -9,6 +9,8 @@ #include #include +#include + namespace IcePy { @@ -16,19 +18,18 @@ extern PyTypeObject BatchRequestType; bool initBatchRequest(PyObject*); -class BatchRequestInterceptor : public Ice::BatchRequestInterceptor +class BatchRequestInterceptorWrapper final { public: - BatchRequestInterceptor(PyObject*); + BatchRequestInterceptorWrapper(PyObject*); - virtual void enqueue(const Ice::BatchRequest&, int, int); + void enqueue(const Ice::BatchRequest&, int, int); private: PyObjectHandle _interceptor; }; -typedef IceUtil::Handle BatchRequestInterceptorPtr; } diff --git a/python/modules/IcePy/Communicator.cpp b/python/modules/IcePy/Communicator.cpp index f092378f24d..1b4cf678ce7 100644 --- a/python/modules/IcePy/Communicator.cpp +++ b/python/modules/IcePy/Communicator.cpp @@ -39,7 +39,7 @@ using namespace IcePy; static unsigned long _mainThreadId; -typedef map CommunicatorMap; +using CommunicatorMap = map; static CommunicatorMap _communicatorMap; namespace IcePy @@ -196,11 +196,10 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) try { - if(initData) + if (initData) { PyObjectHandle properties = getAttr(initData, "properties", false); PyObjectHandle logger = getAttr(initData, "logger", false); - PyObjectHandle threadHook = getAttr(initData, "threadHook", false); PyObjectHandle threadStart = getAttr(initData, "threadStart", false); PyObjectHandle threadStop = getAttr(initData, "threadStop", false); PyObjectHandle batchRequestInterceptor = getAttr(initData, "batchRequestInterceptor", false); @@ -218,23 +217,33 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) if(logger.get()) { - data.logger = new LoggerWrapper(logger.get()); + data.logger = make_shared(logger.get()); } - if(threadHook.get() || threadStart.get() || threadStop.get()) + if(threadStart.get() || threadStop.get()) { - data.threadHook = new ThreadHook(threadHook.get(), threadStart.get(), threadStop.get()); + auto threadHook = make_shared(threadStart.get(), threadStop.get()); + data.threadStart = [threadHook]() { threadHook->start(); }; + data.threadStop = [threadHook]() { threadHook->stop(); }; } - if(dispatcher.get()) + if (dispatcher.get()) { - dispatcherWrapper = new Dispatcher(dispatcher.get()); - data.dispatcher = dispatcherWrapper; + dispatcherWrapper = make_shared(dispatcher.get()); + data.dispatcher = + [dispatcherWrapper] (function call, const shared_ptr& connection) + { + dispatcherWrapper->dispatch(call, connection); + }; } - if(batchRequestInterceptor.get()) + if (batchRequestInterceptor.get()) { - data.batchRequestInterceptor = new BatchRequestInterceptor(batchRequestInterceptor.get()); + auto batchRequestInterceptorWrapper = make_shared(batchRequestInterceptor.get()); + data.batchRequestInterceptor = [batchRequestInterceptorWrapper](const Ice::BatchRequest& req, int count, int size) + { + batchRequestInterceptorWrapper->enqueue(req, count, size); + }; } } @@ -277,7 +286,7 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) } argv[argc] = 0; - data.compactIdResolver = new IdResolver; + data.compactIdResolver = resolveCompactId; // Always accept cycles in Python data.properties->setProperty("Ice.AcceptClassCycles", "1"); @@ -328,12 +337,6 @@ communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) delete[] argv; self->communicator = new Ice::CommunicatorPtr(communicator); - - CommunicatorMap::iterator p = _communicatorMap.find(communicator); - if(p != _communicatorMap.end()) - { - _communicatorMap.erase(p); - } _communicatorMap.insert(CommunicatorMap::value_type(communicator, reinterpret_cast(self))); if(dispatcherWrapper) @@ -392,9 +395,9 @@ communicatorDestroy(CommunicatorObject* self, PyObject* /*args*/) vfm->destroy(); - if(self->dispatcher) + if (self->dispatcher) { - (*self->dispatcher)->setCommunicator(0); // Break cyclic reference. + (*self->dispatcher)->setCommunicator(nullptr); // Break cyclic reference. } // @@ -493,7 +496,8 @@ communicatorWaitForShutdown(CommunicatorObject* self, PyObject* args) } catch(const Ice::Exception& ex) { - self->shutdownException = ex.ice_clone(); + // Clone the exception and take ownership of the object. + self->shutdownException = ex.ice_clone().release(); } } @@ -561,7 +565,7 @@ communicatorStringToProxy(CommunicatorObject* self, PyObject* args) } assert(self->communicator); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->communicator)->stringToProxy(str); @@ -592,7 +596,7 @@ communicatorProxyToString(CommunicatorObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(obj, "proxyToString", "obj", proxy)) { return 0; @@ -633,7 +637,7 @@ communicatorPropertyToProxy(CommunicatorObject* self, PyObject* args) } assert(self->communicator); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->communicator)->propertyToProxy(str); @@ -669,7 +673,7 @@ communicatorProxyToProperty(CommunicatorObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy = getProxy(proxyObj); + shared_ptr proxy = getProxy(proxyObj); string str; if(!getStringArg(strObj, "property", str)) { @@ -787,39 +791,48 @@ communicatorFlushBatchRequestsAsync(CommunicatorObject* self, PyObject* args, Py PyObjectHandle v = getAttr(compressBatch, "_value", false); assert(v.get()); - Ice::CompressBatch cb = static_cast(PyLong_AsLong(v.get())); + Ice::CompressBatch compress = static_cast(PyLong_AsLong(v.get())); assert(self->communicator); const string op = "flushBatchRequests"; - FlushAsyncCallbackPtr d = new FlushAsyncCallback(op); - Ice::Callback_Communicator_flushBatchRequestsPtr callback = - Ice::newCallback_Communicator_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent); - - Ice::AsyncResultPtr result; - + auto callback = make_shared(op); + function cancel; try { - result = (*self->communicator)->begin_flushBatchRequests(cb, callback); + cancel = (*self->communicator)->flushBatchRequestsAsync( + compress, + [callback](exception_ptr exptr) + { + try + { + rethrow_exception(exptr); + } + catch (const Ice::Exception& ex) + { + callback->exception(ex); + } + }, + [callback](bool sentSynchronously) { callback->sent(sentSynchronously); }); } - catch(const Ice::Exception& ex) + catch (const Ice::Exception& ex) { setPythonException(ex); return 0; } - PyObjectHandle asyncResultObj = createAsyncResult(result, 0, 0, self->wrapper); - if(!asyncResultObj.get()) + PyObjectHandle asyncInvocationContextObj = createAsyncInvocationContext(std::move(cancel), *self->communicator); + if (!asyncInvocationContextObj.get()) { return 0; } - PyObjectHandle future = createFuture(op, asyncResultObj.get()); - if(!future.get()) + PyObjectHandle future = createFuture(op, asyncInvocationContextObj.get()); + if (!future.get()) { return 0; } - d->setFuture(future.get()); + callback->setFuture(future.get()); return future.release(); } @@ -858,7 +871,7 @@ communicatorCreateAdmin(CommunicatorObject* self, PyObject* args) } assert(self->communicator); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->communicator)->createAdmin(oa, identity); @@ -880,7 +893,7 @@ static PyObject* communicatorGetAdmin(CommunicatorObject* self, PyObject* /*args*/) { assert(self->communicator); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->communicator)->getAdmin(); @@ -975,7 +988,7 @@ communicatorFindAdminFacet(CommunicatorObject* self, PyObject* args) return wrapper->getObject(); } - Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(obj); + Ice::NativePropertiesAdminPtr props = dynamic_pointer_cast(obj); if(props) { return createNativePropertiesAdmin(props); @@ -1035,7 +1048,7 @@ communicatorFindAllAdminFacets(CommunicatorObject* self, PyObject* /*args*/) } else { - Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(p->second); + Ice::NativePropertiesAdminPtr props = dynamic_pointer_cast(p->second); if(props) { obj = createNativePropertiesAdmin(props); @@ -1172,7 +1185,7 @@ communicatorGetLogger(CommunicatorObject* self, PyObject* /*args*/) // return it directly. Otherwise, we create a Python object // that delegates to the C++ object. // - LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(logger); + LoggerWrapperPtr wrapper = dynamic_pointer_cast(logger); if(wrapper) { PyObject* obj = wrapper->getObject(); @@ -1325,13 +1338,13 @@ communicatorCreateObjectAdapterWithRouter(CommunicatorObject* self, PyObject* ar return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "createObjectAdapterWithRouter", "rtr", proxy, "Ice.RouterPrx")) { return 0; } - Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + shared_ptr router = Ice::uncheckedCast(proxy); assert(self->communicator); Ice::ObjectAdapterPtr adapter; @@ -1368,18 +1381,18 @@ static PyObject* communicatorGetDefaultRouter(CommunicatorObject* self, PyObject* /*args*/) { assert(self->communicator); - Ice::RouterPrx router; + shared_ptr router; try { router = (*self->communicator)->getDefaultRouter(); } - catch(const Ice::Exception& ex) + catch (const Ice::Exception& ex) { setPythonException(ex); return 0; } - if(!router) + if (!router) { Py_INCREF(Py_None); return Py_None; @@ -1402,13 +1415,13 @@ communicatorSetDefaultRouter(CommunicatorObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "setDefaultRouter", "rtr", proxy, "Ice.RouterPrx")) { return 0; } - Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + shared_ptr router = Ice::uncheckedCast(proxy); assert(self->communicator); try @@ -1432,7 +1445,7 @@ static PyObject* communicatorGetDefaultLocator(CommunicatorObject* self, PyObject* /*args*/) { assert(self->communicator); - Ice::LocatorPrx locator; + shared_ptr locator; try { locator = (*self->communicator)->getDefaultLocator(); @@ -1466,13 +1479,13 @@ communicatorSetDefaultLocator(CommunicatorObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "setDefaultLocator", "loc", proxy, "Ice.LocatorPrx")) { return 0; } - Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + shared_ptr locator = Ice::uncheckedCast(proxy); assert(self->communicator); try @@ -1691,7 +1704,7 @@ IcePy_identityToString(PyObject* /*self*/, PyObject* args) return 0; } - Ice::ToStringMode toStringMode = Ice::Unicode; + Ice::ToStringMode toStringMode = Ice::ToStringMode::Unicode; if(mode != Py_None && PyObject_HasAttrString(mode, STRCAST("value"))) { PyObjectHandle modeValue = getAttr(mode, "value", true); diff --git a/python/modules/IcePy/Connection.cpp b/python/modules/IcePy/Connection.cpp index cd18ae12cc0..36ed6ac9040 100644 --- a/python/modules/IcePy/Connection.cpp +++ b/python/modules/IcePy/Connection.cpp @@ -84,18 +84,19 @@ struct ConnectionObject Ice::CommunicatorPtr* communicator; }; -class CloseCallbackWrapper : public Ice::CloseCallback +class CloseCallbackWrapper final { public: CloseCallbackWrapper(PyObject* cb, PyObject* con) : - _cb(cb), _con(con) + _cb(cb), + _con(con) { Py_INCREF(cb); Py_INCREF(con); } - virtual ~CloseCallbackWrapper() + ~CloseCallbackWrapper() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -103,7 +104,7 @@ class CloseCallbackWrapper : public Ice::CloseCallback Py_DECREF(_con); } - virtual void closed(const Ice::ConnectionPtr&) + void closed() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -131,19 +132,21 @@ class CloseCallbackWrapper : public Ice::CloseCallback PyObject* _cb; PyObject* _con; }; +using CloseCallbackWrapperPtr = shared_ptr; -class HeartbeatCallbackWrapper : public Ice::HeartbeatCallback +class HeartbeatCallbackWrapper final { public: HeartbeatCallbackWrapper(PyObject* cb, PyObject* con) : - _cb(cb), _con(con) + _cb(cb), + _con(con) { Py_INCREF(cb); Py_INCREF(con); } - virtual ~HeartbeatCallbackWrapper() + ~HeartbeatCallbackWrapper() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -151,7 +154,7 @@ class HeartbeatCallbackWrapper : public Ice::HeartbeatCallback Py_DECREF(_con); } - virtual void heartbeat(const Ice::ConnectionPtr&) + void heartbeat() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -179,6 +182,7 @@ class HeartbeatCallbackWrapper : public Ice::HeartbeatCallback PyObject* _cb; PyObject* _con; }; +using HeartbeatCallbackWrapperPtr = shared_ptr; } @@ -327,7 +331,7 @@ connectionCreateProxy(ConnectionObject* self, PyObject* args) assert(self->connection); assert(self->communicator); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->connection)->createProxy(ident); @@ -457,20 +461,33 @@ connectionFlushBatchRequestsAsync(ConnectionObject* self, PyObject* args) PyObjectHandle v = getAttr(compressBatch, "_value", true); assert(v.get()); - Ice::CompressBatch cb = static_cast(PyLong_AsLong(v.get())); + Ice::CompressBatch compress = static_cast(PyLong_AsLong(v.get())); assert(self->connection); const string op = "flushBatchRequests"; - FlushAsyncCallbackPtr d = new FlushAsyncCallback(op); - Ice::Callback_Connection_flushBatchRequestsPtr callback = - Ice::newCallback_Connection_flushBatchRequests(d, &FlushAsyncCallback::exception, &FlushAsyncCallback::sent); - - Ice::AsyncResultPtr result; - + auto callback = make_shared(op); + function cancel; try { - result = (*self->connection)->begin_flushBatchRequests(cb, callback); + cancel = (*self->connection)->flushBatchRequestsAsync( + compress, + [callback](exception_ptr exptr) + { + try + { + rethrow_exception(exptr); + } + catch (const Ice::Exception& ex) + { + callback->exception(ex); + } + catch (...) + { + assert(false); + } + }, + [callback](bool sentSynchronously) { callback->sent(sentSynchronously); }); } catch(const Ice::Exception& ex) { @@ -478,20 +495,18 @@ connectionFlushBatchRequestsAsync(ConnectionObject* self, PyObject* args) return 0; } - PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator); - PyObjectHandle asyncResultObj = - createAsyncResult(result, 0, reinterpret_cast(self), communicatorObj.get()); - if(!asyncResultObj.get()) + PyObjectHandle asyncInvocationContextObj = createAsyncInvocationContext(std::move(cancel), *self->communicator); + if (!asyncInvocationContextObj.get()) { return 0; } - PyObjectHandle future = createFuture(op, asyncResultObj.get()); + PyObjectHandle future = createFuture(op, asyncInvocationContextObj.get()); if(!future.get()) { return 0; } - d->setFuture(future.get()); + callback->setFuture(future.get()); return future.release(); } @@ -516,18 +531,25 @@ connectionSetCloseCallback(ConnectionObject* self, PyObject* args) return 0; } - Ice::CloseCallbackPtr wrapper; + CloseCallbackWrapperPtr wrapper; if(cb != Py_None) { - wrapper = new CloseCallbackWrapper(cb, reinterpret_cast(self)); + wrapper = make_shared(cb, reinterpret_cast(self)); } try { AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. - (*self->connection)->setCloseCallback(wrapper); + if (wrapper) + { + (*self->connection)->setCloseCallback([wrapper](const Ice::ConnectionPtr&) { wrapper->closed(); }); + } + else + { + (*self->connection)->setCloseCallback(nullptr); + } } - catch(const Ice::Exception& ex) + catch (const Ice::Exception& ex) { setPythonException(ex); return 0; @@ -558,16 +580,23 @@ connectionSetHeartbeatCallback(ConnectionObject* self, PyObject* args) return 0; } - Ice::HeartbeatCallbackPtr wrapper; + HeartbeatCallbackWrapperPtr wrapper; if(cb != Py_None) { - wrapper = new HeartbeatCallbackWrapper(cb, reinterpret_cast(self)); + wrapper = make_shared(cb, reinterpret_cast(self)); } try { AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. - (*self->connection)->setHeartbeatCallback(wrapper); + if (wrapper) + { + (*self->connection)->setHeartbeatCallback([wrapper](const Ice::ConnectionPtr&){ wrapper->heartbeat(); }); + } + else + { + (*self->connection)->setHeartbeatCallback(nullptr); + } } catch(const Ice::Exception& ex) { @@ -661,9 +690,9 @@ connectionSetACM(ConnectionObject* self, PyObject* args) { (*self->connection)->setACM(timeout, close, heartbeat); } - catch(const IceUtil::IllegalArgumentException& ex) + catch(const invalid_argument& ex) { - PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); return 0; } catch(const Ice::Exception& ex) @@ -718,7 +747,7 @@ connectionGetACM(ConnectionObject* self, PyObject* /*args*/) return 0; } - EnumInfoPtr acmCloseEnum = EnumInfoPtr::dynamicCast(getType(acmCloseType)); + EnumInfoPtr acmCloseEnum = dynamic_pointer_cast(getType(acmCloseType)); assert(acmCloseEnum); PyObjectHandle close = acmCloseEnum->enumeratorForValue(static_cast(acm.close)); if(!close.get()) @@ -732,7 +761,7 @@ connectionGetACM(ConnectionObject* self, PyObject* /*args*/) return 0; } - EnumInfoPtr acmHeartbeatEnum = EnumInfoPtr::dynamicCast(getType(acmHeartbeatType)); + EnumInfoPtr acmHeartbeatEnum = dynamic_pointer_cast(getType(acmHeartbeatType)); assert(acmHeartbeatEnum); PyObjectHandle heartbeat = acmHeartbeatEnum->enumeratorForValue(static_cast(acm.heartbeat)); if(!heartbeat.get()) diff --git a/python/modules/IcePy/ConnectionInfo.cpp b/python/modules/IcePy/ConnectionInfo.cpp index 43064478bbf..601f14ae246 100644 --- a/python/modules/IcePy/ConnectionInfo.cpp +++ b/python/modules/IcePy/ConnectionInfo.cpp @@ -75,7 +75,7 @@ extern "C" static PyObject* ipConnectionInfoGetLocalAddress(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return createString(info->localAddress); } @@ -86,7 +86,7 @@ extern "C" static PyObject* ipConnectionInfoGetLocalPort(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->localPort); } @@ -97,7 +97,7 @@ extern "C" static PyObject* ipConnectionInfoGetRemoteAddress(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return createString(info->remoteAddress); } @@ -108,7 +108,7 @@ extern "C" static PyObject* ipConnectionInfoGetRemotePort(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->remotePort); } @@ -119,7 +119,7 @@ extern "C" static PyObject* tcpConnectionInfoGetRcvSize(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::TCPConnectionInfoPtr info = Ice::TCPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->rcvSize); } @@ -130,7 +130,7 @@ extern "C" static PyObject* tcpConnectionInfoGetSndSize(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::TCPConnectionInfoPtr info = Ice::TCPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->sndSize); } @@ -141,7 +141,7 @@ extern "C" static PyObject* udpConnectionInfoGetMcastAddress(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return createString(info->mcastAddress); } @@ -152,7 +152,7 @@ extern "C" static PyObject* udpConnectionInfoGetMcastPort(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->mcastPort); } @@ -163,7 +163,7 @@ extern "C" static PyObject* udpConnectionInfoGetRcvSize(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->rcvSize); } @@ -174,7 +174,7 @@ extern "C" static PyObject* udpConnectionInfoGetSndSize(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return PyLong_FromLong(info->sndSize); } @@ -185,7 +185,7 @@ extern "C" static PyObject* wsConnectionInfoGetHeaders(ConnectionInfoObject* self, PyObject* /*args*/) { - Ice::WSConnectionInfoPtr info = Ice::WSConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); PyObjectHandle result = PyDict_New(); @@ -211,7 +211,7 @@ extern "C" static PyObject* sslConnectionInfoGetCipher(ConnectionInfoObject* self, PyObject* /*args*/) { - IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return createString(info->cipher); } @@ -222,7 +222,7 @@ extern "C" static PyObject* sslConnectionInfoGetCerts(ConnectionInfoObject* self, PyObject* /*args*/) { - IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); PyObject* certs = PyList_New(0); Ice::StringSeq encoded; @@ -240,7 +240,7 @@ extern "C" static PyObject* sslConnectionInfoGetVerified(ConnectionInfoObject* self, PyObject* /*args*/) { - IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(*self->connectionInfo); + auto info = dynamic_pointer_cast(*self->connectionInfo); assert(info); return info->incoming ? incTrue() : incFalse(); } @@ -685,23 +685,23 @@ IcePy::createConnectionInfo(const Ice::ConnectionInfoPtr& connectionInfo) } PyTypeObject* type; - if(Ice::WSConnectionInfoPtr::dynamicCast(connectionInfo)) + if(dynamic_pointer_cast(connectionInfo)) { type = &WSConnectionInfoType; } - else if(Ice::TCPConnectionInfoPtr::dynamicCast(connectionInfo)) + else if(dynamic_pointer_cast(connectionInfo)) { type = &TCPConnectionInfoType; } - else if(Ice::UDPConnectionInfoPtr::dynamicCast(connectionInfo)) + else if(dynamic_pointer_cast(connectionInfo)) { type = &UDPConnectionInfoType; } - else if(IceSSL::ConnectionInfoPtr::dynamicCast(connectionInfo)) + else if(dynamic_pointer_cast(connectionInfo)) { type = &SSLConnectionInfoType; } - else if(Ice::IPConnectionInfoPtr::dynamicCast(connectionInfo)) + else if(dynamic_pointer_cast(connectionInfo)) { type = &IPConnectionInfoType; } diff --git a/python/modules/IcePy/Current.cpp b/python/modules/IcePy/Current.cpp index 8621b18b1f4..b6ed304d0ff 100644 --- a/python/modules/IcePy/Current.cpp +++ b/python/modules/IcePy/Current.cpp @@ -175,13 +175,13 @@ currentGetter(CurrentObject* self, void* closure) const char* enumerator = 0; switch(self->current->mode) { - case Ice::Normal: + case Ice::OperationMode::Normal: enumerator = "Normal"; break; - case Ice::Nonmutating: + case Ice::OperationMode::Nonmutating: enumerator = "Nonmutating"; break; - case Ice::Idempotent: + case Ice::OperationMode::Idempotent: enumerator = "Idempotent"; break; } diff --git a/python/modules/IcePy/Dispatcher.cpp b/python/modules/IcePy/Dispatcher.cpp index a136e74eaf4..d1e6d9e7a6c 100644 --- a/python/modules/IcePy/Dispatcher.cpp +++ b/python/modules/IcePy/Dispatcher.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include + using namespace std; using namespace IcePy; @@ -16,7 +19,7 @@ namespace IcePy struct DispatcherCallObject { PyObject_HEAD - Ice::DispatcherCallPtr* call; + function* call; }; } @@ -40,7 +43,7 @@ dispatcherCallInvoke(DispatcherCallObject* self, PyObject* /*args*/, PyObject* / try { AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. - (*self->call)->run(); + (*self->call)(); } catch(const Ice::Exception& ex) { @@ -137,18 +140,17 @@ IcePy::Dispatcher::setCommunicator(const Ice::CommunicatorPtr& communicator) } void -IcePy::Dispatcher::dispatch(const Ice::DispatcherCallPtr& call, const Ice::ConnectionPtr& con) +IcePy::Dispatcher::dispatch(function call, const Ice::ConnectionPtr& con) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. - DispatcherCallObject* obj = - reinterpret_cast(DispatcherCallType.tp_alloc(&DispatcherCallType, 0)); - if(!obj) + auto obj = reinterpret_cast(DispatcherCallType.tp_alloc(&DispatcherCallType, 0)); + if (!obj) { return; } - obj->call = new Ice::DispatcherCallPtr(call); + obj->call = new function(std::move(call)); PyObjectHandle c = createConnection(con, _communicator); PyObjectHandle tmp = PyObject_CallFunction(_dispatcher.get(), STRCAST("OO"), obj, c.get()); Py_DECREF(reinterpret_cast(obj)); diff --git a/python/modules/IcePy/Dispatcher.h b/python/modules/IcePy/Dispatcher.h index 17685b03bc7..b6c11b94d00 100644 --- a/python/modules/IcePy/Dispatcher.h +++ b/python/modules/IcePy/Dispatcher.h @@ -15,7 +15,7 @@ namespace IcePy bool initDispatcher(PyObject*); -class Dispatcher : public Ice::Dispatcher +class Dispatcher final { public: @@ -23,14 +23,14 @@ class Dispatcher : public Ice::Dispatcher void setCommunicator(const Ice::CommunicatorPtr&); - virtual void dispatch(const Ice::DispatcherCallPtr&, const Ice::ConnectionPtr&); + void dispatch(std::function call, const Ice::ConnectionPtr&); private: PyObjectHandle _dispatcher; Ice::CommunicatorPtr _communicator; }; -typedef IceUtil::Handle DispatcherPtr; +using DispatcherPtr = std::shared_ptr; } diff --git a/python/modules/IcePy/Endpoint.cpp b/python/modules/IcePy/Endpoint.cpp index 22a3c383d3b..abcd4537a3f 100644 --- a/python/modules/IcePy/Endpoint.cpp +++ b/python/modules/IcePy/Endpoint.cpp @@ -55,22 +55,22 @@ endpointCompare(EndpointObject* p1, PyObject* other, int op) switch(op) { case Py_EQ: - result = *p1->endpoint == *p2->endpoint; + result = Ice::targetEqualTo(*p1->endpoint, *p2->endpoint); break; case Py_NE: - result = *p1->endpoint != *p2->endpoint; + result = !Ice::targetEqualTo(*p1->endpoint, *p2->endpoint); break; case Py_LE: - result = *p1->endpoint <= *p2->endpoint; + result = Ice::targetLessEqual(*p1->endpoint, *p2->endpoint); break; case Py_GE: - result = *p1->endpoint >= *p2->endpoint; + result = Ice::targetGreaterEqual(*p1->endpoint, *p2->endpoint); break; case Py_LT: - result = *p1->endpoint < *p2->endpoint; + result = Ice::targetLess(*p1->endpoint, *p2->endpoint); break; case Py_GT: - result = *p1->endpoint > *p2->endpoint; + result = Ice::targetGreater(*p1->endpoint, *p2->endpoint); break; } } diff --git a/python/modules/IcePy/EndpointInfo.cpp b/python/modules/IcePy/EndpointInfo.cpp index 4a26f2ca2a5..31993f63e1e 100644 --- a/python/modules/IcePy/EndpointInfo.cpp +++ b/python/modules/IcePy/EndpointInfo.cpp @@ -145,7 +145,7 @@ extern "C" static PyObject* ipEndpointInfoGetHost(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return createString(info->host); } @@ -156,7 +156,7 @@ extern "C" static PyObject* ipEndpointInfoGetSourceAddress(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return createString(info->sourceAddress); } @@ -167,7 +167,7 @@ extern "C" static PyObject* ipEndpointInfoGetPort(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return PyLong_FromLong(info->port); } @@ -178,7 +178,7 @@ extern "C" static PyObject* udpEndpointInfoGetMcastInterface(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::UDPEndpointInfoPtr info = Ice::UDPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return createString(info->mcastInterface); } @@ -189,7 +189,7 @@ extern "C" static PyObject* udpEndpointInfoGetMcastTtl(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::UDPEndpointInfoPtr info = Ice::UDPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return PyLong_FromLong(info->mcastTtl); } @@ -200,7 +200,7 @@ extern "C" static PyObject* wsEndpointInfoGetResource(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::WSEndpointInfoPtr info = Ice::WSEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return createString(info->resource); } @@ -211,7 +211,7 @@ extern "C" static PyObject* opaqueEndpointInfoGetRawBytes(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::OpaqueEndpointInfoPtr info = Ice::OpaqueEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return PyBytes_FromStringAndSize(reinterpret_cast(&info->rawBytes[0]), static_cast(info->rawBytes.size())); @@ -223,7 +223,7 @@ extern "C" static PyObject* opaqueEndpointInfoGetRawEncoding(EndpointInfoObject* self, PyObject* /*args*/) { - Ice::OpaqueEndpointInfoPtr info = Ice::OpaqueEndpointInfoPtr::dynamicCast(*self->endpointInfo); + auto info = dynamic_pointer_cast(*self->endpointInfo); assert(info); return IcePy::createEncodingVersion(info->rawEncoding); } @@ -720,27 +720,27 @@ IcePy::createEndpointInfo(const Ice::EndpointInfoPtr& endpointInfo) } PyTypeObject* type; - if(Ice::WSEndpointInfoPtr::dynamicCast(endpointInfo)) + if(dynamic_pointer_cast(endpointInfo)) { type = &WSEndpointInfoType; } - else if(Ice::TCPEndpointInfoPtr::dynamicCast(endpointInfo)) + else if(dynamic_pointer_cast(endpointInfo)) { type = &TCPEndpointInfoType; } - else if(Ice::UDPEndpointInfoPtr::dynamicCast(endpointInfo)) + else if(dynamic_pointer_cast(endpointInfo)) { type = &UDPEndpointInfoType; } - else if(IceSSL::EndpointInfoPtr::dynamicCast(endpointInfo)) + else if(dynamic_pointer_cast(endpointInfo)) { type = &SSLEndpointInfoType; } - else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(endpointInfo)) + else if(dynamic_pointer_cast(endpointInfo)) { type = &OpaqueEndpointInfoType; } - else if(Ice::IPEndpointInfoPtr::dynamicCast(endpointInfo)) + else if(dynamic_pointer_cast(endpointInfo)) { type = &IPEndpointInfoType; } diff --git a/python/modules/IcePy/Logger.cpp b/python/modules/IcePy/Logger.cpp index 0acf2f78c08..690aa6355b0 100644 --- a/python/modules/IcePy/Logger.cpp +++ b/python/modules/IcePy/Logger.cpp @@ -104,7 +104,7 @@ IcePy::LoggerWrapper::cloneWithPrefix(const string& prefix) throwPythonException(); } - return new LoggerWrapper(tmp.get()); + return make_shared(tmp.get()); } PyObject* @@ -336,7 +336,7 @@ loggerCloneWithPrefix(LoggerObject* self, PyObject* args) // return it directly. Otherwise, we create a Python object // that delegates to the C++ object. // - LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(clone); + auto wrapper = dynamic_pointer_cast(clone); if(wrapper) { PyObject* obj = wrapper->getObject(); @@ -474,7 +474,7 @@ IcePy_getProcessLogger(PyObject* /*self*/, PyObject* /*args*/) // return it directly. Otherwise, we create a Python object // that delegates to the C++ object. // - LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(logger); + auto wrapper = dynamic_pointer_cast(logger); if(wrapper) { PyObject* obj = wrapper->getObject(); @@ -498,7 +498,7 @@ IcePy_setProcessLogger(PyObject* /*self*/, PyObject* args) return 0; } - Ice::LoggerPtr wrapper = new LoggerWrapper(logger); + auto wrapper = make_shared(logger); try { Ice::setProcessLogger(wrapper); diff --git a/python/modules/IcePy/Logger.h b/python/modules/IcePy/Logger.h index fa8fb609c00..9e3bdd733dd 100644 --- a/python/modules/IcePy/Logger.h +++ b/python/modules/IcePy/Logger.h @@ -9,6 +9,8 @@ #include #include +#include + namespace IcePy { @@ -33,7 +35,7 @@ class LoggerWrapper : public Ice::Logger PyObjectHandle _logger; }; -typedef IceUtil::Handle LoggerWrapperPtr; +using LoggerWrapperPtr = std::shared_ptr; bool initLogger(PyObject*); diff --git a/python/modules/IcePy/Makefile.mk b/python/modules/IcePy/Makefile.mk index 06645c1ea8a..15ffb845e33 100644 --- a/python/modules/IcePy/Makefile.mk +++ b/python/modules/IcePy/Makefile.mk @@ -8,9 +8,14 @@ IcePy_target := python-module IcePy_targetname := IcePy IcePy_targetdir := $(lang_srcdir)/python IcePy_installdir := $(install_pythondir) -IcePy_cppflags := -I$(project) $(ice_cpp_cppflags) -I$(top_srcdir)/cpp/src -I$(top_srcdir)/cpp/src/slice2py $(python_cppflags) -IcePy_system_libs := $(python_ldflags) -IcePy_dependencies := IceDiscovery IceLocatorDiscovery IceSSL Ice +IcePy_cppflags := -I$(project) $(ice_cpp_cppflags) -I$(top_srcdir)/cpp/src -I$(top_srcdir)/cpp/src/slice2py $(python_cppflags) \ + -DICE_CPP11_MAPPING +IcePy_dependencies := IceDiscovery++11 IceLocatorDiscovery++11 IceSSL++11 Ice++11 +# TODO temporary ++11 dependencies are not linked +IcePy_system_libs := $(python_ldflags) \ + -L$(top_srcdir)/cpp/lib/x86_64-linux-gnu \ + -L$(top_srcdir)/cpp/lib \ + -lIce++11 -lIceSSL++11 -lIceDiscovery++11 -lIceLocatorDiscovery++11 IcePy_libs := mcpp IcePy_extra_sources := $(wildcard $(top_srcdir)/cpp/src/Slice/*.cpp) \ $(top_srcdir)/cpp/src/slice2py/PythonUtil.cpp \ diff --git a/python/modules/IcePy/ObjectAdapter.cpp b/python/modules/IcePy/ObjectAdapter.cpp index 311bf6bf580..97162a249d7 100644 --- a/python/modules/IcePy/ObjectAdapter.cpp +++ b/python/modules/IcePy/ObjectAdapter.cpp @@ -478,7 +478,8 @@ adapterWaitForHold(ObjectAdapterObject* self, PyObject* args) } catch(const Ice::Exception& ex) { - self->holdException = ex.ice_clone(); + // Clone the exception and take ownership of the object. + self->holdException = ex.ice_clone().release(); } } @@ -585,7 +586,8 @@ adapterWaitForDeactivate(ObjectAdapterObject* self, PyObject* args) } catch(const Ice::Exception& ex) { - self->deactivateException = ex.ice_clone(); + // Clone the exception and take ownership of the object. + self->deactivateException = ex.ice_clone().release(); } } @@ -683,7 +685,7 @@ adapterAdd(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->add(wrapper, ident); @@ -731,7 +733,7 @@ adapterAddFacet(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->addFacet(wrapper, ident, facet); @@ -764,7 +766,7 @@ adapterAddWithUUID(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->addWithUUID(wrapper); @@ -804,7 +806,7 @@ adapterAddFacetWithUUID(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->addFacetWithUUID(wrapper, facet); @@ -1199,7 +1201,7 @@ adapterFindByProxy(ObjectAdapterObject* self, PyObject* args) return 0; } - Ice::ObjectPrx prx = getProxy(proxy); + shared_ptr prx = getProxy(proxy); assert(self->adapter); shared_ptr obj; @@ -1403,7 +1405,7 @@ adapterCreateProxy(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->createProxy(ident); @@ -1437,7 +1439,7 @@ adapterCreateDirectProxy(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->createDirectProxy(ident); @@ -1471,7 +1473,7 @@ adapterCreateIndirectProxy(ObjectAdapterObject* self, PyObject* args) } assert(self->adapter); - Ice::ObjectPrx proxy; + shared_ptr proxy; try { proxy = (*self->adapter)->createIndirectProxy(ident); @@ -1497,13 +1499,13 @@ adapterSetLocator(ObjectAdapterObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "setLocator", "loc", proxy, "Ice.LocatorPrx")) { return 0; } - Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + shared_ptr locator = Ice::uncheckedCast(proxy); assert(self->adapter); try @@ -1528,7 +1530,7 @@ static PyObject* adapterGetLocator(ObjectAdapterObject* self, PyObject* /*args*/) { assert(self->adapter); - Ice::LocatorPrx locator; + shared_ptr locator; try { locator = (*self->adapter)->getLocator(); @@ -1673,6 +1675,11 @@ adapterSetPublishedEndpoints(ObjectAdapterObject* self, PyObject* args) AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. (*self->adapter)->setPublishedEndpoints(seq); } + catch(const invalid_argument& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); + return 0; + } catch(const Ice::Exception& ex) { setPythonException(ex); diff --git a/python/modules/IcePy/Operation.cpp b/python/modules/IcePy/Operation.cpp index 492c16e1240..9b9f9e297a9 100644 --- a/python/modules/IcePy/Operation.cpp +++ b/python/modules/IcePy/Operation.cpp @@ -10,16 +10,19 @@ #include #include #include + #include #include #include +#include #include #include #include -#include #include #include + #include + #include "PythonUtil.h" using namespace std; @@ -44,13 +47,11 @@ class ParamInfo : public UnmarshalCallback int tag; Py_ssize_t pos; }; -typedef IceUtil::Handle ParamInfoPtr; -typedef list ParamInfoList; +using ParamInfoPtr = shared_ptr; +using ParamInfoList = list; -// // Encapsulates attributes of an operation. -// -class Operation : public IceUtil::Shared +class Operation { public: @@ -84,66 +85,56 @@ class Operation : public IceUtil::Shared static void convertParams(PyObject*, ParamInfoList&, Py_ssize_t, bool&); static ParamInfoPtr convertParam(PyObject*, Py_ssize_t); }; -typedef IceUtil::Handle OperationPtr; +using OperationPtr = shared_ptr; -// // The base class for client-side invocations. -// -class Invocation : public virtual IceUtil::Shared +class Invocation { public: - Invocation(const Ice::ObjectPrx&); + Invocation(const shared_ptr&); virtual PyObject* invoke(PyObject*, PyObject* = 0) = 0; protected: - // // Helpers for typed invocations. - // - enum MappingType { SyncMapping, NewAsyncMapping }; // TODO: rename enumerators + enum MappingType { SyncMapping, AsyncMapping }; bool prepareRequest(const OperationPtr&, PyObject*, MappingType, Ice::OutputStream*, pair&); PyObject* unmarshalResults(const OperationPtr&, const pair&); PyObject* unmarshalException(const OperationPtr&, const pair&); bool validateException(const OperationPtr&, PyObject*) const; - void checkTwowayOnly(const OperationPtr&, const Ice::ObjectPrx&) const; + void checkTwowayOnly(const OperationPtr&, const shared_ptr&) const; - Ice::ObjectPrx _prx; + shared_ptr _prx; Ice::CommunicatorPtr _communicator; }; -typedef IceUtil::Handle InvocationPtr; +using InvocationPtr = shared_ptr; -// -// Synchronous typed invocation. -// -class SyncTypedInvocation : public Invocation +class SyncTypedInvocation final : public Invocation { public: - SyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&); + SyncTypedInvocation(const shared_ptr&, const OperationPtr&); - virtual PyObject* invoke(PyObject*, PyObject* = 0); + PyObject* invoke(PyObject*, PyObject* = 0) final; private: OperationPtr _op; }; -// -// Asynchronous invocation with futures. -// -class NewAsyncInvocation : public Invocation // TODO: rename class +class AsyncInvocation : public Invocation { public: - NewAsyncInvocation(const Ice::ObjectPrx&, PyObject*, const string&); - ~NewAsyncInvocation(); + AsyncInvocation(const shared_ptr&, PyObject*, const string&); + ~AsyncInvocation(); - virtual PyObject* invoke(PyObject*, PyObject* = 0); + PyObject* invoke(PyObject*, PyObject* = 0) final; void response(bool, const pair&); void exception(const Ice::Exception&); @@ -151,7 +142,7 @@ class NewAsyncInvocation : public Invocation // TODO: rename class protected: - virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*) = 0; + virtual function handleInvoke(PyObject*, PyObject*) = 0; virtual void handleResponse(PyObject*, bool, const pair&) = 0; PyObject* _pyProxy; @@ -165,152 +156,142 @@ class NewAsyncInvocation : public Invocation // TODO: rename class vector _results; PyObject* _exception; }; -typedef IceUtil::Handle NewAsyncInvocationPtr; +using AsyncInvocationPtr = shared_ptr; -// -// New-style asynchronous typed invocation. -// -class NewAsyncTypedInvocation : public NewAsyncInvocation +class AsyncTypedInvocation final : public AsyncInvocation, public enable_shared_from_this { public: - NewAsyncTypedInvocation(const Ice::ObjectPrx&, PyObject*, const OperationPtr&); + AsyncTypedInvocation(const shared_ptr&, PyObject*, const OperationPtr&); protected: - virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*); - virtual void handleResponse(PyObject*, bool, const pair&); + function handleInvoke(PyObject*, PyObject*) final; + void handleResponse(PyObject*, bool, const pair&) final; private: OperationPtr _op; }; -// -// Synchronous blobject invocation. -// -class SyncBlobjectInvocation : public Invocation +class SyncBlobjectInvocation final : public Invocation { public: - SyncBlobjectInvocation(const Ice::ObjectPrx&); + SyncBlobjectInvocation(const shared_ptr&); - virtual PyObject* invoke(PyObject*, PyObject* = 0); + PyObject* invoke(PyObject*, PyObject* = 0) final; }; -// -// New-style asynchronous blobject invocation. -// -class NewAsyncBlobjectInvocation : public NewAsyncInvocation // TODO: rename class +class AsyncBlobjectInvocation final : public AsyncInvocation, public enable_shared_from_this { public: - NewAsyncBlobjectInvocation(const Ice::ObjectPrx&, PyObject*); + AsyncBlobjectInvocation(const shared_ptr&, PyObject*); protected: - virtual Ice::AsyncResultPtr handleInvoke(PyObject*, PyObject*); - virtual void handleResponse(PyObject*, bool, const pair&); + function handleInvoke(PyObject*, PyObject*) final; + void handleResponse(PyObject*, bool, const pair&) final; string _op; }; -// // The base class for server-side upcalls. -// -class Upcall : public IceUtil::Shared +class Upcall : public enable_shared_from_this { public: virtual void dispatch(PyObject*, const pair&, const Ice::Current&) = 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 UpcallPtr; - -// -// TypedUpcall uses the information in the given Operation to validate, marshal, and unmarshal -// parameters and exceptions. -// -class TypedUpcall; -typedef IceUtil::Handle TypedUpcallPtr; +using UpcallPtr = shared_ptr; -class TypedUpcall : public Upcall +// TypedUpcall uses the information in the given Operation to validate, marshal, and unmarshal parameters and exceptions. +class TypedUpcall final : public Upcall { public: - TypedUpcall(const OperationPtr&, const Ice::AMD_Object_ice_invokePtr&, const Ice::CommunicatorPtr&); + TypedUpcall( + const OperationPtr&, + function&)>, + function, + const Ice::CommunicatorPtr&); - virtual void dispatch(PyObject*, const pair&, const Ice::Current&); - virtual void response(PyObject*); - virtual void exception(PyException&); - virtual void exception(const Ice::Exception&); + void dispatch(PyObject*, const pair&, const Ice::Current&) final; + void response(PyObject*) final; + void exception(PyException&) final; private: OperationPtr _op; - Ice::AMD_Object_ice_invokePtr _callback; + + function&)> _response; + function _error; + Ice::CommunicatorPtr _communicator; Ice::EncodingVersion _encoding; }; +using TypedUpcallPtr = shared_ptr; // // Upcall for blobject servants. // -class BlobjectUpcall : public Upcall +class BlobjectUpcall final : public Upcall { public: - BlobjectUpcall(const Ice::AMD_Object_ice_invokePtr&); + BlobjectUpcall( + function&)>, + function); - virtual void dispatch(PyObject*, const pair&, const Ice::Current&); - virtual void response(PyObject*); - virtual void exception(PyException&); - virtual void exception(const Ice::Exception&); + void dispatch(PyObject*, const pair&, const Ice::Current&) final; + void response(PyObject*) final; + void exception(PyException&) final; private: - Ice::AMD_Object_ice_invokePtr _callback; + function&)> _response; + function _error; }; -// -// TypedServantWrapper uses the information in Operation to validate, marshal, and unmarshal -// parameters and exceptions. -// -class TypedServantWrapper : public ServantWrapper +// TypedServantWrapper uses the information in Operation to validate, marshal, and unmarshal parameters and exceptions. +class TypedServantWrapper final : public ServantWrapper { public: TypedServantWrapper(PyObject*); - virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, - const pair&, - const Ice::Current&); + void ice_invokeAsync( + pair inEncaps, + function&)> response, + function error, + const Ice::Current& current) final; private: - typedef map OperationMap; + using OperationMap = map; OperationMap _operationMap; OperationMap::iterator _lastOp; }; -// // Encapsulates a blobject servant. -// -class BlobjectServantWrapper : public ServantWrapper +class BlobjectServantWrapper final : public ServantWrapper { public: BlobjectServantWrapper(PyObject*); - virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, - const pair&, - const Ice::Current&); + void ice_invokeAsync( + pair inEncaps, + function&)> response, + function error, + const Ice::Current& current) final; }; struct OperationObject @@ -319,27 +300,17 @@ struct OperationObject OperationPtr* op; }; -struct DoneCallbackObject -{ - PyObject_HEAD - UpcallPtr* upcall; - PyObject* coroutine; -}; - struct DispatchCallbackObject { PyObject_HEAD UpcallPtr* upcall; }; -struct AsyncResultObject +struct AsyncInvocationContextObject { PyObject_HEAD - Ice::AsyncResultPtr* result; - InvocationPtr* invocation; - PyObject* proxy; - PyObject* connection; - PyObject* communicator; + function* cancel; + Ice::CommunicatorPtr* communicator; }; struct MarshaledResultObject @@ -352,20 +323,6 @@ extern PyTypeObject MarshaledResultType; extern PyTypeObject OperationType; -class UserExceptionFactory : public Ice::UserExceptionFactory -{ -public: - - virtual void createAndThrow(const string& id) - { - ExceptionInfoPtr info = lookupExceptionInfo(id); - if(info) - { - throw ExceptionReader(info); - } - } -}; - } namespace @@ -397,24 +354,6 @@ handleException() ex.raise(); } -void -callException(PyObject* method, PyObject* ex) -{ - PyObjectHandle tmp = callMethod(method, ex); - if(PyErr_Occurred()) - { - handleException(); // Callback raised an exception. - } -} - -void -callException(PyObject* method, const Ice::Exception& ex) -{ - PyObjectHandle exh = convertException(ex); - assert(exh.get()); - callException(method, exh.get()); -} - } #ifdef WIN32 @@ -457,10 +396,18 @@ operationInit(OperationObject* self, PyObject* args, PyObject* /*kwds*/) return -1; } - OperationPtr op = new Operation(name, mode, sendMode, amd, format, metaData, inParams, outParams, returnType, - exceptions); - self->op = new OperationPtr(op); - + self->op = new OperationPtr( + make_shared( + name, + mode, + sendMode, + amd, + format, + metaData, + inParams, + outParams, + returnType, + exceptions)); return 0; } @@ -487,10 +434,10 @@ operationInvoke(OperationObject* self, PyObject* args) return 0; } - Ice::ObjectPrx prx = getProxy(pyProxy); + shared_ptr prx = getProxy(pyProxy); assert(self->op); - InvocationPtr i = new SyncTypedInvocation(prx, *self->op); + InvocationPtr i = make_shared(prx, *self->op); return i->invoke(opArgs); } @@ -507,8 +454,8 @@ operationInvokeAsync(OperationObject* self, PyObject* args) return 0; } - Ice::ObjectPrx p = getProxy(proxy); - InvocationPtr i = new NewAsyncTypedInvocation(p, proxy, *self->op); + shared_ptr prx = getProxy(proxy); + InvocationPtr i = make_shared(prx, proxy, *self->op); return i->invoke(opArgs); } @@ -530,79 +477,6 @@ operationDeprecate(OperationObject* self, PyObject* args) return incRef(Py_None); } -// -// DoneCallback operations -// - -#ifdef WIN32 -extern "C" -#endif -static DoneCallbackObject* -doneCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) -{ - DoneCallbackObject* self = reinterpret_cast(type->tp_alloc(type, 0)); - if(!self) - { - return 0; - } - self->upcall = 0; - self->coroutine = 0; - return self; -} - -#ifdef WIN32 -extern "C" -#endif -static void -doneCallbackDealloc(DoneCallbackObject* self) -{ - delete self->upcall; - Py_XDECREF(self->coroutine); - Py_TYPE(self)->tp_free(reinterpret_cast(self)); -} - -#ifdef WIN32 -extern "C" -#endif -static PyObject* -doneCallbackInvoke(DoneCallbackObject* self, PyObject* args) -{ - PyObject* future = 0; - if(!PyArg_ParseTuple(args, STRCAST("O"), &future)) - { - return 0; - } - - try - { - assert(self->upcall); - - PyObjectHandle resultMethod = getAttr(future, "result", false); - 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(...) - { - // - // No exceptions should propagate to Python. - // - assert(false); - } - - return incRef(Py_None); -} - // // DispatchCallbackObject operations // @@ -690,24 +564,21 @@ dispatchCallbackException(DispatchCallbackObject* self, PyObject* args) } // -// AsyncResult operations +// AsyncInvocationContext operations // #ifdef WIN32 extern "C" #endif -static AsyncResultObject* -asyncResultNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +static AsyncInvocationContextObject* +asyncInvocationContextNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) { - AsyncResultObject* self = reinterpret_cast(type->tp_alloc(type, 0)); - if(!self) + auto self = reinterpret_cast(type->tp_alloc(type, 0)); + if (!self) { return 0; } - self->result = 0; - self->invocation = 0; - self->proxy = 0; - self->connection = 0; + self->cancel = 0; self->communicator = 0; return self; } @@ -716,13 +587,10 @@ asyncResultNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) extern "C" #endif static void -asyncResultDealloc(AsyncResultObject* self) +asyncInvocationContextDealloc(AsyncInvocationContextObject* self) { - delete self->result; - delete self->invocation; - Py_XDECREF(self->proxy); - Py_XDECREF(self->connection); - Py_XDECREF(self->communicator); + delete self->cancel; + delete self->communicator; Py_TYPE(self)->tp_free(reinterpret_cast(self)); } @@ -730,25 +598,11 @@ asyncResultDealloc(AsyncResultObject* self) extern "C" #endif static PyObject* -asyncResultGetCommunicator(AsyncResultObject* self, PyObject* /*args*/) -{ - if(self->communicator) - { - return incRef(self->communicator); - } - - return incRef(Py_None); -} - -#ifdef WIN32 -extern "C" -#endif -static PyObject* -asyncResultCancel(AsyncResultObject* self, PyObject* /*args*/) +asyncInvocationContextCancel(AsyncInvocationContextObject* self, PyObject* /*args*/) { try { - (*self->result)->cancel(); + (*self->cancel)(); } catch(...) { @@ -762,35 +616,7 @@ asyncResultCancel(AsyncResultObject* self, PyObject* /*args*/) extern "C" #endif static PyObject* -asyncResultGetConnection(AsyncResultObject* self, PyObject* /*args*/) -{ - if(self->connection) - { - return incRef(self->connection); - } - - return incRef(Py_None); -} - -#ifdef WIN32 -extern "C" -#endif -static PyObject* -asyncResultGetProxy(AsyncResultObject* self, PyObject* /*args*/) -{ - if(self->proxy) - { - return incRef(self->proxy); - } - - return incRef(Py_None); -} - -#ifdef WIN32 -extern "C" -#endif -static PyObject* -asyncResultCallLater(AsyncResultObject* self, PyObject* args) +asyncInvocationContextCallLater(AsyncInvocationContextObject* self, PyObject* args) { PyObject* callback; if(!PyArg_ParseTuple(args, STRCAST("O"), &callback)) @@ -804,23 +630,23 @@ asyncResultCallLater(AsyncResultObject* self, PyObject* args) return 0; } - class CallbackI : public Ice::AsyncResult::Callback + class CallbackWrapper final { public: - CallbackI(PyObject* callback) : + CallbackWrapper(PyObject* callback) : _callback(incRef(callback)) { } - ~CallbackI() + ~CallbackWrapper() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. Py_DECREF(_callback); } - virtual void run() + void run() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -835,9 +661,11 @@ asyncResultCallLater(AsyncResultObject* self, PyObject* args) PyObject* _callback; }; + // CommunicatorDestroyedException is the only exception that can propagate directly from this method. try { - (*self->result)->_scheduleCallback(new CallbackI(callback)); + auto callbackWrapper = make_shared(callback); + (*self->communicator)->postToClientThreadPool([callbackWrapper]() { callbackWrapper->run(); }); } catch(const Ice::CommunicatorDestroyedException& ex) { @@ -973,7 +801,7 @@ IcePy::Operation::Operation(const char* n, PyObject* m, PyObject* sm, int amdFla // if(fmt == Py_None) { - format = Ice::DefaultFormat; + format = Ice::FormatType::DefaultFormat; } else { @@ -1226,7 +1054,7 @@ IcePy::Operation::convertParam(PyObject* p, Py_ssize_t pos) assert(PyTuple_Check(p)); assert(PyTuple_GET_SIZE(p) == 4); - ParamInfoPtr param = new ParamInfo; + auto param = make_shared(); // // metaData @@ -1277,13 +1105,6 @@ static PyMethodDef OperationMethods[] = { 0, 0 } /* sentinel */ }; -static PyMethodDef DoneCallbackMethods[] = -{ - { STRCAST("invoke"), reinterpret_cast(doneCallbackInvoke), METH_VARARGS, - PyDoc_STR(STRCAST("internal function")) }, - { 0, 0 } /* sentinel */ -}; - static PyMethodDef DispatchCallbackMethods[] = { { STRCAST("response"), reinterpret_cast(dispatchCallbackResponse), METH_VARARGS, @@ -1293,18 +1114,20 @@ static PyMethodDef DispatchCallbackMethods[] = { 0, 0 } /* sentinel */ }; -static PyMethodDef AsyncResultMethods[] = -{ - { STRCAST("cancel"), reinterpret_cast(asyncResultCancel), METH_NOARGS, - PyDoc_STR(STRCAST("cancels the invocation")) }, - { STRCAST("getCommunicator"), reinterpret_cast(asyncResultGetCommunicator), METH_NOARGS, - PyDoc_STR(STRCAST("returns the communicator for the invocation")) }, - { STRCAST("getConnection"), reinterpret_cast(asyncResultGetConnection), METH_NOARGS, - PyDoc_STR(STRCAST("returns the connection for the invocation")) }, - { STRCAST("getProxy"), reinterpret_cast(asyncResultGetProxy), METH_NOARGS, - PyDoc_STR(STRCAST("returns the proxy for the invocation")) }, - { STRCAST("callLater"), reinterpret_cast(asyncResultCallLater), METH_VARARGS, - PyDoc_STR(STRCAST("internal function")) }, +static PyMethodDef AsyncInvocationContextMethods[] = +{ + { + STRCAST("cancel"), + reinterpret_cast(asyncInvocationContextCancel), + METH_NOARGS, + PyDoc_STR(STRCAST("cancels the invocation")) + }, + { + STRCAST("callLater"), + reinterpret_cast(asyncInvocationContextCallLater), + METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) + }, { 0, 0 } /* sentinel */ }; @@ -1358,53 +1181,6 @@ PyTypeObject OperationType = 0, /* tp_is_gc */ }; -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.DoneCallback"), /* tp_name */ - sizeof(DoneCallbackObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - reinterpret_cast(doneCallbackDealloc), /* 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 */ - DoneCallbackMethods, /* 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(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 @@ -1452,16 +1228,16 @@ static PyTypeObject DispatchCallbackType = 0, /* tp_is_gc */ }; -PyTypeObject AsyncResultType = +PyTypeObject AsyncInvocationContextType = { /* 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.AsyncResult"), /* tp_name */ - sizeof(AsyncResultObject), /* tp_basicsize */ - 0, /* tp_itemsize */ + STRCAST("IcePy.AsyncInvocationContext"), /* tp_name */ + sizeof(AsyncInvocationContextObject), /* tp_basicsize */ + 0, /* tp_itemsize */ /* methods */ - reinterpret_cast(asyncResultDealloc), /* tp_dealloc */ + reinterpret_cast(asyncInvocationContextDealloc), /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -1484,7 +1260,7 @@ PyTypeObject AsyncResultType = 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - AsyncResultMethods, /* tp_methods */ + AsyncInvocationContextMethods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1494,7 +1270,7 @@ PyTypeObject AsyncResultType = 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - reinterpret_cast(asyncResultNew), /* tp_new */ + reinterpret_cast(asyncInvocationContextNew), /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ }; @@ -1561,16 +1337,6 @@ IcePy::initOperation(PyObject* module) return false; } - if(PyType_Ready(&DoneCallbackType) < 0) - { - return false; - } - PyTypeObject* cbType = &DoneCallbackType; // Necessary to prevent GCC's strict-alias warnings. - if(PyModule_AddObject(module, STRCAST("DoneCallback"), reinterpret_cast(cbType)) < 0) - { - return false; - } - if(PyType_Ready(&DispatchCallbackType) < 0) { return false; @@ -1581,12 +1347,12 @@ IcePy::initOperation(PyObject* module) return false; } - if(PyType_Ready(&AsyncResultType) < 0) + if(PyType_Ready(&AsyncInvocationContextType) < 0) { return false; } - PyTypeObject* arType = &AsyncResultType; // Necessary to prevent GCC's strict-alias warnings. - if(PyModule_AddObject(module, STRCAST("AsyncResult"), reinterpret_cast(arType)) < 0) + PyTypeObject* arType = &AsyncInvocationContextType; // Necessary to prevent GCC's strict-alias warnings. + if (PyModule_AddObject(module, STRCAST("AsyncInvocationContext"), reinterpret_cast(arType)) < 0) { return false; } @@ -1607,8 +1373,9 @@ IcePy::initOperation(PyObject* module) // // Invocation // -IcePy::Invocation::Invocation(const Ice::ObjectPrx& prx) : - _prx(prx), _communicator(prx->ice_getCommunicator()) +IcePy::Invocation::Invocation(const shared_ptr& prx) : + _prx(prx), + _communicator(prx->ice_getCommunicator()) { } @@ -1627,7 +1394,7 @@ IcePy::Invocation::prepareRequest(const OperationPtr& op, PyObject* args, Mappin if(argc != paramCount) { string opName; - if(mapping == NewAsyncMapping) + if(mapping == AsyncMapping) { opName = op->name + "Async"; } @@ -1662,7 +1429,7 @@ IcePy::Invocation::prepareRequest(const OperationPtr& op, PyObject* args, Mappin if((!info->optional || arg != Unset) && !info->type->validate(arg)) { string name; - if(mapping == NewAsyncMapping) + if(mapping == AsyncMapping) { name = op->name + "Async"; } @@ -1679,9 +1446,8 @@ IcePy::Invocation::prepareRequest(const OperationPtr& op, PyObject* args, Mappin // // Marshal the required parameters. // - for(p = op->inParams.begin(); p != op->inParams.end(); ++p) + for (const auto& info : op->inParams) { - ParamInfoPtr info = *p; if(!info->optional) { PyObject* arg = PyTuple_GET_ITEM(args, info->pos); @@ -1692,9 +1458,8 @@ IcePy::Invocation::prepareRequest(const OperationPtr& op, PyObject* args, Mappin // // Marshal the optional parameters. // - for(p = op->optionalInParams.begin(); p != op->optionalInParams.end(); ++p) + for(const auto& info : op->optionalInParams) { - ParamInfoPtr info = *p; PyObject* arg = PyTuple_GET_ITEM(args, info->pos); if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat())) { @@ -1821,8 +1586,14 @@ IcePy::Invocation::unmarshalException(const OperationPtr& op, const pair& proxy) const { if((op->returnType != 0 || !op->outParams.empty() || !op->exceptions.empty()) && !proxy->ice_isTwoway()) { @@ -1894,8 +1665,9 @@ IcePy::Invocation::checkTwowayOnly(const OperationPtr& op, const Ice::ObjectPrx& // // SyncTypedInvocation // -IcePy::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) : - Invocation(prx), _op(op) +IcePy::SyncTypedInvocation::SyncTypedInvocation(const shared_ptr& prx, const OperationPtr& op) : + Invocation(prx), + _op(op) { } @@ -1927,49 +1699,48 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) // vector result; bool status; + Ice::Context ctx; + if(pyctx != Py_None) { - if(pyctx != Py_None) + if(!PyDict_Check(pyctx)) { - 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. - status = _prx->ice_invoke(_op->name, _op->sendMode, params, result, ctx); + PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary")); + return 0; } - else + + if(!dictionaryToContext(pyctx, ctx)) { - AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. - status = _prx->ice_invoke(_op->name, _op->sendMode, params, result); + return 0; } } + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + status = _prx->ice_invoke( + _op->name, + _op->sendMode, + params, + result, + pyctx == Py_None ? Ice::noExplicitContext : ctx); + } + // // Process the reply. // if(_prx->ice_isTwoway()) { + pair rb { 0, 0 }; + if(!result.empty()) + { + rb.first = &result[0]; + rb.second = &result[0] + result.size(); + } + if(!status) { // // Unmarshal a user exception. // - pair rb(static_cast(0), - static_cast(0)); - if(!result.empty()) - { - rb.first = &result[0]; - rb.second = &result[0] + result.size(); - } PyObjectHandle ex = unmarshalException(_op, rb); // @@ -1984,13 +1755,6 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) // Unmarshal the results. If there is more than one value to be returned, then return them // in a tuple of the form (result, outParam1, ...). Otherwise just return the value. // - pair rb(static_cast(0), - static_cast(0)); - if(!result.empty()) - { - rb.first = &result[0]; - rb.second = &result[0] + result.size(); - } PyObjectHandle results = unmarshalResults(_op, rb); if(!results.get()) { @@ -2031,16 +1795,24 @@ IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) } // -// NewAsyncInvocation +// AsyncInvocation // -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) +IcePy::AsyncInvocation::AsyncInvocation(const shared_ptr& 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::NewAsyncInvocation::~NewAsyncInvocation() +IcePy::AsyncInvocation::~AsyncInvocation() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -2050,17 +1822,15 @@ IcePy::NewAsyncInvocation::~NewAsyncInvocation() } PyObject* -IcePy::NewAsyncInvocation::invoke(PyObject* args, PyObject* kwds) +IcePy::AsyncInvocation::invoke(PyObject* args, PyObject* kwds) { - // // Called from Python code, so the GIL is already acquired. - // - Ice::AsyncResultPtr result; + function cancel; try { - result = handleInvoke(args, kwds); + cancel = handleInvoke(args, kwds); } catch(const Ice::CommunicatorDestroyedException& ex) { @@ -2090,23 +1860,17 @@ IcePy::NewAsyncInvocation::invoke(PyObject* args, PyObject* kwds) { return 0; } + assert(cancel); - assert(result); - - // - // NOTE: Any time we call into interpreted Python code there's a chance that another thread will be - // allowed to run! - // - - PyObjectHandle communicatorObj = getCommunicatorWrapper(_communicator); + // Any time we call into interpreted Python code there's a chance that another thread will be allowed to run! - PyObjectHandle asyncResultObj = createAsyncResult(result, _pyProxy, 0, communicatorObj.get()); - if(!asyncResultObj.get()) + PyObjectHandle asyncInvocationContextObj = createAsyncInvocationContext(std::move(cancel), _communicator); + if (!asyncInvocationContextObj.get()) { return 0; } - PyObjectHandle future = createFuture(_operation, asyncResultObj.get()); // Calls into Python code. + PyObjectHandle future = createFuture(_operation, asyncInvocationContextObj.get()); // Calls into Python code. if(!future.get()) { return 0; @@ -2138,7 +1902,7 @@ IcePy::NewAsyncInvocation::invoke(PyObject* args, PyObject* kwds) } } - if(_done) + if (_done) { if(_exception) { @@ -2176,7 +1940,7 @@ IcePy::NewAsyncInvocation::invoke(PyObject* args, PyObject* kwds) } void -IcePy::NewAsyncInvocation::response(bool ok, const pair& results) +IcePy::AsyncInvocation::response(bool ok, const pair& results) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -2221,13 +1985,12 @@ IcePy::NewAsyncInvocation::response(bool ok, const pairname), _op(op) +IcePy::AsyncTypedInvocation::AsyncTypedInvocation( + const shared_ptr& prx, + PyObject* pyProxy, + const OperationPtr& op) + : AsyncInvocation(prx, pyProxy, op->name), + _op(op) { } -Ice::AsyncResultPtr -IcePy::NewAsyncTypedInvocation::handleInvoke(PyObject* args, PyObject* /* kwds */) +function +IcePy::AsyncTypedInvocation::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) @@ -2321,91 +2083,82 @@ IcePy::NewAsyncTypedInvocation::handleInvoke(PyObject* args, PyObject* /* kwds * assert(PyTuple_Check(pyparams)); PyObject* pyctx = PyTuple_GET_ITEM(args, 1); - // // Marshal the input parameters to a byte sequence. - // Ice::OutputStream os(_communicator); pair params; - if(!prepareRequest(_op, pyparams, NewAsyncMapping, &os, params)) + if(!prepareRequest(_op, pyparams, AsyncMapping, &os, params)) { return 0; } checkTwowayOnly(_op, _prx); - NewAsyncInvocationPtr self = this; - Ice::Callback_Object_ice_invokePtr cb; - if(!_prx->ice_isBatchOneway() && !_prx->ice_isBatchDatagram()) - { - cb = Ice::newCallback_Object_ice_invoke(self, - &NewAsyncInvocation::response, - &NewAsyncInvocation::exception, - &NewAsyncInvocation::sent); - } - - // // Invoke the operation asynchronously. - // + Ice::Context context; 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)) + if(!dictionaryToContext(pyctx, context)) { return 0; } + } - if(cb) + auto self = shared_from_this(); + return _prx->ice_invokeAsync( + _op->name, + _op->sendMode, + params, + [self](bool ok, const pair& results) { - return _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb); - } - else - { - return _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx); - } - } - else - { - if(cb) + self->response(ok, results); + }, + [self](exception_ptr exptr) { - return _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb); - } - else + try + { + rethrow_exception(exptr); + } + catch(const Ice::Exception& ex) + { + self->exception(ex); + } + }, + [self](bool sentSynchronously) { - return _prx->begin_ice_invoke(_op->name, _op->sendMode, params); - } - } + self->sent(sentSynchronously); + }, + pyctx == Py_None ? Ice::noExplicitContext : context); } void -IcePy::NewAsyncTypedInvocation::handleResponse(PyObject* future, bool ok, - const pair& results) +IcePy::AsyncTypedInvocation::handleResponse( + PyObject* future, + bool ok, + const pair& results) { try { - if(ok) + if (ok) { - // // Unmarshal the results. - // PyObjectHandle args; try { args = unmarshalResults(_op, results); - if(!args.get()) + if (!args.get()) { assert(PyErr_Occurred()); return; } } - catch(const Ice::Exception& ex) + catch (const Ice::Exception& ex) { PyObjectHandle exh = convertException(ex); assert(exh.get()); @@ -2414,19 +2167,17 @@ IcePy::NewAsyncTypedInvocation::handleResponse(PyObject* future, bool ok, return; } - // // 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) + if (PyTuple_GET_SIZE(args.get()) == 0) { r = incRef(Py_None); } - else if(PyTuple_GET_SIZE(args.get()) == 1) + else if (PyTuple_GET_SIZE(args.get()) == 1) { r = incRef(PyTuple_GET_ITEM(args.get(), 0)); // PyTuple_GET_ITEM steals a reference. } @@ -2445,16 +2196,13 @@ IcePy::NewAsyncTypedInvocation::handleResponse(PyObject* future, bool ok, PyErr_Clear(); } } - catch(const AbortMarshaling&) + catch (const AbortMarshaling&) { assert(PyErr_Occurred()); } } -// -// SyncBlobjectInvocation -// -IcePy::SyncBlobjectInvocation::SyncBlobjectInvocation(const Ice::ObjectPrx& prx) +IcePy::SyncBlobjectInvocation::SyncBlobjectInvocation(const shared_ptr& prx) : Invocation(prx) { } @@ -2478,8 +2226,9 @@ IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) assert(!PyErr_Occurred()); Py_ssize_t sz = PyBytes_GET_SIZE(inParams); - pair in(static_cast(0), - static_cast(0)); + pair in( + static_cast(0), + static_cast(0)); if(sz > 0) { in.first = reinterpret_cast(PyBytes_AS_STRING(inParams)); @@ -2491,21 +2240,23 @@ IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) vector out; bool ok; - if(ctx == 0 || ctx == Py_None) - { - AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. - ok = _prx->ice_invoke(operation, sendMode, in, out); - } - else + Ice::Context context; + if(ctx != 0 && ctx != Py_None) { - Ice::Context context; if(!dictionaryToContext(ctx, context)) { return 0; } + } + { AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. - ok = _prx->ice_invoke(operation, sendMode, in, out, context); + ok = _prx->ice_invoke( + operation, + sendMode, + in, + out, + ctx == 0 || ctx == Py_None ? Ice::noExplicitContext : context); } // @@ -2544,16 +2295,13 @@ IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) } } -// -// NewAsyncBlobjectInvocation -// -IcePy::NewAsyncBlobjectInvocation::NewAsyncBlobjectInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy) : - NewAsyncInvocation(prx, pyProxy, "ice_invoke") +IcePy::AsyncBlobjectInvocation::AsyncBlobjectInvocation(const shared_ptr& prx, PyObject* pyProxy) : + AsyncInvocation(prx, pyProxy, "ice_invoke") { } -Ice::AsyncResultPtr -IcePy::NewAsyncBlobjectInvocation::handleInvoke(PyObject* args, PyObject* /* kwds */) +function +IcePy::AsyncBlobjectInvocation::handleInvoke(PyObject* args, PyObject* /* kwds */) { char* operation; PyObject* mode; @@ -2573,61 +2321,56 @@ IcePy::NewAsyncBlobjectInvocation::handleInvoke(PyObject* args, PyObject* /* kwd assert(!PyErr_Occurred()); Py_ssize_t sz = PyBytes_GET_SIZE(inParams); - pair in(static_cast(0), - static_cast(0)); + pair params { 0, 0 }; if(sz > 0) { - in.first = reinterpret_cast(PyBytes_AS_STRING(inParams)); - in.second = in.first + sz; + params.first = reinterpret_cast(PyBytes_AS_STRING(inParams)); + params.second = params.first + sz; } - NewAsyncInvocationPtr self = this; - Ice::Callback_Object_ice_invokePtr cb; - if(!_prx->ice_isBatchOneway() && !_prx->ice_isBatchDatagram()) + Ice::Context context; + if (ctx != 0 || ctx != Py_None) { - cb = Ice::newCallback_Object_ice_invoke(self, - &NewAsyncInvocation::response, - &NewAsyncInvocation::exception, - &NewAsyncInvocation::sent); - } - - if(ctx == 0 || ctx == Py_None) - { - if(cb) - { - return _prx->begin_ice_invoke(operation, sendMode, in, cb); - } - else - { - return _prx->begin_ice_invoke(operation, sendMode, in); - } - } - else - { - Ice::Context context; - if(!dictionaryToContext(ctx, context)) + if (!dictionaryToContext(ctx, context)) { return 0; } + } - if(cb) + auto self = shared_from_this(); + return _prx->ice_invokeAsync( + operation, + sendMode, + params, + [self](bool ok, const pair& results) { - return _prx->begin_ice_invoke(operation, sendMode, in, context, cb); - } - else + self->response(ok, results); + }, + [self](exception_ptr exptr) { - return _prx->begin_ice_invoke(operation, sendMode, in, context); - } - } + try + { + rethrow_exception(exptr); + } + catch(const Ice::Exception& ex) + { + self->exception(ex); + } + }, + [self](bool sentSynchronously) + { + self->sent(sentSynchronously); + }, + (ctx == 0 || ctx == Py_None) ? Ice::noExplicitContext : context); } void -IcePy::NewAsyncBlobjectInvocation::handleResponse(PyObject* future, bool ok, - const pair& results) +IcePy::AsyncBlobjectInvocation::handleResponse( + PyObject* future, + bool ok, + const pair& results) { - // - // Prepare the args as a tuple of the bool and out param buffer. - // + // Prepare the args as a tuple of the bool and out param buffer. PyObjectHandle args = PyTuple_New(2); if(!args.get()) { @@ -2710,7 +2453,7 @@ Upcall::dispatchImpl(PyObject* servant, const string& dispatchName, PyObject* ar { throwPythonException(); } - callback->upcall = new UpcallPtr(this); + callback->upcall = new UpcallPtr(shared_from_this()); PyTuple_SET_ITEM(dispatchArgs.get(), 0, reinterpret_cast(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. @@ -2733,15 +2476,23 @@ Upcall::dispatchImpl(PyObject* servant, const string& dispatchName, PyObject* ar // // TypedUpcall // -IcePy::TypedUpcall::TypedUpcall(const OperationPtr& op, const Ice::AMD_Object_ice_invokePtr& callback, - const Ice::CommunicatorPtr& communicator) : - _op(op), _callback(callback), _communicator(communicator) +IcePy::TypedUpcall::TypedUpcall( + const OperationPtr& op, + function&)> response, + function error, + const Ice::CommunicatorPtr& communicator) : + _op(op), + _response(std::move(response)), + _error(std::move(error)), + _communicator(communicator) { } void -IcePy::TypedUpcall::dispatch(PyObject* servant, const pair& inBytes, - const Ice::Current& current) +IcePy::TypedUpcall::dispatch( + PyObject* servant, + const pair& inBytes, + const Ice::Current& current) { _encoding = current.encoding; @@ -2838,7 +2589,7 @@ IcePy::TypedUpcall::response(PyObject* result) if(PyObject_IsInstance(result, reinterpret_cast(&MarshaledResultType))) { MarshaledResultObject* mro = reinterpret_cast(result); - _callback->ice_response(true, mro->out->finished()); + _response(true, mro->out->finished()); } else { @@ -2846,29 +2597,26 @@ IcePy::TypedUpcall::response(PyObject* result) { Ice::OutputStream os(_communicator); os.startEncapsulation(_encoding, _op->format); - _op->marshalResult(os, result); - os.endEncapsulation(); - - _callback->ice_response(true, os.finished()); + _response(true, os.finished()); } - catch(const AbortMarshaling&) + catch (const AbortMarshaling&) { try { throwPythonException(); } - catch(const Ice::Exception& ex) + catch (const Ice::Exception&) { - _callback->ice_exception(ex); + _error(current_exception()); } } } } - catch(const Ice::Exception& ex) + catch (const Ice::Exception&) { - _callback->ice_exception(ex); + _error(current_exception()); } } @@ -2896,7 +2644,7 @@ IcePy::TypedUpcall::exception(PyException& ex) // PyObjectHandle iceType = getAttr(ex.ex.get(), "_ice_type", false); assert(iceType.get()); - ExceptionInfoPtr info = ExceptionInfoPtr::dynamicCast(getException(iceType.get())); + ExceptionInfoPtr info = dynamic_pointer_cast(getException(iceType.get())); assert(info); Ice::OutputStream os(_communicator); @@ -2904,10 +2652,8 @@ IcePy::TypedUpcall::exception(PyException& ex) ExceptionWriter writer(ex.ex, info); os.writeException(writer); - os.endEncapsulation(); - - _callback->ice_response(false, os.finished()); + _response(false, os.finished()); } else { @@ -2919,29 +2665,28 @@ IcePy::TypedUpcall::exception(PyException& ex) throwPythonException(); } } - catch(const Ice::Exception& e) + catch(const Ice::Exception&) { - exception(e); + _error(current_exception()); } } -void -IcePy::TypedUpcall::exception(const Ice::Exception& ex) -{ - _callback->ice_exception(ex); -} - // // BlobjectUpcall // -IcePy::BlobjectUpcall::BlobjectUpcall(const Ice::AMD_Object_ice_invokePtr& callback) : - _callback(callback) +IcePy::BlobjectUpcall::BlobjectUpcall( + function&)> response, + function error) : + _response(std::move(response)), + _error(std::move(error)) { } void -IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair& inBytes, - const Ice::Current& current) +IcePy::BlobjectUpcall::dispatch( + PyObject* servant, + const pair& inBytes, + const Ice::Current& current) { Ice::CommunicatorPtr communicator = current.adapter->getCommunicator(); @@ -3003,15 +2748,14 @@ IcePy::BlobjectUpcall::response(PyObject* result) } Py_ssize_t sz = PyBytes_GET_SIZE(arg); - pair r(static_cast(0), - static_cast(0)); + pair r { 0, 0 }; if(sz > 0) { r.first = reinterpret_cast(PyBytes_AS_STRING(arg)); r.second = r.first + sz; } - _callback->ice_response(isTrue, r); + _response(isTrue, r); } catch(const AbortMarshaling&) { @@ -3019,14 +2763,14 @@ IcePy::BlobjectUpcall::response(PyObject* result) { throwPythonException(); } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { - exception(ex); + _error(current_exception()); } } - catch(const Ice::Exception& ex) + catch(const Ice::Exception&) { - exception(ex); + _error(current_exception()); } } @@ -3045,18 +2789,12 @@ IcePy::BlobjectUpcall::exception(PyException& ex) ex.raise(); } - catch(const Ice::Exception& e) + catch(const Ice::Exception&) { - exception(e); + _error(current_exception()); } } -void -IcePy::BlobjectUpcall::exception(const Ice::Exception& ex) -{ - _callback->ice_exception(ex); -} - PyObject* IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args) { @@ -3069,8 +2807,8 @@ IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args) OperationPtr op = getOperation(obj.get()); assert(op); - Ice::ObjectPrx p = getProxy(proxy); - InvocationPtr i = new SyncTypedInvocation(p, op); + shared_ptr prx = getProxy(proxy); + InvocationPtr i = make_shared(prx, op); return i->invoke(args); } @@ -3086,52 +2824,46 @@ IcePy::invokeBuiltinAsync(PyObject* proxy, const string& builtin, PyObject* args OperationPtr op = getOperation(obj.get()); assert(op); - Ice::ObjectPrx p = getProxy(proxy); - InvocationPtr i = new NewAsyncTypedInvocation(p, proxy, op); + shared_ptr prx = getProxy(proxy); + InvocationPtr i = make_shared(prx, proxy, op); return i->invoke(args); } PyObject* IcePy::iceInvoke(PyObject* proxy, PyObject* args) { - Ice::ObjectPrx p = getProxy(proxy); - InvocationPtr i = new SyncBlobjectInvocation(p); + shared_ptr prx = getProxy(proxy); + InvocationPtr i = make_shared(prx); return i->invoke(args); } PyObject* IcePy::iceInvokeAsync(PyObject* proxy, PyObject* args) { - Ice::ObjectPrx p = getProxy(proxy); - InvocationPtr i = new NewAsyncBlobjectInvocation(p, proxy); + shared_ptr prx = getProxy(proxy); + InvocationPtr i = make_shared(prx, proxy); return i->invoke(args); } PyObject* -IcePy::createAsyncResult(const Ice::AsyncResultPtr& r, PyObject* proxy, PyObject* connection, PyObject* communicator) +IcePy::createAsyncInvocationContext(function cancel, Ice::CommunicatorPtr communicator) { - AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0); - if(!obj) + AsyncInvocationContextObject* obj = asyncInvocationContextNew(&AsyncInvocationContextType, 0, 0); + if (!obj) { return 0; } - obj->result = new Ice::AsyncResultPtr(r); - obj->proxy = incRef(proxy); - obj->connection = incRef(connection); - obj->communicator = incRef(communicator); + obj->cancel = new function(std::move(cancel)); + obj->communicator = new Ice::CommunicatorPtr(std::move(communicator)); return reinterpret_cast(obj); } -Ice::AsyncResultPtr -IcePy::getAsyncResult(PyObject* p) -{ - assert(PyObject_IsInstance(p, reinterpret_cast(&AsyncResultType)) == 1); - AsyncResultObject* obj = reinterpret_cast(p); - return *obj->result; -} - IcePy::FlushAsyncCallback::FlushAsyncCallback(const string& op) : - _op(op), _future(0), _sent(false), _sentSynchronously(false), _exception(0) + _op(op), + _future(0), + _sent(false), + _sentSynchronously(false), + _exception(0) { } @@ -3224,48 +2956,13 @@ IcePy::FlushAsyncCallback::sent(bool sentSynchronously) _future = 0; } -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); -} - -IcePy::GetConnectionAsyncCallback::GetConnectionAsyncCallback(const Ice::CommunicatorPtr& communicator, - const string& op) : - _communicator(communicator), _op(op), _future(0), _exception(0) +IcePy::GetConnectionAsyncCallback::GetConnectionAsyncCallback( + const Ice::CommunicatorPtr& communicator, + const string& op) : + _communicator(communicator), + _op(op), + _future(0), + _exception(0) { } @@ -3381,9 +3078,11 @@ IcePy::TypedServantWrapper::TypedServantWrapper(PyObject* servant) : } void -IcePy::TypedServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, - const pair& inParams, - const Ice::Current& current) +IcePy::TypedServantWrapper::ice_invokeAsync( + pair inParams, + function&)> response, + function error, + const Ice::Current& current) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. @@ -3440,12 +3139,16 @@ IcePy::TypedServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr _iceCheckMode(op->mode, current.mode); } - UpcallPtr up = new TypedUpcall(op, cb, current.adapter->getCommunicator()); + UpcallPtr up = make_shared( + op, + std::move(response), + std::move(error), + current.adapter->getCommunicator()); up->dispatch(_servant, inParams, current); } - catch(const Ice::Exception& ex) + catch (const Ice::Exception&) { - cb->ice_exception(ex); + error(current_exception()); } } @@ -3458,20 +3161,21 @@ IcePy::BlobjectServantWrapper::BlobjectServantWrapper(PyObject* servant) : } void -IcePy::BlobjectServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, - const pair& inParams, - const Ice::Current& current) +IcePy::BlobjectServantWrapper::ice_invokeAsync( + pair inParams, + function&)> response, + function error, + const Ice::Current& current) { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. - try { - UpcallPtr up = new BlobjectUpcall(cb); + UpcallPtr up = make_shared(std::move(response), std::move(error)); up->dispatch(_servant, inParams, current); } - catch(const Ice::Exception& ex) + catch (const Ice::Exception&) { - cb->ice_exception(ex); + error(current_exception()); } } @@ -3481,46 +3185,19 @@ IcePy::createServantWrapper(PyObject* servant) ServantWrapperPtr wrapper; PyObject* blobjectType = lookupType("Ice.Blobject"); PyObject* blobjectAsyncType = lookupType("Ice.BlobjectAsync"); - if(PyObject_IsInstance(servant, blobjectType)) - { - return make_shared(servant); - } - else if(PyObject_IsInstance(servant, blobjectAsyncType)) + if(PyObject_IsInstance(servant, blobjectType) || PyObject_IsInstance(servant, blobjectAsyncType)) { return make_shared(servant); } - - return make_shared(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(futureType); - PyObject* future = type->tp_new(type, args.get(), 0); - if(!future) + else { - return 0; + return make_shared(servant); } - type->tp_init(future, args.get(), 0); // Call the constructor - return future; } PyObject* -IcePy::createFuture(const string& operation, PyObject* asyncResult) +IcePy::createFuture(const string& operation, PyObject* asyncInvocationContext) { - if(!asyncResult) // Can be nil for batch invocations. - { - asyncResult = Py_None; - } - PyObject* futureType = lookupType("Ice.InvocationFuture"); assert(futureType); PyObjectHandle args = PyTuple_New(2); @@ -3529,7 +3206,7 @@ IcePy::createFuture(const string& operation, PyObject* asyncResult) return 0; } PyTuple_SET_ITEM(args.get(), 0, createString(operation)); - PyTuple_SET_ITEM(args.get(), 1, incRef(asyncResult)); + PyTuple_SET_ITEM(args.get(), 1, incRef(asyncInvocationContext)); PyTypeObject* type = reinterpret_cast(futureType); PyObject* future = type->tp_new(type, args.get(), 0); if(!future) diff --git a/python/modules/IcePy/Operation.h b/python/modules/IcePy/Operation.h index 57e9741fcc1..f01d52dbc21 100644 --- a/python/modules/IcePy/Operation.h +++ b/python/modules/IcePy/Operation.h @@ -12,53 +12,25 @@ #include #include +#include + namespace IcePy { bool initOperation(PyObject*); -// +extern PyTypeObject AsyncInvocationContextType; + // Builtin operations. -// PyObject* invokeBuiltin(PyObject*, const std::string&, PyObject*); PyObject* invokeBuiltinAsync(PyObject*, const std::string&, PyObject*); -// // Blobject invocations. -// PyObject* iceInvoke(PyObject*, PyObject*); PyObject* iceInvokeAsync(PyObject*, PyObject*); -extern PyTypeObject AsyncResultType; -PyObject* createAsyncResult(const Ice::AsyncResultPtr&, PyObject*, PyObject*, PyObject*); -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 GetConnectionCallbackPtr; - -// // Used as the callback for getConnectionAsync operation. -// -class GetConnectionAsyncCallback : public IceUtil::Shared +class GetConnectionAsyncCallback { public: @@ -78,12 +50,10 @@ class GetConnectionAsyncCallback : public IceUtil::Shared Ice::ConnectionPtr _connection; PyObject* _exception; }; -typedef IceUtil::Handle GetConnectionAsyncCallbackPtr; +using GetConnectionAsyncCallbackPtr = std::shared_ptr; -// // Used as the callback for the various flushBatchRequestAsync operations. -// -class FlushAsyncCallback : public IceUtil::Shared +class FlushAsyncCallback { public: @@ -103,11 +73,9 @@ class FlushAsyncCallback : public IceUtil::Shared bool _sentSynchronously; PyObject* _exception; }; -typedef IceUtil::Handle FlushAsyncCallbackPtr; +using FlushAsyncCallbackPtr = std::shared_ptr; -// // ServantWrapper handles dispatching to a Python servant. -// class ServantWrapper : public Ice::BlobjectArrayAsync { public: @@ -125,7 +93,7 @@ using ServantWrapperPtr = std::shared_ptr; ServantWrapperPtr createServantWrapper(PyObject*); -PyObject* createFuture(); +PyObject* createAsyncInvocationContext(std::function, Ice::CommunicatorPtr); PyObject* createFuture(const std::string&, PyObject*); } diff --git a/python/modules/IcePy/Proxy.cpp b/python/modules/IcePy/Proxy.cpp index 39bffcebe8b..4e87dedf474 100644 --- a/python/modules/IcePy/Proxy.cpp +++ b/python/modules/IcePy/Proxy.cpp @@ -31,7 +31,7 @@ namespace IcePy struct ProxyObject { PyObject_HEAD - Ice::ObjectPrx* proxy; + shared_ptr* proxy; Ice::CommunicatorPtr* communicator; }; @@ -41,7 +41,7 @@ struct ProxyObject // Proxy implementation. // static ProxyObject* -allocateProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) +allocateProxy(const shared_ptr& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) { PyTypeObject* typeObj = reinterpret_cast(type); ProxyObject* p = reinterpret_cast(typeObj->tp_alloc(typeObj, 0)); @@ -60,7 +60,7 @@ allocateProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communica // p->proxy = new Ice::ObjectPrx(proxy->ice_collocationOptimized(false)); //} // - p->proxy = new Ice::ObjectPrx(proxy); + p->proxy = new shared_ptr(proxy); p->communicator = new Ice::CommunicatorPtr(communicator); return p; @@ -102,22 +102,22 @@ proxyCompare(ProxyObject* p1, PyObject* other, int op) switch(op) { case Py_EQ: - result = *p1->proxy == *p2->proxy; + result = Ice::targetEqualTo(*p1->proxy, *p2->proxy); break; case Py_NE: - result = *p1->proxy != *p2->proxy; + result = !Ice::targetEqualTo(*p1->proxy, *p2->proxy); break; case Py_LE: - result = *p1->proxy <= *p2->proxy; + result = Ice::targetLessEqual(*p1->proxy, *p2->proxy); break; case Py_GE: - result = *p1->proxy >= *p2->proxy; + result = Ice::targetGreaterEqual(*p1->proxy, *p2->proxy); break; case Py_LT: - result = *p1->proxy < *p2->proxy; + result = Ice::targetLess(*p1->proxy, *p2->proxy); break; case Py_GT: - result = *p1->proxy > *p2->proxy; + result = Ice::targetGreater(*p1->proxy, *p2->proxy); break; } } @@ -379,7 +379,7 @@ proxyIceIdentity(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_identity(ident); @@ -440,7 +440,7 @@ proxyIceContext(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_context(ctx); @@ -496,7 +496,7 @@ proxyIceFacet(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_facet(facet); @@ -552,7 +552,7 @@ proxyIceAdapterId(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_adapterId(id); @@ -627,7 +627,7 @@ proxyIceEndpoints(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_endpoints(seq); @@ -715,14 +715,14 @@ proxyIceLocatorCacheTimeout(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_locatorCacheTimeout(timeout); } - catch(const IceUtil::IllegalArgumentException& ex) + catch(const invalid_argument& ex) { - PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); return 0; } catch(const Ice::Exception& ex) @@ -748,14 +748,14 @@ proxyIceInvocationTimeout(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_invocationTimeout(timeout); } - catch(const IceUtil::IllegalArgumentException& ex) + catch(const invalid_argument& ex) { - PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); return 0; } catch(const Ice::Exception& ex) @@ -810,7 +810,7 @@ proxyIceConnectionCached(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_connectionCached(n == 1); @@ -844,7 +844,7 @@ proxyIceGetEndpointSelection(ProxyObject* self, PyObject* /*args*/) try { Ice::EndpointSelectionType val = (*self->proxy)->ice_getEndpointSelection(); - if(val == Ice::Random) + if(val == Ice::EndpointSelectionType::Random) { type = rnd.get(); } @@ -884,11 +884,11 @@ proxyIceEndpointSelection(ProxyObject* self, PyObject* args) assert(ord.get()); if(rnd.get() == type) { - val = Ice::Random; + val = Ice::EndpointSelectionType::Random; } else if(ord.get() == type) { - val = Ice::Ordered; + val = Ice::EndpointSelectionType::Ordered; } else { @@ -898,7 +898,7 @@ proxyIceEndpointSelection(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_endpointSelection(val); @@ -955,7 +955,7 @@ proxyIceSecure(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_secure(n == 1); @@ -1014,7 +1014,7 @@ proxyIceEncodingVersion(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_encodingVersion(val); @@ -1071,7 +1071,7 @@ proxyIcePreferSecure(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_preferSecure(n == 1); @@ -1093,7 +1093,7 @@ proxyIceGetRouter(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::RouterPrx router; + shared_ptr router; try { router = (*self->proxy)->ice_getRouter(); @@ -1127,17 +1127,17 @@ proxyIceRouter(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "ice_router", "rtr", proxy, "Ice.RouterPrx")) { return 0; } - Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + shared_ptr router = Ice::uncheckedCast(proxy); assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_router(router); @@ -1159,7 +1159,7 @@ proxyIceGetLocator(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::LocatorPrx locator; + shared_ptr locator; try { locator = (*self->proxy)->ice_getLocator(); @@ -1193,17 +1193,17 @@ proxyIceLocator(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx proxy; + shared_ptr proxy; if(!getProxyArg(p, "ice_locator", "loc", proxy, "Ice.LocatorPrx")) { return 0; } - Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + shared_ptr locator = Ice::uncheckedCast(proxy); assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_locator(locator); @@ -1225,7 +1225,7 @@ proxyIceTwoway(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_twoway(); @@ -1270,7 +1270,7 @@ proxyIceOneway(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_oneway(); @@ -1315,7 +1315,7 @@ proxyIceBatchOneway(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_batchOneway(); @@ -1360,7 +1360,7 @@ proxyIceDatagram(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_datagram(); @@ -1405,7 +1405,7 @@ proxyIceBatchDatagram(ProxyObject* self, PyObject* /*args*/) { assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_batchDatagram(); @@ -1462,7 +1462,7 @@ proxyIceCompress(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_compress(n == 1); @@ -1520,14 +1520,14 @@ proxyIceTimeout(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_timeout(timeout); } - catch(const IceUtil::IllegalArgumentException& ex) + catch(const invalid_argument& ex) { - PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); return 0; } catch(const Ice::Exception& ex) @@ -1610,7 +1610,7 @@ proxyIceCollocationOptimized(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_collocationOptimized(n == 1); @@ -1644,7 +1644,7 @@ proxyIceConnectionId(ProxyObject* self, PyObject* args) assert(self->proxy); - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_connectionId(id); @@ -1678,11 +1678,16 @@ proxyIceFixed(ProxyObject* self, PyObject* args) return 0; } - Ice::ObjectPrx newProxy; + shared_ptr newProxy; try { newProxy = (*self->proxy)->ice_fixed(connection); } + catch(const invalid_argument& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); + return 0; + } catch(const Ice::Exception& ex) { setPythonException(ex); @@ -1754,37 +1759,45 @@ proxyIceGetConnectionAsync(ProxyObject* self, PyObject* /*args*/, PyObject* /*kw 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; - + auto callback = make_shared(*self->communicator, op); + function cancel; try { - result = (*self->proxy)->begin_ice_getConnection(cb); - } - catch(const Ice::Exception& ex) + cancel = (*self->proxy)->ice_getConnectionAsync( + [callback](const Ice::ConnectionPtr& connection) + { + callback->response(connection); + }, + [callback](exception_ptr exptr) + { + try + { + rethrow_exception(exptr); + } + catch (const Ice::Exception& ex) + { + callback->exception(ex); + } + }); + } + catch (const Ice::Exception& ex) { setPythonException(ex); return 0; } - PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator); - PyObjectHandle asyncResultObj = - createAsyncResult(result, reinterpret_cast(self), 0, communicatorObj.get()); - if(!asyncResultObj.get()) + PyObjectHandle asyncInvocationContextObj = createAsyncInvocationContext(cancel, *self->communicator); + if (!asyncInvocationContextObj.get()) { return 0; } - PyObjectHandle future = createFuture(op, asyncResultObj.get()); - if(!future.get()) + PyObjectHandle future = createFuture(op, asyncInvocationContextObj.get()); + if (!future.get()) { return 0; } - d->setFuture(future.get()); + callback->setFuture(future.get()); return future.release(); } @@ -1850,15 +1863,30 @@ proxyIceFlushBatchRequestsAsync(ProxyObject* self, PyObject* /*args*/, PyObject* 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; - + auto callback = make_shared(op); + function cancel; try { - result = (*self->proxy)->begin_ice_flushBatchRequests(cb); + cancel = (*self->proxy)->ice_flushBatchRequestsAsync( + [callback](exception_ptr exptr) + { + try + { + rethrow_exception(exptr); + } + catch (const Ice::Exception& ex) + { + callback->exception(ex); + } + catch (...) + { + assert(false); + } + }, + [callback](bool sentSynchronously) + { + callback->sent(sentSynchronously); + }); } catch(const Ice::Exception& ex) { @@ -1866,20 +1894,18 @@ proxyIceFlushBatchRequestsAsync(ProxyObject* self, PyObject* /*args*/, PyObject* return 0; } - PyObjectHandle communicatorObj = getCommunicatorWrapper(*self->communicator); - PyObjectHandle asyncResultObj = - createAsyncResult(result, reinterpret_cast(self), 0, communicatorObj.get()); - if(!asyncResultObj.get()) + PyObjectHandle asyncInvocationContextObj = createAsyncInvocationContext(std::move(cancel), *self->communicator); + if(!asyncInvocationContextObj.get()) { return 0; } - PyObjectHandle future = createFuture(op, asyncResultObj.get()); + PyObjectHandle future = createFuture(op, asyncInvocationContextObj.get()); if(!future.get()) { return 0; } - d->setFuture(future.get()); + callback->setFuture(future.get()); return future.release(); } @@ -1904,7 +1930,7 @@ proxyIceInvokeAsync(ProxyObject* self, PyObject* args, PyObject* /*kwds*/) static PyObject* checkedCastImpl(ProxyObject* p, const string& id, PyObject* facet, PyObject* ctx, PyObject* type) { - Ice::ObjectPrx target; + shared_ptr target; if(!facet || facet == Py_None) { target = *p->proxy; @@ -1918,7 +1944,7 @@ checkedCastImpl(ProxyObject* p, const string& id, PyObject* facet, PyObject* ctx bool b = false; try { - Ice::Context c = ::Ice::noExplicitContext; + Ice::Context c; if(ctx && ctx != Py_None) { if(!dictionaryToContext(ctx, c)) @@ -1928,7 +1954,7 @@ checkedCastImpl(ProxyObject* p, const string& id, PyObject* facet, PyObject* ctx } AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. - b = target->ice_isA(id, c); + b = target->ice_isA(id, (ctx == 0 || ctx == Py_None) ? Ice::noExplicitContext : c); } catch(const Ice::FacetNotExistException&) { @@ -2398,7 +2424,7 @@ IcePy::initProxy(PyObject* module) } PyObject* -IcePy::createProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) +IcePy::createProxy(const shared_ptr& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) { assert(proxy); @@ -2417,7 +2443,7 @@ IcePy::checkProxy(PyObject* p) return PyObject_IsInstance(p, reinterpret_cast(type)) == 1; } -Ice::ObjectPrx +shared_ptr IcePy::getProxy(PyObject* p) { assert(checkProxy(p)); @@ -2426,7 +2452,7 @@ IcePy::getProxy(PyObject* p) } bool -IcePy::getProxyArg(PyObject* p, const string& func, const string& arg, Ice::ObjectPrx& proxy, const string& type) +IcePy::getProxyArg(PyObject* p, const string& func, const string& arg, shared_ptr& proxy, const string& type) { bool result = true; diff --git a/python/modules/IcePy/Proxy.h b/python/modules/IcePy/Proxy.h index 5b11bebd888..c24ff2ac34c 100644 --- a/python/modules/IcePy/Proxy.h +++ b/python/modules/IcePy/Proxy.h @@ -16,7 +16,7 @@ extern PyTypeObject ProxyType; bool initProxy(PyObject*); -PyObject* createProxy(const Ice::ObjectPrx&, const Ice::CommunicatorPtr&, PyObject* = 0); +PyObject* createProxy(const std::shared_ptr&, const Ice::CommunicatorPtr&, PyObject* = 0); // // Verifies that the given Python object is a proxy. A value of None is not considered legal here. @@ -27,7 +27,7 @@ bool checkProxy(PyObject*); // Extracts a proxy from the given Python object. The Python object *must* be a proxy. // None is not legal here. // -Ice::ObjectPrx getProxy(PyObject*); +std::shared_ptr getProxy(PyObject*); // // Extracts a proxy argument from the given Python object. None is accepted here. If the Python @@ -35,7 +35,7 @@ Ice::ObjectPrx getProxy(PyObject*); // false. The optional trailing string provides the Python class name of a derived Slice // interface that the caller requires. // -bool getProxyArg(PyObject*, const std::string&, const std::string&, Ice::ObjectPrx&, +bool getProxyArg(PyObject*, const std::string&, const std::string&, std::shared_ptr&, const std::string& = std::string()); // diff --git a/python/modules/IcePy/Thread.cpp b/python/modules/IcePy/Thread.cpp index ba1a7f34564..a6a1f465758 100644 --- a/python/modules/IcePy/Thread.cpp +++ b/python/modules/IcePy/Thread.cpp @@ -27,31 +27,20 @@ IcePy::AdoptThread::~AdoptThread() PyGILState_Release(_state); } -IcePy::ThreadHook::ThreadHook(PyObject* threadNotification, PyObject* threadStart, PyObject* threadStop) : - _threadNotification(threadNotification), _threadStart(threadStart), _threadStop(threadStop) +IcePy::ThreadHook::ThreadHook(PyObject* threadStart, PyObject* threadStop) : + _threadStart(threadStart), + _threadStop(threadStop) { - if(threadNotification) - { - if(!PyObject_HasAttrString(threadNotification, STRCAST("start")) || - !PyObject_HasAttrString(threadNotification, STRCAST("stop"))) - { - throw Ice::InitializationException(__FILE__, __LINE__, - "threadNotification object must have 'start' and 'stop' methods"); - } - - } - - if(threadStart && !PyCallable_Check(threadStart)) + if (threadStart && !PyCallable_Check(threadStart)) { throw Ice::InitializationException(__FILE__, __LINE__, "threadStart must be a callable"); } - if(threadStop && !PyCallable_Check(threadStop)) + if (threadStop && !PyCallable_Check(threadStop)) { throw Ice::InitializationException(__FILE__, __LINE__, "threadStop must be a callable"); } - Py_XINCREF(threadNotification); Py_XINCREF(threadStart); Py_XINCREF(threadStop); } @@ -60,20 +49,11 @@ void IcePy::ThreadHook::start() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. - - if(_threadNotification.get()) - { - PyObjectHandle tmp = PyObject_CallMethod(_threadNotification.get(), STRCAST("start"), 0); - if(!tmp.get()) - { - throwPythonException(); - } - } - if(_threadStart.get()) + if (_threadStart.get()) { PyObjectHandle args = PyTuple_New(0); PyObjectHandle tmp = PyObject_Call(_threadStart.get(), args.get(), 0); - if(!tmp.get()) + if (!tmp.get()) { throwPythonException(); } @@ -84,20 +64,11 @@ void IcePy::ThreadHook::stop() { AdoptThread adoptThread; // Ensure the current thread is able to call into Python. - - if(_threadNotification.get()) - { - PyObjectHandle tmp = PyObject_CallMethod(_threadNotification.get(), STRCAST("stop"), 0); - if(!tmp.get()) - { - throwPythonException(); - } - } - if(_threadStop.get()) + if (_threadStop.get()) { PyObjectHandle args = PyTuple_New(0); PyObjectHandle tmp = PyObject_Call(_threadStop.get(), args.get(), 0); - if(!tmp.get()) + if (!tmp.get()) { throwPythonException(); } diff --git a/python/modules/IcePy/Thread.h b/python/modules/IcePy/Thread.h index 423c4054465..d4e7d77aae7 100644 --- a/python/modules/IcePy/Thread.h +++ b/python/modules/IcePy/Thread.h @@ -43,26 +43,22 @@ class AdoptThread PyGILState_STATE _state; }; -// -// ThreadHook ensures that every Ice thread is ready to invoke the Python API. -// It also acts as a wrapper for an optional ThreadNotification object. -// -class ThreadHook : public Ice::ThreadNotification +// ThreadHook ensures that every Ice thread is ready to invoke the Python API. It also acts as a wrapper thread +// notification callbacks. +class ThreadHook final { public: - ThreadHook(PyObject*, PyObject*, PyObject*); + ThreadHook(PyObject*, PyObject*); - virtual void start(); - virtual void stop(); + void start(); + void stop(); private: - PyObjectHandle _threadNotification; PyObjectHandle _threadStart; PyObjectHandle _threadStop; }; -typedef IceUtil::Handle ThreadHookPtr; } diff --git a/python/modules/IcePy/Types.cpp b/python/modules/IcePy/Types.cpp index 8886fd4f554..6d9f7b8eec4 100644 --- a/python/modules/IcePy/Types.cpp +++ b/python/modules/IcePy/Types.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -190,73 +189,6 @@ unsetRepr(PyObject* /*v*/) return PyBytes_FromString("Unset"); } -#ifdef WIN32 -extern "C" -#endif -static BufferObject* -bufferNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) -{ - BufferObject* self = reinterpret_cast(type->tp_alloc(type, 0)); - if(!self) - { - return 0; - } - self->buffer = 0; - return self; -} - -#ifdef WIN32 -extern "C" -#endif -static void -bufferDealloc(BufferObject* self) -{ - if(self->buffer) - { - delete self->buffer; - } - Py_TYPE(self)->tp_free(reinterpret_cast(self)); -} - -// -// See https://docs.python.org/3/c-api/typeobj.html#buffer-object-structures -// -#ifdef WIN32 -extern "C" -#endif -static int -bufferGetBuffer(BufferObject* self, Py_buffer* view, int flags) -{ - if(!self->buffer) - { - PyErr_SetString(PyExc_BufferError,"no data available"); - view->obj = 0; - return -1; - } - - if(flags & PyBUF_WRITABLE) - { - PyErr_SetString(PyExc_BufferError,"buffer object is read only"); - view->obj = 0; - return -1; - } - - BufferPtr buffer = *self->buffer; - if(PyBuffer_FillInfo(view, reinterpret_cast(self), const_cast(buffer->data()), - buffer->size(), 1, flags) != 0) - { - PyErr_SetString(PyExc_BufferError, "fill buffer info failed"); - return -1; - } - view->obj = reinterpret_cast(self); - // - // Don't nee to increase the view->obj ref count here - // PyBuffer_FillInfo already increases it. - // - //Py_INCREF(view->obj); - return 0; -} - // // addClassInfo() // @@ -864,23 +796,23 @@ IcePy::PrimitiveInfo::optionalFormat() const { case KindBool: case KindByte: - return Ice::OptionalFormatF1; + return Ice::OptionalFormat::F1; case KindShort: - return Ice::OptionalFormatF2; + return Ice::OptionalFormat::F2; case KindInt: - return Ice::OptionalFormatF4; + return Ice::OptionalFormat::F4; case KindLong: - return Ice::OptionalFormatF8; + return Ice::OptionalFormat::F8; case KindFloat: - return Ice::OptionalFormatF4; + return Ice::OptionalFormat::F4; case KindDouble: - return Ice::OptionalFormatF8; + return Ice::OptionalFormat::F8; case KindString: - return Ice::OptionalFormatVSize; + return Ice::OptionalFormat::VSize; } assert(false); - return Ice::OptionalFormatF1; + return Ice::OptionalFormat::F1; } void @@ -1115,7 +1047,7 @@ IcePy::EnumInfo::wireSize() const Ice::OptionalFormat IcePy::EnumInfo::optionalFormat() const { - return Ice::OptionalFormatSize; + return Ice::OptionalFormat::Size; } void @@ -1254,7 +1186,7 @@ convertDataMembers(PyObject* members, DataMemberList& reqMembers, DataMemberList assert(PyLong_Check(tag)); } - DataMemberPtr member = new DataMember; + DataMemberPtr member = make_shared(); member->name = getString(name); #ifndef NDEBUG bool b = @@ -1351,7 +1283,7 @@ IcePy::StructInfo::wireSize() const Ice::OptionalFormat IcePy::StructInfo::optionalFormat() const { - return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; + return _variableLength ? Ice::OptionalFormat::FSize : Ice::OptionalFormat::VSize; } bool @@ -1521,7 +1453,7 @@ IcePy::SequenceInfo::SequenceInfo(const string& ident, PyObject* m, PyObject* t) tupleToStringSeq(m, metaData); assert(b); - const_cast(mapping) = new SequenceMapping(metaData); + const_cast(mapping) = make_shared(metaData); mapping->init(metaData); const_cast(elementType) = getType(t); } @@ -1553,7 +1485,7 @@ IcePy::SequenceInfo::wireSize() const Ice::OptionalFormat IcePy::SequenceInfo::optionalFormat() const { - return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; + return elementType->variableLength() ? Ice::OptionalFormat::FSize : Ice::OptionalFormat::VSize; } bool @@ -1566,7 +1498,7 @@ void IcePy::SequenceInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectMap, bool optional, const Ice::StringSeq* /*metaData*/) { - PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + auto pi = dynamic_pointer_cast(elementType); Ice::OutputStream::size_type sizePos = 0; if(optional) @@ -1692,7 +1624,7 @@ IcePy::SequenceInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& } else { - sm = new SequenceMapping(type); + sm = make_shared(type); try { sm->init(*metaData); @@ -1708,7 +1640,7 @@ IcePy::SequenceInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& sm = mapping; } - PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + auto pi = dynamic_pointer_cast(elementType); if(pi) { unmarshalPrimitiveSequence(pi, is, cb, target, closure, sm); @@ -2161,28 +2093,15 @@ IcePy::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, PyObje } PyObject* -IcePy::SequenceInfo::createSequenceFromMemory(const SequenceMappingPtr& sm, - const char* buffer, - Py_ssize_t size, - BuiltinType type, - bool adopt) +IcePy::SequenceInfo::createSequenceFromMemory( + const SequenceMappingPtr& sm, + const char* buffer, + Py_ssize_t size, + BuiltinType type) { PyObjectHandle memoryview; - if(adopt && size > 0) - { - PyObjectHandle bufferObject = createBuffer(new Buffer(buffer, size, type)); - if(!bufferObject.get()) - { - assert(PyErr_Occurred()); - throw AbortMarshaling(); - } - memoryview = PyMemoryView_FromObject(bufferObject.get()); - } - else - { - char* buf = const_cast(size == 0 ? emptySeq : buffer); - memoryview = PyMemoryView_FromMemory(buf, size, PyBUF_READ); - } + char* buf = const_cast(size == 0 ? emptySeq : buffer); + memoryview = PyMemoryView_FromMemory(buf, size, PyBUF_READ); if(!memoryview.get()) { @@ -2202,11 +2121,7 @@ IcePy::SequenceInfo::createSequenceFromMemory(const SequenceMappingPtr& sm, PyObjectHandle args = PyTuple_New(3); PyTuple_SET_ITEM(args.get(), 0, incRef(memoryview.get())); PyTuple_SET_ITEM(args.get(), 1, incRef(builtinType.get())); - // - // If the Buffer object adopts the data we set the copy factory argument to false - // to avoid a second copy in the factory. - // - PyTuple_SET_ITEM(args.get(), 2, adopt ? incFalse() : incTrue()); + PyTuple_SET_ITEM(args.get(), 2, incTrue()); PyObjectHandle result = PyObject_Call(sm->factory, args.get(), 0); if(!result.get()) @@ -2234,14 +2149,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindBool: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz, BuiltinTypeBool, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz, BuiltinTypeBool); } else { @@ -2266,7 +2179,7 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: int sz = static_cast(p.second - p.first); if(sm->factory) { - result = createSequenceFromMemory(sm, reinterpret_cast(p.first), sz, BuiltinTypeByte, false); + result = createSequenceFromMemory(sm, reinterpret_cast(p.first), sz, BuiltinTypeByte); } else if(sm->type == SequenceMapping::SEQ_DEFAULT) { @@ -2302,14 +2215,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindShort: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz * 2, BuiltinTypeShort, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz * 2, BuiltinTypeShort); } else { @@ -2336,14 +2247,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindInt: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeInt, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeInt); } else { @@ -2369,14 +2278,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindLong: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeLong, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeLong); } else { @@ -2403,14 +2310,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindFloat: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeFloat, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeFloat); } else { @@ -2437,14 +2342,12 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice: case PrimitiveInfo::KindDouble: { pair p; - IceUtil::ScopedArray arr; - is->read(p, arr); + is->read(p); int sz = static_cast(p.second - p.first); if(sm->factory) { - bool adopt = arr.get() != 0; - const char* data = reinterpret_cast(arr.get() != 0 ? arr.release() : p.first); - result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeDouble, adopt); + const char* data = reinterpret_cast(p.first); + result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeDouble); } else { @@ -2651,78 +2554,6 @@ IcePy::SequenceInfo::SequenceMapping::setItem(PyObject* cont, int i, PyObject* v } } -// -// Buffer implementation -// -IcePy::Buffer::Buffer(const char* data, Py_ssize_t size, SequenceInfo::BuiltinType type) : - _data(data), - _size(size), - _type(type) -{ -} - -IcePy::Buffer::~Buffer() -{ - assert(_data != 0); - switch(_type) - { - case SequenceInfo::BuiltinTypeBool: - { - delete [] reinterpret_cast(_data); - break; - } - case SequenceInfo::BuiltinTypeShort: - { - delete [] reinterpret_cast(_data); - break; - } - case SequenceInfo::BuiltinTypeInt: - { - delete [] reinterpret_cast(_data); - break; - } - case SequenceInfo::BuiltinTypeLong: - { - delete [] reinterpret_cast(_data); - break; - } - case SequenceInfo::BuiltinTypeFloat: - { - delete [] reinterpret_cast(_data); - break; - } - case SequenceInfo::BuiltinTypeDouble: - { - delete [] reinterpret_cast(_data); - break; - } - default: - { - assert(false); - break; - } - } - _data = 0; -} - -const char* -IcePy::Buffer::data() const -{ - return _data; -} - -Py_ssize_t -IcePy::Buffer::size() const -{ - return _size; -} - -SequenceInfo::BuiltinType -IcePy::Buffer::type() -{ - return _type; -} - // // CustomInfo implementation. // @@ -2759,7 +2590,7 @@ IcePy::CustomInfo::wireSize() const Ice::OptionalFormat IcePy::CustomInfo::optionalFormat() const { - return Ice::OptionalFormatVSize; + return Ice::OptionalFormat::VSize; } bool @@ -2918,7 +2749,7 @@ IcePy::DictionaryInfo::wireSize() const Ice::OptionalFormat IcePy::DictionaryInfo::optionalFormat() const { - return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; + return _variableLength ? Ice::OptionalFormat::FSize : Ice::OptionalFormat::VSize; } bool @@ -3010,7 +2841,7 @@ IcePy::DictionaryInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPt throw AbortMarshaling(); } - KeyCallbackPtr keyCB = new KeyCallback; + KeyCallbackPtr keyCB = make_shared(); keyCB->key = 0; Ice::Int sz = is->readSize(); @@ -3039,7 +2870,7 @@ IcePy::DictionaryInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPt // so we pass it the key. // void* cl = reinterpret_cast(keyCB->key.get()); - valueType->unmarshal(is, this, p.get(), cl, false); + valueType->unmarshal(is, shared_from_this(), p.get(), cl, false); } cb->unmarshaled(p.get(), target, closure); @@ -3115,7 +2946,12 @@ IcePy::DictionaryInfo::destroy() IcePy::ClassInfo::ClassInfo(const string& ident) : id(ident), defined(false) { - typeObj = createType(this); +} + +void +IcePy::ClassInfo::init() +{ + typeObj = createType(shared_from_this()); } void @@ -3126,7 +2962,7 @@ IcePy::ClassInfo::define(PyObject* t, PyObject* b, PyObject* i) if(b != Py_None) { - const_cast(base) = ClassInfoPtr::dynamicCast(getType(b)); + const_cast(base) = dynamic_pointer_cast(getType(b)); assert(base); } @@ -3135,7 +2971,7 @@ IcePy::ClassInfo::define(PyObject* t, PyObject* b, PyObject* i) for(n = 0; n < sz; ++n) { PyObject* o = PyTuple_GET_ITEM(i, n); - ClassInfoPtr iface = ClassInfoPtr::dynamicCast(getType(o)); + auto iface = dynamic_pointer_cast(getType(o)); assert(iface); const_cast(interfaces).push_back(iface); } @@ -3174,7 +3010,7 @@ IcePy::ClassInfo::wireSize() const Ice::OptionalFormat IcePy::ClassInfo::optionalFormat() const { - return Ice::OptionalFormatClass; + return Ice::OptionalFormat::Class; } bool @@ -3230,11 +3066,11 @@ IcePy::ClassInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObje // that does not derive from a user-defined type. // assert(id == "::Ice::LocalObject"); - info = this; + info = shared_from_this(); } else { - info = ClassInfoPtr::dynamicCast(getType(iceType.get())); + info = dynamic_pointer_cast(getType(iceType.get())); assert(info); } out << "object #" << history->index << " (" << info->id << ')'; @@ -3257,7 +3093,12 @@ IcePy::ClassInfo::destroy() IcePy::ValueInfo::ValueInfo(const string& ident) : id(ident), compactId(-1), preserve(false), interface(false), defined(false) { - typeObj = createType(this); +} + +void +IcePy::ValueInfo::init() +{ + typeObj = createType(shared_from_this()); } void @@ -3272,7 +3113,7 @@ IcePy::ValueInfo::define(PyObject* t, int compact, bool pres, bool intf, PyObjec if(b != Py_None) { - const_cast(base) = ValueInfoPtr::dynamicCast(getType(b)); + const_cast(base) = dynamic_pointer_cast(getType(b)); assert(base); } @@ -3310,7 +3151,7 @@ IcePy::ValueInfo::wireSize() const Ice::OptionalFormat IcePy::ValueInfo::optionalFormat() const { - return Ice::OptionalFormatClass; + return Ice::OptionalFormat::Class; } bool @@ -3353,7 +3194,7 @@ IcePy::ValueInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* objectM ObjectMap::iterator q = objectMap->find(p); if(q == objectMap->end()) { - writer = make_shared(p, objectMap, this); + writer = make_shared(p, objectMap, shared_from_this()); objectMap->insert(ObjectMap::value_type(p, writer)); } else @@ -3395,7 +3236,7 @@ IcePy::ValueInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb // attached to the stream keeps a reference to the callback object to ensure it lives // long enough. // - ReadValueCallbackPtr rocb = new ReadValueCallback(this, cb, target, closure); + ReadValueCallbackPtr rocb = make_shared(shared_from_this(), cb, target, closure); StreamUtil* util = reinterpret_cast(is->getClosure()); assert(util); util->add(rocb); @@ -3433,11 +3274,11 @@ IcePy::ValueInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObje // that does not derive from a user-defined type. // assert(id == "::Ice::LocalObject"); - info = this; + info = shared_from_this(); } else { - info = ValueInfoPtr::dynamicCast(getType(iceType.get())); + info = dynamic_pointer_cast(getType(iceType.get())); assert(info); } out << "object #" << history->index << " (" << info->id << ')'; @@ -3508,7 +3349,12 @@ IcePy::ValueInfo::printMembers(PyObject* value, IceUtilInternal::Output& out, Pr IcePy::ProxyInfo::ProxyInfo(const string& ident) : id(ident) { - typeObj = createType(this); // Borrowed reference. +} + +void +IcePy::ProxyInfo::init() +{ + typeObj = createType(shared_from_this()); } void @@ -3544,7 +3390,7 @@ IcePy::ProxyInfo::wireSize() const Ice::OptionalFormat IcePy::ProxyInfo::optionalFormat() const { - return Ice::OptionalFormatFSize; + return Ice::OptionalFormat::FSize; } void @@ -3558,7 +3404,8 @@ IcePy::ProxyInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap*, bool o if(p == Py_None) { - os->write(Ice::ObjectPrx()); + shared_ptr proxy; + os->write(proxy); } else if(checkProxy(p)) { @@ -3584,7 +3431,7 @@ IcePy::ProxyInfo::unmarshal(Ice::InputStream* is, const UnmarshalCallbackPtr& cb is->skip(4); } - Ice::ObjectPrx proxy; + shared_ptr proxy; is->read(proxy); if(!proxy) @@ -3643,7 +3490,7 @@ IcePy::ValueWriter::ValueWriter(PyObject* object, ObjectMap* objectMap, const Va assert(PyErr_Occurred()); throw AbortMarshaling(); } - _info = ValueInfoPtr::dynamicCast(getType(iceType.get())); + _info = dynamic_pointer_cast(getType(iceType.get())); assert(_info); } } @@ -3851,7 +3698,7 @@ IcePy::ValueReader::_iceRead(Ice::InputStream* is) { StreamUtil* util = reinterpret_cast(is->getClosure()); assert(util); - util->add(ValueReaderPtr(shared_from_this())); + util->add(shared_from_this()); // // Define the "unknownTypeId" member for an instance of UnknownSlicedObject. @@ -3956,7 +3803,7 @@ IcePy::ExceptionInfo::marshal(PyObject* p, Ice::OutputStream* os, ObjectMap* obj os->startException(slicedData); - ExceptionInfoPtr info = this; + ExceptionInfoPtr info = shared_from_this(); while(info) { os->startSlice(info->id, -1, !info->base); @@ -4024,7 +3871,7 @@ IcePy::ExceptionInfo::unmarshal(Ice::InputStream* is) throw AbortMarshaling(); } - ExceptionInfoPtr info = this; + ExceptionInfoPtr info = shared_from_this(); while(info) { is->startSlice(); @@ -4135,7 +3982,7 @@ IcePy::ExceptionWriter::ExceptionWriter(const PyObjectHandle& ex, const Exceptio { PyObjectHandle iceType = getAttr(ex.get(), "_ice_type", false); assert(iceType.get()); - _info = ExceptionInfoPtr::dynamicCast(getException(iceType.get())); + _info = dynamic_pointer_cast(getException(iceType.get())); assert(_info); } } @@ -4153,13 +4000,11 @@ IcePy::ExceptionWriter::ice_id() const return _info->id; } -#ifndef ICE_CPP11_MAPPING Ice::UserException* -IcePy::ExceptionWriter::ice_clone() const +IcePy::ExceptionWriter::ice_cloneImpl() const { return new ExceptionWriter(*this); } -#endif void IcePy::ExceptionWriter::ice_throw() const @@ -4207,14 +4052,12 @@ IcePy::ExceptionReader::ice_id() const return _info->id; } -#ifndef ICE_CPP11_MAPPING Ice::UserException* -IcePy::ExceptionReader::ice_clone() const +IcePy::ExceptionReader::ice_cloneImpl() const { assert(false); return 0; } -#endif void IcePy::ExceptionReader::ice_throw() const @@ -4262,7 +4105,7 @@ IcePy::ExceptionReader::getSlicedData() const // IdResolver // string -IcePy::IdResolver::resolve(Ice::Int id) const +IcePy::resolveCompactId(Ice::Int id) { CompactIdMap::iterator p = _compactIdMap.find(id); if(p != _compactIdMap.end()) @@ -4283,7 +4126,7 @@ IcePy::lookupClassInfo(const string& id) { return p->second; } - return 0; + return nullptr; } // @@ -4488,59 +4331,6 @@ PyObject UnsetValue = PyObject* Unset = &UnsetValue; -static PyBufferProcs BufferProcs = -{ - (getbufferproc) bufferGetBuffer, - 0 -}; - -PyTypeObject BufferType = -{ - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(&PyType_Type, 0) - STRCAST("IcePy.BufferType"), /* tp_name */ - sizeof(BufferObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - reinterpret_cast(bufferDealloc), /* 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 */ - &BufferProcs, /* 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 */ - 0, /* 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(bufferNew), /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ -}; - } bool @@ -4566,17 +4356,7 @@ IcePy::initTypes(PyObject* module) return false; } - if(PyType_Ready(&BufferType) < 0) - { - return false; - } - PyTypeObject* bufferType = &BufferType; // Necessary to prevent GCC's strict-alias warnings. - if(PyModule_AddObject(module, STRCAST("Buffer"), reinterpret_cast(bufferType)) < 0) - { - return false; - } - - PrimitiveInfoPtr boolType = new PrimitiveInfo(PrimitiveInfo::KindBool); + PrimitiveInfoPtr boolType = make_shared(PrimitiveInfo::KindBool); PyObjectHandle boolTypeObj = createType(boolType); if(PyModule_AddObject(module, STRCAST("_t_bool"), boolTypeObj.get()) < 0) { @@ -4584,7 +4364,7 @@ IcePy::initTypes(PyObject* module) } boolTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr byteType = new PrimitiveInfo(PrimitiveInfo::KindByte); + PrimitiveInfoPtr byteType = make_shared(PrimitiveInfo::KindByte); PyObjectHandle byteTypeObj = createType(byteType); if(PyModule_AddObject(module, STRCAST("_t_byte"), byteTypeObj.get()) < 0) { @@ -4592,7 +4372,7 @@ IcePy::initTypes(PyObject* module) } byteTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr shortType = new PrimitiveInfo(PrimitiveInfo::KindShort); + PrimitiveInfoPtr shortType = make_shared(PrimitiveInfo::KindShort); PyObjectHandle shortTypeObj = createType(shortType); if(PyModule_AddObject(module, STRCAST("_t_short"), shortTypeObj.get()) < 0) { @@ -4600,7 +4380,7 @@ IcePy::initTypes(PyObject* module) } shortTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr intType = new PrimitiveInfo(PrimitiveInfo::KindInt); + PrimitiveInfoPtr intType = make_shared(PrimitiveInfo::KindInt); PyObjectHandle intTypeObj = createType(intType); if(PyModule_AddObject(module, STRCAST("_t_int"), intTypeObj.get()) < 0) { @@ -4608,7 +4388,7 @@ IcePy::initTypes(PyObject* module) } intTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr longType = new PrimitiveInfo(PrimitiveInfo::KindLong); + PrimitiveInfoPtr longType = make_shared(PrimitiveInfo::KindLong); PyObjectHandle longTypeObj = createType(longType); if(PyModule_AddObject(module, STRCAST("_t_long"), longTypeObj.get()) < 0) { @@ -4616,7 +4396,7 @@ IcePy::initTypes(PyObject* module) } longTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr floatType = new PrimitiveInfo(PrimitiveInfo::KindFloat); + PrimitiveInfoPtr floatType = make_shared(PrimitiveInfo::KindFloat); PyObjectHandle floatTypeObj = createType(floatType); if(PyModule_AddObject(module, STRCAST("_t_float"), floatTypeObj.get()) < 0) { @@ -4624,7 +4404,7 @@ IcePy::initTypes(PyObject* module) } floatTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr doubleType = new PrimitiveInfo(PrimitiveInfo::KindDouble); + PrimitiveInfoPtr doubleType = make_shared(PrimitiveInfo::KindDouble); PyObjectHandle doubleTypeObj = createType(doubleType); if(PyModule_AddObject(module, STRCAST("_t_double"), doubleTypeObj.get()) < 0) { @@ -4632,7 +4412,7 @@ IcePy::initTypes(PyObject* module) } doubleTypeObj.release(); // PyModule_AddObject steals a reference. - PrimitiveInfoPtr stringType = new PrimitiveInfo(PrimitiveInfo::KindString); + PrimitiveInfoPtr stringType = make_shared(PrimitiveInfo::KindString); PyObjectHandle stringTypeObj = createType(stringType); if(PyModule_AddObject(module, STRCAST("_t_string"), stringTypeObj.get()) < 0) { @@ -4687,17 +4467,6 @@ IcePy::createException(const ExceptionInfoPtr& info) return reinterpret_cast(obj); } -PyObject* -IcePy::createBuffer(const BufferPtr& buffer) -{ - BufferObject* obj = bufferNew(&BufferType, 0, 0); - if(obj) - { - obj->buffer = new BufferPtr(buffer); - } - return reinterpret_cast(obj); -} - extern "C" PyObject* IcePy_defineEnum(PyObject*, PyObject* args) @@ -4713,7 +4482,7 @@ IcePy_defineEnum(PyObject*, PyObject* args) assert(PyTuple_Check(meta)); - EnumInfoPtr info = new EnumInfo(id, type, enumerators); + EnumInfoPtr info = make_shared(id, type, enumerators); return createType(info); } @@ -4735,7 +4504,7 @@ IcePy_defineStruct(PyObject*, PyObject* args) assert(PyTuple_Check(meta)); assert(PyTuple_Check(members)); - StructInfoPtr info = new StructInfo(id, type, members); + StructInfoPtr info = make_shared(id, type, members); return createType(info); } @@ -4754,7 +4523,7 @@ IcePy_defineSequence(PyObject*, PyObject* args) try { - SequenceInfoPtr info = new SequenceInfo(id, meta, elementType); + SequenceInfoPtr info = make_shared(id, meta, elementType); return createType(info); } catch(const InvalidSequenceFactoryException&) @@ -4775,7 +4544,7 @@ IcePy_defineCustom(PyObject*, PyObject* args) return 0; } - CustomInfoPtr info = new CustomInfo(id, type); + CustomInfoPtr info = make_shared(id, type); return createType(info); } @@ -4795,7 +4564,7 @@ IcePy_defineDictionary(PyObject*, PyObject* args) assert(PyTuple_Check(meta)); - DictionaryInfoPtr info = new DictionaryInfo(id, keyType, valueType); + DictionaryInfoPtr info = make_shared(id, keyType, valueType); return createType(info); } @@ -4816,7 +4585,8 @@ IcePy_declareProxy(PyObject*, PyObject* args) ProxyInfoPtr info = lookupProxyInfo(proxyId); if(!info) { - info = new ProxyInfo(proxyId); + info = make_shared(proxyId); + info->init(); addProxyInfo(proxyId, info); return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. } @@ -4846,7 +4616,8 @@ IcePy_defineProxy(PyObject*, PyObject* args) ProxyInfoPtr info = lookupProxyInfo(proxyId); if(!info) { - info = new ProxyInfo(proxyId); + info = make_shared(proxyId); + info->init(); addProxyInfo(proxyId, info); info->define(type); return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. @@ -4870,9 +4641,10 @@ IcePy_declareClass(PyObject*, PyObject* args) } ClassInfoPtr info = lookupClassInfo(id); - if(!info) + if (!info) { - info = new ClassInfo(id); + info = make_shared(id); + info->init(); addClassInfo(id, info); return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. } @@ -4907,7 +4679,8 @@ IcePy_defineClass(PyObject*, PyObject* args) ClassInfoPtr info = lookupClassInfo(id); if(!info || info->defined) { - info = new ClassInfo(id); + info = make_shared(id); + info->init(); addClassInfo(id, info); info->define(type, base, interfaces); return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. @@ -4933,7 +4706,8 @@ IcePy_declareValue(PyObject*, PyObject* args) ValueInfoPtr info = lookupValueInfo(id); if(!info) { - info = new ValueInfo(id); + info = make_shared(id); + info->init(); addValueInfo(id, info); return info->typeObj; // Delegate ownership to the global "_t_XXX" variable. } @@ -4974,7 +4748,8 @@ IcePy_defineValue(PyObject*, PyObject* args) ValueInfoPtr info = lookupValueInfo(id); if(!info || info->defined) { - info = new ValueInfo(id); + info = make_shared(id); + info->init(); addValueInfo(id, info); r = info->typeObj; // Delegate ownership to the global "_t_XXX" variable. } @@ -5018,14 +4793,14 @@ IcePy_defineException(PyObject*, PyObject* args) assert(PyTuple_Check(meta)); assert(PyTuple_Check(members)); - ExceptionInfoPtr info = new ExceptionInfo; + ExceptionInfoPtr info = make_shared(); info->id = id; info->preserve = preserve ? true : false; if(base != Py_None) { - info->base = ExceptionInfoPtr::dynamicCast(getException(base)); + info->base = dynamic_pointer_cast(getException(base)); assert(info->base); } diff --git a/python/modules/IcePy/Types.h b/python/modules/IcePy/Types.h index 6613685e9ad..58db46e8b8b 100644 --- a/python/modules/IcePy/Types.h +++ b/python/modules/IcePy/Types.h @@ -14,24 +14,25 @@ #include #include +#include #include namespace IcePy { class Buffer; -typedef IceUtil::Handle BufferPtr; +using BufferPtr = std::shared_ptr; class ExceptionInfo; -typedef IceUtil::Handle ExceptionInfoPtr; -typedef std::vector ExceptionInfoList; +using ExceptionInfoPtr = std::shared_ptr; +using ExceptionInfoList = std::vector; class ClassInfo; -typedef IceUtil::Handle ClassInfoPtr; -typedef std::vector ClassInfoList; +using ClassInfoPtr = std::shared_ptr; +using ClassInfoList = std::vector; class ValueInfo; -typedef IceUtil::Handle ValueInfoPtr; +using ValueInfoPtr = std::shared_ptr; // // This class is raised as an exception when object marshaling needs to be aborted. @@ -40,7 +41,7 @@ class AbortMarshaling { }; -typedef std::map> ObjectMap; +using ObjectMap = std::map>; class ValueReader; using ValueReaderPtr = std::shared_ptr; @@ -53,7 +54,7 @@ using ValueReaderPtr = std::shared_ptr; // returns. For class instances, however, the callback may not be invoked until // the stream's finished() function is called. // -class UnmarshalCallback : public IceUtil::Shared +class UnmarshalCallback { public: @@ -66,13 +67,13 @@ class UnmarshalCallback : public IceUtil::Shared // virtual void unmarshaled(PyObject*, PyObject*, void*) = 0; }; -typedef IceUtil::Handle UnmarshalCallbackPtr; +using UnmarshalCallbackPtr = std::shared_ptr; // // ReadValueCallback retains all of the information necessary to store an unmarshaled // Slice value as a Python object. // -class ReadValueCallback : public IceUtil::Shared +class ReadValueCallback { public: @@ -88,7 +89,7 @@ class ReadValueCallback : public IceUtil::Shared PyObject* _target; void* _closure; }; -typedef IceUtil::Handle ReadValueCallbackPtr; +using ReadValueCallbackPtr = std::shared_ptr; // // This class assists during unmarshaling of Slice classes and exceptions. @@ -140,6 +141,7 @@ class TypeInfo : public UnmarshalCallback { public: + TypeInfo(); virtual std::string getId() const = 0; virtual bool validate(PyObject*) = 0; @@ -153,13 +155,6 @@ class TypeInfo : public UnmarshalCallback virtual void unmarshaled(PyObject*, PyObject*, void*); // Default implementation is assert(false). virtual void destroy(); - -protected: - - TypeInfo(); - -public: - // // The marshal and unmarshal functions can raise Ice exceptions, and may raise // AbortMarshaling if an error occurs. @@ -170,7 +165,7 @@ class TypeInfo : public UnmarshalCallback virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*) = 0; }; -typedef IceUtil::Handle TypeInfoPtr; +using TypeInfoPtr = std::shared_ptr; // // Primitive type information. @@ -209,20 +204,20 @@ class PrimitiveInfo : public TypeInfo const Kind kind; }; -typedef IceUtil::Handle PrimitiveInfoPtr; +using PrimitiveInfoPtr = std::shared_ptr; // // Enum information. // -typedef std::map EnumeratorMap; +using EnumeratorMap = std::map; -class EnumInfo : public TypeInfo +class EnumInfo final : public TypeInfo { public: EnumInfo(const std::string&, PyObject*, PyObject*); - virtual std::string getId() const; + std::string getId() const final; virtual bool validate(PyObject*); @@ -246,7 +241,7 @@ class EnumInfo : public TypeInfo const Ice::Int maxValue; const EnumeratorMap enumerators; }; -typedef IceUtil::Handle EnumInfoPtr; +using EnumInfoPtr = std::shared_ptr; class DataMember : public UnmarshalCallback { @@ -260,8 +255,8 @@ class DataMember : public UnmarshalCallback bool optional; int tag; }; -typedef IceUtil::Handle DataMemberPtr; -typedef std::vector DataMemberList; +using DataMemberPtr = std::shared_ptr; +using DataMemberList = std::vector; // // Struct information. @@ -302,7 +297,7 @@ class StructInfo : public TypeInfo int _wireSize; PyObjectHandle _nullMarshalValue; }; -typedef IceUtil::Handle StructInfoPtr; +using StructInfoPtr = std::shared_ptr; // // Sequence information. @@ -363,14 +358,14 @@ class SequenceInfo : public TypeInfo Type type; PyObject* factory; }; - typedef IceUtil::Handle SequenceMappingPtr; + using SequenceMappingPtr = std::shared_ptr; PyObject* getSequence(const PrimitiveInfoPtr&, PyObject*); void marshalPrimitiveSequence(const PrimitiveInfoPtr&, PyObject*, Ice::OutputStream*); void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, Ice::InputStream*, const UnmarshalCallbackPtr&, PyObject*, void*, const SequenceMappingPtr&); - PyObject* createSequenceFromMemory(const SequenceMappingPtr&, const char*, Py_ssize_t, BuiltinType, bool); + PyObject* createSequenceFromMemory(const SequenceMappingPtr&, const char*, Py_ssize_t, BuiltinType); public: @@ -378,24 +373,7 @@ class SequenceInfo : public TypeInfo const SequenceMappingPtr mapping; const TypeInfoPtr elementType; }; -typedef IceUtil::Handle SequenceInfoPtr; - -class Buffer : public IceUtil::Shared -{ -public: - - Buffer(const char*, Py_ssize_t, SequenceInfo::BuiltinType); - ~Buffer(); - const char* data() const; - Py_ssize_t size() const; - SequenceInfo::BuiltinType type(); - -private: - - const char* _data; - const Py_ssize_t _size; - const SequenceInfo::BuiltinType _type; -}; +using SequenceInfoPtr = std::shared_ptr; // // Custom information. @@ -425,12 +403,12 @@ class CustomInfo : public TypeInfo const std::string id; PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. }; -typedef IceUtil::Handle CustomInfoPtr; +using CustomInfoPtr = std::shared_ptr; // // Dictionary information. // -class DictionaryInfo : public TypeInfo +class DictionaryInfo : public TypeInfo, public std::enable_shared_from_this { public: @@ -463,7 +441,7 @@ class DictionaryInfo : public TypeInfo PyObjectHandle key; }; - typedef IceUtil::Handle KeyCallbackPtr; + using KeyCallbackPtr = std::shared_ptr; std::string id; TypeInfoPtr keyType; @@ -474,15 +452,15 @@ class DictionaryInfo : public TypeInfo bool _variableLength; int _wireSize; }; -typedef IceUtil::Handle DictionaryInfoPtr; - -typedef std::vector TypeInfoList; +using DictionaryInfoPtr = std::shared_ptr; +using TypeInfoList = std::vector; -class ClassInfo : public TypeInfo +class ClassInfo final : public TypeInfo, public std::enable_shared_from_this { public: ClassInfo(const std::string&); + void init(); void define(PyObject*, PyObject*, PyObject*); @@ -516,11 +494,12 @@ class ClassInfo : public TypeInfo // Value type information // -class ValueInfo : public TypeInfo +class ValueInfo final : public TypeInfo, public std::enable_shared_from_this { public: ValueInfo(const std::string&); + void init(); void define(PyObject*, int, bool, bool, PyObject*, PyObject*); @@ -559,11 +538,12 @@ class ValueInfo : public TypeInfo // // Proxy information. // -class ProxyInfo : public TypeInfo +class ProxyInfo final : public TypeInfo, public std::enable_shared_from_this { public: ProxyInfo(const std::string&); + void init(); void define(PyObject*); @@ -585,12 +565,12 @@ class ProxyInfo : public TypeInfo PyObject* pythonType; // Borrowed reference - the enclosing Python module owns the reference. PyObject* typeObj; // Borrowed reference - the "_t_XXX" variable owns the reference. }; -typedef IceUtil::Handle ProxyInfoPtr; +using ProxyInfoPtr = std::shared_ptr; // // Exception information. // -class ExceptionInfo : public IceUtil::Shared +class ExceptionInfo : public std::enable_shared_from_this { public: @@ -679,9 +659,7 @@ class ExceptionWriter : public Ice::UserException ExceptionWriter(const ExceptionWriter&) = default; virtual std::string ice_id() const; -#ifndef ICE_CPP11_MAPPING - virtual Ice::UserException* ice_clone() const; -#endif + virtual Ice::UserException* ice_cloneImpl() const; virtual void ice_throw() const; virtual void _write(Ice::OutputStream*) const; @@ -714,9 +692,7 @@ class ExceptionReader : public Ice::UserException ExceptionReader(const ExceptionReader&) = default; virtual std::string ice_id() const; -#ifndef ICE_CPP11_MAPPING - virtual Ice::UserException* ice_clone() const; -#endif + virtual Ice::UserException* ice_cloneImpl() const; virtual void ice_throw() const; virtual void _write(Ice::OutputStream*) const; @@ -740,12 +716,7 @@ class ExceptionReader : public Ice::UserException Ice::SlicedDataPtr _slicedData; }; -class IdResolver : public Ice::CompactIdResolver -{ -public: - - virtual ::std::string resolve(Ice::Int) const; -}; +std::string resolveCompactId(Ice::Int id); ClassInfoPtr lookupClassInfo(const std::string&); ValueInfoPtr lookupValueInfo(const std::string&); diff --git a/python/modules/IcePy/msbuild/icepy.vcxproj b/python/modules/IcePy/msbuild/icepy.vcxproj index 2887c6e60de..a84ad13831b 100644 --- a/python/modules/IcePy/msbuild/icepy.vcxproj +++ b/python/modules/IcePy/msbuild/icepy.vcxproj @@ -153,6 +153,7 @@ stdcpp17 + ICE_CPP11_MAPPING;%(PreprocessorDefinitions) @@ -161,6 +162,7 @@ stdcpp17 + ICE_CPP11_MAPPING;%(PreprocessorDefinitions) @@ -169,6 +171,7 @@ stdcpp17 + ICE_CPP11_MAPPING;%(PreprocessorDefinitions) @@ -177,6 +180,7 @@ stdcpp17 + ICE_CPP11_MAPPING;%(PreprocessorDefinitions) @@ -194,10 +198,10 @@ - - - - + + + + @@ -205,4 +209,4 @@ CopyDependencies - \ No newline at end of file + diff --git a/python/msbuild/ice.proj b/python/msbuild/ice.proj index 92dbbe3fb45..1dd566b810b 100644 --- a/python/msbuild/ice.proj +++ b/python/msbuild/ice.proj @@ -15,7 +15,7 @@ - c++98\slice2py;c++98\icessl;c++98\icediscovery;c++98\icelocatordiscovery;c++11\glacier2router++11;c++98\glacier2cryptpermissionsverifier + c++98\slice2py;c++11\icessl++11;c++11\icediscovery++11;c++11\icelocatordiscovery++11;c++11\glacier2router++11;c++11\glacier2cryptpermissionsverifier++11 diff --git a/python/python/Ice/__init__.py b/python/python/Ice/__init__.py index f6ad058c69f..6ec37e32050 100644 --- a/python/python/Ice/__init__.py +++ b/python/python/Ice/__init__.py @@ -81,7 +81,7 @@ encodingVersionToString = IcePy.encodingVersionToString generateUUID = IcePy.generateUUID loadSlice = IcePy.loadSlice -AsyncResult = IcePy.AsyncResult +AsyncInvocationContext = IcePy.AsyncInvocationContext Unset = IcePy.Unset from Ice.IceFuture import FutureBase, wrap_future # noqa @@ -136,6 +136,7 @@ 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: @@ -216,17 +217,17 @@ def _warn(self, msg): class InvocationFuture(Future): - def __init__(self, operation, asyncResult): + def __init__(self, operation, asyncInvocationContext): Future.__init__(self) - assert asyncResult + assert asyncInvocationContext self._operation = operation - self._asyncResult = asyncResult # May be None for a batch invocation. + self._asyncInvocationContext = asyncInvocationContext self._sent = False self._sentSynchronously = False self._sentCallbacks = [] def cancel(self): - self._asyncResult.cancel() + self._asyncInvocationContext.cancel() return Future.cancel(self) def add_done_callback_async(self, fn): @@ -240,7 +241,7 @@ def callback(): if self._state == Future.StateRunning: self._doneCallbacks.append(fn) return - self._asyncResult.callLater(callback) + self._asyncInvocationContext.callLater(callback) def is_sent(self): with self._condition: @@ -268,12 +269,13 @@ def callback(): if not self._sent: self._sentCallbacks.append(fn) return - self._asyncResult.callLater(callback) + self._asyncInvocationContext.callLater(callback) 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: @@ -301,16 +303,6 @@ def set_sent(self, sentSynchronously): def operation(self): return self._operation - - def proxy(self): - return self._asyncResult.getProxy() - - def connection(self): - return self._asyncResult.getConnection() - - def communicator(self): - return self._asyncResult.getCommunicator() - def _warn(self, msg): communicator = self.communicator() if communicator: @@ -853,23 +845,6 @@ def __init__(self, val): SSLConnectionInfo = IcePy.SSLConnectionInfo -class ThreadNotification(object): - """Base class for thread notification callbacks. A subclass must - define the start and stop methods.""" - - def __init__(self): - pass - - def start(): - """Invoked in the context of a thread created by the Ice run time.""" - pass - - def stop(): - """Invoked in the context of an Ice run-time thread that is about - to terminate.""" - pass - - class BatchRequestInterceptor(object): """Base class for batch request interceptor. A subclass must define the enqueue method.""" @@ -915,7 +890,6 @@ class InitializationData(object): def __init__(self): self.properties = None self.logger = None - self.threadHook = None # Deprecated. self.threadStart = None self.threadStop = None self.dispatcher = None diff --git a/python/python/IceBox/__init__.py b/python/python/IceBox/__init__.py index 5fcb8db2345..304f0feb8c4 100644 --- a/python/python/IceBox/__init__.py +++ b/python/python/IceBox/__init__.py @@ -2,7 +2,6 @@ # import Ice - Ice.updateModule("IceBox") # Modules: diff --git a/python/test/Ice/ami/AllTests.py b/python/test/Ice/ami/AllTests.py index 0b686474e7d..e60e5fd6013 100644 --- a/python/test/Ice/ami/AllTests.py +++ b/python/test/Ice/ami/AllTests.py @@ -525,8 +525,9 @@ def allTestsFuture(helper, communicator, collocated): test(len(p.ice_idsAsync().result()) == 2) test(len(p.ice_idsAsync(ctx).result()) == 2) - if not collocated: - test(p.ice_getConnectionAsync().result() is not None) + # TODO: test connection + # if not collocated: + # test(p.ice_getConnectionAsync().result() is not None) p.opAsync().result() p.opAsync(ctx).result() @@ -573,9 +574,10 @@ def allTestsFuture(helper, communicator, collocated): p.ice_idsAsync(ctx).add_done_callback(cb.ids) cb.check() - if not collocated: - p.ice_getConnectionAsync().add_done_callback(cb.connection) - cb.check() + # TODO test connection + # if not collocated: + # p.ice_getConnectionAsync().add_done_callback(cb.connection) + # cb.check() p.opAsync().add_done_callback(cb.op) cb.check() @@ -663,9 +665,10 @@ def allTestsFuture(helper, communicator, collocated): i.ice_idsAsync().add_done_callback(cb.ex) cb.check() - if not collocated: - i.ice_getConnectionAsync().add_done_callback(cb.ex) - cb.check() + # TODO + # if not collocated: + # i.ice_getConnectionAsync().add_done_callback(cb.ex) + # cb.check() i.opAsync().add_done_callback(cb.ex) cb.check() @@ -1000,9 +1003,6 @@ def allTestsFuture(helper, communicator, collocated): # f = p.ice_pingAsync() test(f.operation() == "ice_ping") - test(f.connection() is None) # Expected - test(f.communicator() == communicator) - test(f.proxy() == p) f.result() # @@ -1011,9 +1011,6 @@ def allTestsFuture(helper, communicator, collocated): p2 = p.ice_oneway() f = p2.ice_pingAsync() test(f.operation() == "ice_ping") - test(f.connection() is None) # Expected - test(f.communicator() == communicator) - test(f.proxy() == p2) # # Batch request via proxy @@ -1021,9 +1018,6 @@ def allTestsFuture(helper, communicator, collocated): p2 = p.ice_batchOneway() p2.ice_ping() f = p2.ice_flushBatchRequestsAsync() - test(f.connection() is None) # Expected - test(f.communicator() == communicator) - test(f.proxy() == p2) f.result() if p.ice_getConnection(): @@ -1034,9 +1028,6 @@ def allTestsFuture(helper, communicator, collocated): p2 = p.ice_batchOneway() p2.ice_ping() f = con.flushBatchRequestsAsync(Ice.CompressBatch.BasedOnProxy) - test(f.connection() == con) - test(f.communicator() == communicator) - test(f.proxy() is None) # Expected f.result() # @@ -1045,9 +1036,6 @@ def allTestsFuture(helper, communicator, collocated): p2 = p.ice_batchOneway() p2.ice_ping() f = communicator.flushBatchRequestsAsync(Ice.CompressBatch.BasedOnProxy) - test(f.connection() is None) # Expected - test(f.communicator() == communicator) - test(f.proxy() is None) # Expected f.result() if p.ice_getConnection(): diff --git a/python/test/Ice/thread/AllTests.py b/python/test/Ice/thread/AllTests.py index b40908dbe16..d8e1eb3068a 100644 --- a/python/test/Ice/thread/AllTests.py +++ b/python/test/Ice/thread/AllTests.py @@ -29,7 +29,7 @@ def allTests(helper, communicator): obj = com.getObject() - startCount = com.getThreadHookStartCount() + startCount = com.getThreadStartCount() # # Start 5 async invocations that sleep for a little while to force new threads to be created. @@ -43,7 +43,6 @@ def allTests(helper, communicator): # # The remote thread hook should detect at least 4 more threads. There could be more for other Ice threads. # - test(com.getThreadHookStartCount() - startCount >= 4) test(com.getThreadStartCount() - startCount >= 4) # @@ -54,9 +53,7 @@ def allTests(helper, communicator): # # Finally, make sure we detected the same number of stops as starts. # - test(com.getThreadHookStopCount() == com.getThreadHookStartCount()) test(com.getThreadStopCount() == com.getThreadStartCount()) - test(com.getThreadHookStartCount() == com.getThreadStartCount()) print("ok") diff --git a/python/test/Ice/thread/Test.ice b/python/test/Ice/thread/Test.ice index 93432b67a86..762c44dd61d 100644 --- a/python/test/Ice/thread/Test.ice +++ b/python/test/Ice/thread/Test.ice @@ -19,9 +19,6 @@ interface RemoteCommunicator { TestIntf* getObject(); - int getThreadHookStartCount(); - int getThreadHookStopCount(); - int getThreadStartCount(); int getThreadStopCount(); diff --git a/python/test/Ice/thread/TestI.py b/python/test/Ice/thread/TestI.py index e5f8d7a8b7f..797fb4fe7a0 100644 --- a/python/test/Ice/thread/TestI.py +++ b/python/test/Ice/thread/TestI.py @@ -8,22 +8,12 @@ import threading -class ThreadHook(Ice.ThreadNotification): +class ThreadHook: def __init__(self): - self.threadHookStartCount = 0 - self.threadHookStopCount = 0 self.threadStartCount = 0 self.threadStopCount = 0 self.cond = threading.Condition() - def start(self): - with self.cond: - self.threadHookStartCount += 1 - - def stop(self): - with self.cond: - self.threadHookStopCount += 1 - def threadStart(self): with self.cond: self.threadStartCount += 1 @@ -32,14 +22,6 @@ def threadStop(self): with self.cond: self.threadStopCount += 1 - def getThreadHookStartCount(self): - with self.cond: - return self.threadHookStartCount - - def getThreadHookStopCount(self): - with self.cond: - return self.threadHookStopCount - def getThreadStartCount(self): with self.cond: return self.threadStartCount @@ -65,12 +47,6 @@ def __init__(self, communicator, hook): def getObject(self, current=None): return self.obj - def getThreadHookStartCount(self, current=None): - return self.hook.getThreadHookStartCount() - - def getThreadHookStopCount(self, current=None): - return self.hook.getThreadHookStopCount() - def getThreadStartCount(self, current=None): return self.hook.getThreadStartCount() @@ -91,9 +67,10 @@ def createCommunicator(self, props, current=None): for k, v in props.items(): init.properties.setProperty(k, v) - init.threadHook = ThreadHook() - init.threadStart = init.threadHook.threadStart - init.threadStop = init.threadHook.threadStop + threadHook = ThreadHook() + + init.threadStart = threadHook.threadStart + init.threadStop = threadHook.threadStop # # Initialize a new communicator. @@ -101,7 +78,7 @@ def createCommunicator(self, props, current=None): communicator = Ice.initialize(init) proxy = current.adapter.addWithUUID( - RemoteCommunicatorI(communicator, init.threadHook) + RemoteCommunicatorI(communicator, threadHook) ) return Test.RemoteCommunicatorPrx.uncheckedCast(proxy)