summaryrefslogtreecommitdiff
path: root/cpp/include/Ice/OutgoingAsync.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/include/Ice/OutgoingAsync.h')
-rw-r--r--cpp/include/Ice/OutgoingAsync.h786
1 files changed, 641 insertions, 145 deletions
diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h
index afcfc1d7fcc..3b61fd7be52 100644
--- a/cpp/include/Ice/OutgoingAsync.h
+++ b/cpp/include/Ice/OutgoingAsync.h
@@ -11,12 +11,23 @@
#define ICE_OUTGOING_ASYNC_H
#include <IceUtil/Timer.h>
+#include <IceUtil/Monitor.h>
#include <Ice/OutgoingAsyncF.h>
-#include <Ice/AsyncResult.h>
#include <Ice/CommunicatorF.h>
#include <Ice/ConnectionIF.h>
#include <Ice/ObjectAdapterF.h>
+#include <Ice/VirtualShared.h>
+#include <Ice/RequestHandlerF.h>
+#include <Ice/ConnectionF.h>
#include <Ice/OutputStream.h>
+#include <Ice/InputStream.h>
+#include <Ice/ObserverHelper.h>
+#include <Ice/LocalException.h>
+
+#ifndef ICE_CPP11_MAPPING
+# include <Ice/AsyncResult.h>
+# include <IceUtil/UniquePtr.h>
+#endif
#include <exception>
@@ -26,25 +37,74 @@ namespace IceInternal
class RetryException;
class CollocatedRequestHandler;
+class ICE_API OutgoingAsyncCompletionCallback
+{
+protected:
+
+ virtual bool handleSent(bool, bool) = 0;
+ virtual bool handleException(const Ice::Exception&) = 0;
+ virtual bool handleResponse(bool) = 0;
+
+ virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const = 0;
+ virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const = 0;
+ virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const = 0;
+};
+
//
// Base class for handling asynchronous invocations. This class is
// responsible for the handling of the output stream and the child
// invocation observer.
//
-class ICE_API OutgoingAsyncBase : public Ice::AsyncResult
+class ICE_API OutgoingAsyncBase : virtual public OutgoingAsyncCompletionCallback,
+#ifndef ICE_CPP11_MAPPING
+ public Ice::AsyncResult,
+#endif
+ public Ice::EnableSharedFromThis<OutgoingAsyncBase>
{
public:
virtual bool sent();
- virtual bool completed(const Ice::Exception&);
- virtual bool completed();
+ virtual bool exception(const Ice::Exception&);
+ virtual bool response();
+
+ void invokeSentAsync();
+ void invokeExceptionAsync();
+ void invokeResponseAsync();
+
+ void invokeSent();
+ void invokeException();
+ void invokeResponse();
+
+ virtual void cancelable(const IceInternal::CancellationHandlerPtr&);
+ void cancel();
+
+#ifndef ICE_CPP11_MAPPING
+ virtual Ice::Int getHash() const;
+
+ virtual Ice::CommunicatorPtr getCommunicator() const;
+ virtual Ice::ConnectionPtr getConnection() const;
+ virtual Ice::ObjectPrx getProxy() const;
+
+ virtual Ice::LocalObjectPtr getCookie() const;
+ virtual const std::string& getOperation() const;
+
+ virtual bool isCompleted() const;
+ virtual void waitForCompleted();
+
+ virtual bool isSent() const;
+ virtual void waitForSent();
- // Those methods are public when called from an OutgoingAsyncBase reference.
- using Ice::AsyncResult::cancelable;
- using Ice::AsyncResult::invokeSent;
- using Ice::AsyncResult::invokeSentAsync;
- using Ice::AsyncResult::invokeCompleted;
- using Ice::AsyncResult::invokeCompletedAsync;
+ virtual bool sentSynchronously() const;
+
+ virtual void throwLocalException() const;
+
+ virtual bool __wait();
+ virtual Ice::InputStream* __startReadParams();
+ virtual void __endReadParams();
+ virtual void __readEmptyParams();
+ virtual void __readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&);
+ virtual void __throwUserException();
+#endif
void attachRemoteObserver(const Ice::ConnectionInfoPtr& c, const Ice::EndpointPtr& endpt, Ice::Int requestId)
{
@@ -63,22 +123,67 @@ public:
return &_os;
}
- virtual Ice::InputStream* getIs();
+ Ice::InputStream* getIs()
+ {
+ return &_is;
+ }
protected:
+ OutgoingAsyncBase(const InstancePtr&);
+
+ bool sentImpl(bool);
+ bool exceptionImpl(const Ice::Exception&);
+ bool responseImpl(bool);
+
+ void cancel(const Ice::LocalException&);
+ void checkCanceled();
+
+ void warning(const std::exception&) const;
+ void warning() const;
+
+ //
+ // This virtual method is necessary for the communicator flush
+ // batch requests implementation.
+ //
+ virtual IceInternal::InvocationObserver& getObserver()
+ {
+ return _observer;
+ }
+
+ const InstancePtr _instance;
+ Ice::ConnectionPtr _cachedConnection;
+ bool _sentSynchronously;
+ bool _doneInSent;
+ unsigned char _state;
+
#ifdef ICE_CPP11_MAPPING
- OutgoingAsyncBase(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, const CallbackBasePtr&);
+ std::mutex _m;
+ using Lock = std::lock_guard<std::mutex>;
+ std::exception_ptr _ex;
+ std::exception_ptr _cancellationException;
#else
- OutgoingAsyncBase(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, const CallbackBasePtr&,
- const Ice::LocalObjectPtr&);
+ IceUtil::Monitor<IceUtil::Mutex> _m;
+ typedef IceUtil::Monitor<IceUtil::Mutex>::Lock Lock;
+ IceUtil::UniquePtr<Ice::Exception> _ex;
+ IceUtil::UniquePtr<Ice::LocalException> _cancellationException;
+ Ice::LocalObjectPtr _cookie;
#endif
- bool sent(bool);
- bool finished(const Ice::Exception&);
+ InvocationObserver _observer;
ObserverHelperT<Ice::Instrumentation::ChildInvocationObserver> _childObserver;
Ice::OutputStream _os;
+ Ice::InputStream _is;
+
+ CancellationHandlerPtr _cancellationHandler;
+
+ static const unsigned char OK;
+ static const unsigned char Sent;
+#ifndef ICE_CPP11_MAPPING
+ static const unsigned char Done;
+ static const unsigned char EndCalled;
+#endif
};
//
@@ -87,38 +192,39 @@ protected:
// correct notified of failures and make sure the retry task is
// correctly canceled when the invocation completes.
//
-class ICE_API ProxyOutgoingAsyncBase : public OutgoingAsyncBase, public IceUtil::TimerTask
+class ICE_API ProxyOutgoingAsyncBase : public OutgoingAsyncBase,
+ public IceUtil::TimerTask,
+ public Ice::EnableSharedFromThis<ProxyOutgoingAsyncBase>
{
public:
virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool) = 0;
virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*) = 0;
- virtual Ice::ObjectPrxPtr getProxy() const;
-
- using OutgoingAsyncBase::sent;
- virtual bool completed(const Ice::Exception&);
- void retryException(const Ice::Exception&);
+ virtual bool exception(const Ice::Exception&);
virtual void cancelable(const CancellationHandlerPtr&);
+ void retryException(const Ice::Exception&);
void retry();
void abort(const Ice::Exception&);
-protected:
+ using Ice::EnableSharedFromThis<ProxyOutgoingAsyncBase>::shared_from_this;
-#ifdef ICE_CPP11_MAPPING
- ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&);
-#else
- ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&,
- const Ice::LocalObjectPtr&);
+#ifndef ICE_CPP11_MAPPING
+ virtual Ice::ObjectPrx getProxy() const;
+ virtual Ice::CommunicatorPtr getCommunicator() const;
#endif
- void invokeImpl(bool);
- bool sent(bool);
- bool finished(const Ice::Exception&);
- bool finished(bool);
+protected:
+
+ ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&);
+ ~ProxyOutgoingAsyncBase();
+
+ void invokeImpl(bool);
+ bool sentImpl(bool);
+ bool exceptionImpl(const Ice::Exception&);
+ bool responseImpl(bool);
- int handleException(const Ice::Exception&);
virtual void runTimerTask();
const Ice::ObjectPrxPtr _proxy;
@@ -138,24 +244,23 @@ class ICE_API OutgoingAsync : public ProxyOutgoingAsyncBase
{
public:
-#ifdef ICE_CPP11_MAPPING
- OutgoingAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&);
-#else
- OutgoingAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&);
-#endif
+ OutgoingAsync(const Ice::ObjectPrxPtr&);
+
void prepare(const std::string&, Ice::OperationMode, const Ice::Context&);
virtual bool sent();
+ virtual bool response();
virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool);
virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*);
- using ProxyOutgoingAsyncBase::completed;
- virtual bool completed();
-
void abort(const Ice::Exception&);
-
- void invoke();
+ void invoke(const std::string&);
+#ifdef ICE_CPP11_MAPPING
+ void invoke(const std::string&, Ice::OperationMode, Ice::FormatType, const Ice::Context&,
+ const std::function<void (Ice::OutputStream*)>&);
+ void throwUserException();
+#endif
Ice::OutputStream* startWriteParams(Ice::FormatType format)
{
@@ -182,14 +287,15 @@ public:
}
}
- virtual Ice::InputStream* getIs()
- {
- return &_is;
- }
-
-private:
+protected:
const Ice::EncodingVersion _encoding;
+
+#ifdef ICE_CPP11_MAPPING
+ std::function<void (const ::Ice::UserException&)> _userException;
+#endif
+
+ bool _synchronous;
};
//
@@ -199,16 +305,12 @@ class ICE_API ProxyFlushBatchAsync : public ProxyOutgoingAsyncBase
{
public:
-#ifdef ICE_CPP11_MAPPING
- ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&);
-#else
- ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&);
-#endif
+ ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&);
virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool);
virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*);
- void invoke();
+ void invoke(const std::string&);
private:
@@ -223,15 +325,12 @@ class ICE_API ProxyGetConnection : public ProxyOutgoingAsyncBase
{
public:
-#ifdef ICE_CPP11_MAPPING
- ProxyGetConnection(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&);
-#else
- ProxyGetConnection(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&);
-#endif
+ ProxyGetConnection(const Ice::ObjectPrxPtr&);
+
virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool);
virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*);
- void invoke();
+ void invoke(const std::string&);
};
typedef IceUtil::Handle<ProxyGetConnection> ProxyGetConnectionPtr;
@@ -242,16 +341,11 @@ class ICE_API ConnectionFlushBatchAsync : public OutgoingAsyncBase
{
public:
-#ifdef ICE_CPP11_MAPPING
- ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const Ice::CommunicatorPtr&, const InstancePtr&,
- const std::string&, const CallbackBasePtr&);
-#else
- ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const Ice::CommunicatorPtr&, const InstancePtr&,
- const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&);
-#endif
+ ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const InstancePtr&);
+
virtual Ice::ConnectionPtr getConnection() const;
- void invoke();
+ void invoke(const std::string&);
private:
@@ -262,122 +356,524 @@ typedef IceUtil::Handle<ConnectionFlushBatchAsync> ConnectionFlushBatchAsyncPtr;
//
// Class for handling Ice::Communicator::begin_flushBatchRequests
//
-class ICE_API CommunicatorFlushBatchAsync : public Ice::AsyncResult
+class ICE_API CommunicatorFlushBatchAsync : public OutgoingAsyncBase,
+ public Ice::EnableSharedFromThis<CommunicatorFlushBatchAsync>
{
public:
-#ifdef ICE_CPP11_MAPPING
- CommunicatorFlushBatchAsync(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&,
- const CallbackBasePtr&);
-#else
- CommunicatorFlushBatchAsync(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&,
- const CallbackBasePtr&, const Ice::LocalObjectPtr&);
-#endif
+ CommunicatorFlushBatchAsync(const InstancePtr&);
void flushConnection(const Ice::ConnectionIPtr&);
- void ready();
+ void invoke(const std::string&);
+
+ using Ice::EnableSharedFromThis<CommunicatorFlushBatchAsync>::shared_from_this;
private:
void check(bool);
int _useCount;
+ InvocationObserver _observer;
};
}
+namespace IceInternal
+{
+
+#ifdef ICE_CPP11_MAPPING
+
+class ICE_API LambdaInvoke : virtual public OutgoingAsyncCompletionCallback
+{
+public:
+
+ LambdaInvoke(std::function<void (::std::exception_ptr)>&& exception, std::function<void (bool)>&& sent) :
+ _exception(move(exception)), _sent(move(sent))
+ {
+ }
+
+protected:
+
+ virtual bool handleSent(bool, bool) override;
+ virtual bool handleException(const Ice::Exception&) override;
+ virtual bool handleResponse(bool) override;
+
+ virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override;
+ virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override;
+ virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override;
+
+ std::function<void (::std::exception_ptr)> _exception;
+ std::function<void (bool)> _sent;
+ std::function<void (bool)> _response;
+};
+
+template<typename Promise>
+class PromiseInvoke : virtual public OutgoingAsyncCompletionCallback
+{
+public:
+
+ auto
+ getFuture() -> decltype(std::declval<Promise>().get_future())
+ {
+ return _promise.get_future();
+ }
+
+protected:
+
+ Promise _promise;
+ std::function<void (bool)> _response;
+
+private:
+
+ virtual bool handleSent(bool, bool) override
+ {
+ return false;
+ }
+
+ virtual bool handleException(const Ice::Exception& ex) override
+ {
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::Exception&)
+ {
+ _promise.set_exception(std::current_exception());
+ }
+ return false;
+ }
+
+ virtual bool handleResponse(bool ok) override
+ {
+ _response(ok);
+ return false;
+ }
+
+ virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override
+ {
+ assert(false);
+ }
+
+ virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override
+ {
+ assert(false);
+ }
+
+ virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override
+ {
+ assert(false);
+ }
+};
+
+template<typename T>
+class OutgoingAsyncT : public OutgoingAsync
+{
+public:
+
+ using OutgoingAsync::OutgoingAsync;
+
+ void
+ invoke(const std::string& operation,
+ Ice::OperationMode mode,
+ Ice::FormatType format,
+ const Ice::Context& ctx,
+ std::function<void (Ice::OutputStream*)>&& write,
+ std::function<void (const Ice::UserException&)>&& userException)
+ {
+ _read = [](Ice::InputStream* stream)
+ {
+ T v;
+ stream->read(v);
+ return v;
+ };
+ _userException = userException;
+ OutgoingAsync::invoke(operation, mode, format, ctx, write);
+ }
+
+ void
+ invoke(const std::string& operation,
+ Ice::OperationMode mode,
+ Ice::FormatType format,
+ const Ice::Context& ctx,
+ std::function<void (Ice::OutputStream*)>&& write,
+ std::function<void (const Ice::UserException&)>&& userException,
+ std::function<T (Ice::InputStream*)>&& read)
+ {
+ _read = read;
+ _userException = userException;
+ OutgoingAsync::invoke(operation, mode, format, ctx, write);
+ }
+
+protected:
+
+ std::function<T (Ice::InputStream*)> _read;
+};
+
+template<>
+class ICE_API OutgoingAsyncT<void> : public OutgoingAsync
+{
+public:
+
+ using OutgoingAsync::OutgoingAsync;
+
+ void
+ invoke(const std::string& operation,
+ Ice::OperationMode mode,
+ Ice::FormatType format,
+ const Ice::Context& ctx,
+ std::function<void (Ice::OutputStream*)>&& write,
+ std::function<void (const Ice::UserException&)>&& userException)
+ {
+ _userException = userException;
+ OutgoingAsync::invoke(operation, mode, format, ctx, write);
+ }
+};
+
+template<typename R>
+class LambdaOutgoing : public OutgoingAsyncT<R>, public LambdaInvoke
+{
+public:
+
+ LambdaOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy,
+ std::function<void (R)> response,
+ std::function<void (::std::exception_ptr)>& ex,
+ std::function<void (bool)>& sent) :
+ OutgoingAsyncT<R>(proxy), LambdaInvoke(std::move(ex), std::move(sent))
+ {
+ if(response)
+ {
+ _response = [this, response](bool ok)
+ {
+ if(ok)
+ {
+ assert(this->_read);
+ this->_is.startEncapsulation();
+ R v = this->_read(&this->_is);
+ this->_is.endEncapsulation();
+ try
+ {
+ response(std::move(v));
+ }
+ catch(...)
+ {
+ throw std::current_exception();
+ }
+ }
+ else
+ {
+ this->throwUserException();
+ }
+ };
+ }
+ }
+};
+
+template<>
+class ICE_API LambdaOutgoing<void> : public OutgoingAsyncT<void>, public LambdaInvoke
+{
+public:
+
+ LambdaOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy,
+ std::function<void()> response,
+ std::function<void (::std::exception_ptr)>& ex,
+ std::function<void (bool)>& sent) :
+ OutgoingAsyncT<void>(proxy), LambdaInvoke(std::move(ex), std::move(sent))
+ {
+ if(response)
+ {
+ _response = [this, response](bool ok)
+ {
+ if(this->_is.b.empty())
+ {
+ //
+ // If there's no response (oneway, batch-oneway proxies), we just set the promise
+ // on completion without reading anything from the input stream. This is required for
+ // batch invocations.
+ //
+ try
+ {
+ response();
+ }
+ catch(...)
+ {
+ throw std::current_exception();
+ }
+ }
+ else if(ok)
+ {
+ this->_is.skipEmptyEncapsulation();
+ try
+ {
+ response();
+ }
+ catch(...)
+ {
+ throw std::current_exception();
+ }
+ }
+ else
+ {
+ this->throwUserException();
+ }
+ };
+ }
+ }
+};
+
+template<typename P, typename R>
+class PromiseOutgoing : public OutgoingAsyncT<R>, public PromiseInvoke<P>
+{
+public:
+
+ PromiseOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, bool synchronous) :
+ OutgoingAsyncT<R>(proxy)
+ {
+ this->_synchronous = synchronous;
+ this->_response = [this](bool ok)
+ {
+ if(ok)
+ {
+ assert(this->_read);
+ this->_is.startEncapsulation();
+ R v = this->_read(&this->_is);
+ this->_is.endEncapsulation();
+ this->_promise.set_value(v);
+ }
+ else
+ {
+ this->throwUserException();
+ }
+ };
+ }
+};
+
+template<typename P>
+class PromiseOutgoing<P, void> : public OutgoingAsyncT<void>, public PromiseInvoke<P>
+{
+public:
+
+ PromiseOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, bool synchronous) :
+ OutgoingAsyncT<void>(proxy)
+ {
+ this->_synchronous = synchronous;
+ this->_response = [&](bool ok)
+ {
+ if(this->_is.b.empty())
+ {
+ //
+ // If there's no response (oneway, batch-oneway proxies), we just set the promise
+ // on completion without reading anything from the input stream. This is required for
+ // batch invocations.
+ //
+ this->_promise.set_value();
+ }
+ else if(ok)
+ {
+ this->_is.skipEmptyEncapsulation();
+ this->_promise.set_value();
+ }
+ else
+ {
+ this->throwUserException();
+ }
+ };
+ }
+
+ virtual bool handleSent(bool done, bool) override
+ {
+ if(done)
+ {
+ PromiseInvoke<P>::_promise.set_value();
+ }
+ return false;
+ }
+};
+
+#else
+
//
-// Base callback for C++11 mapping
+// Base class for all callbacks.
//
-#ifdef ICE_CPP11_MAPPING
-namespace IceInternal
+class ICE_API CallbackBase : public IceUtil::Shared
+{
+public:
+
+ void checkCallback(bool, bool);
+
+ virtual void completed(const ::Ice::AsyncResultPtr&) const = 0;
+ virtual IceUtil::Handle<CallbackBase> verify(const ::Ice::LocalObjectPtr&) = 0;
+ virtual void sent(const ::Ice::AsyncResultPtr&) const = 0;
+ virtual bool hasSentCallback() const = 0;
+};
+typedef IceUtil::Handle<CallbackBase> CallbackBasePtr;
+
+//
+// Base class for generic callbacks.
+//
+class ICE_API GenericCallbackBase : public virtual CallbackBase
+{
+};
+
+//
+// See comments in OutgoingAsync.cpp
+//
+extern ICE_API CallbackBasePtr __dummyCallback;
+
+//
+// Generic callback template that requires the caller to down-cast the
+// proxy and the cookie that are obtained from the AsyncResult.
+//
+template<class T>
+class AsyncCallback : public GenericCallbackBase
{
+public:
+
+ typedef T callback_type;
+ typedef IceUtil::Handle<T> TPtr;
+
+ typedef void (T::*Callback)(const ::Ice::AsyncResultPtr&);
+
+ AsyncCallback(const TPtr& instance, Callback cb, Callback sentcb = 0) :
+ _callback(instance), _completed(cb), _sent(sentcb)
+ {
+ checkCallback(instance, cb != 0);
+ }
-class ICE_API OnewayClosureCallback : public ::IceInternal::GenericCallbackBase
+ virtual void completed(const ::Ice::AsyncResultPtr& result) const
+ {
+ (_callback.get()->*_completed)(result);
+ }
+
+ virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr&)
+ {
+ return this; // Nothing to do, the cookie is not type-safe.
+ }
+
+ virtual void sent(const ::Ice::AsyncResultPtr& result) const
+ {
+ if(_sent)
+ {
+ (_callback.get()->*_sent)(result);
+ }
+ }
+
+ virtual bool hasSentCallback() const
+ {
+ return _sent != 0;
+ }
+
+private:
+
+ TPtr _callback;
+ Callback _completed;
+ Callback _sent;
+};
+
+class CallbackCompletion : virtual public OutgoingAsyncCompletionCallback
{
public:
- OnewayClosureCallback(const std::string&,
- const std::shared_ptr<Ice::ObjectPrx>&,
- std::function<void ()>,
- std::function<void (::std::exception_ptr)>,
- std::function<void (bool)>);
+ CallbackCompletion(const CallbackBasePtr& cb, const Ice::LocalObjectPtr& cookie) : _callback(cb)
+ {
+ if(!_callback)
+ {
+ throw IceUtil::IllegalArgumentException(__FILE__, __LINE__);
+ }
+ const_cast<CallbackBasePtr&>(_callback) = _callback->verify(cookie);
+ }
- virtual void
- sent(const ::Ice::AsyncResultPtr&) const;
+ virtual bool handleSent(bool, bool alreadySent)
+ {
+ return _callback && _callback->hasSentCallback() && !alreadySent;
+ }
- virtual bool
- hasSentCallback() const;
+ virtual bool handleException(const Ice::Exception&)
+ {
+ return _callback;
+ }
- virtual void
- completed(const ::Ice::AsyncResultPtr&) const;
+ virtual bool handleResponse(bool)
+ {
+ return _callback;
+ }
- static std::function<void ()>
- invoke(const std::string&,
- const std::shared_ptr<Ice::ObjectPrx>&,
- Ice::OperationMode,
- Ice::FormatType,
- std::function<void (::Ice::OutputStream*)>,
- std::function<void ()>,
- std::function<void (::std::exception_ptr)>,
- std::function<void (bool)>,
- const Ice::Context&);
+ virtual void handleInvokeSent(bool, OutgoingAsyncBase* outAsync) const
+ {
+ _callback->sent(outAsync);
+ }
+
+ virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase* outAsync) const
+ {
+ _callback->completed(outAsync);
+ }
+
+ virtual void handleInvokeResponse(bool, OutgoingAsyncBase* outAsync) const
+ {
+ _callback->completed(outAsync);
+ }
private:
- const std::string& __name;
- std::shared_ptr<Ice::ObjectPrx> __proxy;
- std::function<void ()> __response;
- std::function<void (::std::exception_ptr)> __exception;
- std::function<void (bool)> __sent;
+ const CallbackBasePtr _callback;
};
-class ICE_API TwowayClosureCallback : public ::IceInternal::GenericCallbackBase
+class ICE_API CallbackOutgoing : public OutgoingAsync, public CallbackCompletion
{
public:
- TwowayClosureCallback(const std::string&,
- const std::shared_ptr<Ice::ObjectPrx>&,
- bool,
- std::function<void (::Ice::InputStream*)>,
- std::function<void (const ::Ice::UserException&)>,
- std::function<void (::std::exception_ptr)>,
- std::function<void (bool)>);
-
- virtual void
- sent(const ::Ice::AsyncResultPtr&) const;
-
- virtual bool
- hasSentCallback() const;
-
- virtual void
- completed(const ::Ice::AsyncResultPtr&) const;
-
- static std::function<void ()>
- invoke(const std::string&,
- const std::shared_ptr<Ice::ObjectPrx>&,
- Ice::OperationMode,
- Ice::FormatType,
- std::function<void (::Ice::OutputStream*)>,
- bool,
- std::function<void (::Ice::InputStream*)>,
- std::function<void (const ::Ice::UserException&)>,
- std::function<void (::std::exception_ptr)>,
- std::function<void (bool)>,
- const Ice::Context&);
+ CallbackOutgoing(const Ice::ObjectPrx& proxy,
+ const std::string& operation,
+ const CallbackBasePtr& cb,
+ const Ice::LocalObjectPtr& cookie) :
+ OutgoingAsync(proxy), CallbackCompletion(cb, cookie), _operation(operation)
+ {
+ _cookie = cookie;
+ }
+
+ virtual const std::string&
+ getOperation() const
+ {
+ return _operation;
+ }
private:
- const std::string& __name;
- std::shared_ptr<Ice::ObjectPrx> __proxy;
- bool __readEmptyParams;
- std::function<void (::Ice::InputStream*)> __read;
- std::function<void (const ::Ice::UserException&)> __userException;
- std::function<void (::std::exception_ptr)> __exception;
- std::function<void (bool)> __sent;
+ const std::string& _operation;
};
+#endif
+
}
+
+#ifndef ICE_CPP11_MAPPING
+
+namespace Ice
+{
+
+typedef IceUtil::Handle< ::IceInternal::GenericCallbackBase> CallbackPtr;
+
+template<class T> CallbackPtr
+newCallback(const IceUtil::Handle<T>& instance,
+ void (T::*cb)(const AsyncResultPtr&),
+ void (T::*sentcb)(const AsyncResultPtr&) = 0)
+{
+ return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb);
+}
+
+template<class T> CallbackPtr
+newCallback(T* instance,
+ void (T::*cb)(const AsyncResultPtr&),
+ void (T::*sentcb)(const AsyncResultPtr&) = 0)
+{
+ return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb);
+}
+
+}
+
+//
+// Operation callbacks are specified in Proxy.h
+//
+
#endif
#endif