// ********************************************************************** // // Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #include #include #include using namespace std; using namespace Ice; using namespace Test; class Cookie : public Ice::LocalObject { }; typedef IceUtil::Handle CookiePtr; template class CookieT : public Cookie { public: CookieT(const T& v) : cb(v) { } T cb; }; template CookiePtr newCookie(const T& cb) { return new CookieT(cb); } template const T& getCookie(const CookiePtr& cookie) { return dynamic_cast* >(cookie.get())->cb; } class AsyncCB : public IceUtil::Shared { public: void responseCallback(const CookiePtr& cookie) { getCookie(cookie)->ice_response(); } void exceptionCallback(const Ice::Exception& ex, const CookiePtr& cookie) { getCookie(cookie)->ice_exception(ex); } void responseCallbackEx(const CookiePtr& cookie) { getCookie(cookie)->ice_response(); } void exceptionCallbackEx(const Ice::Exception& ex, const CookiePtr& cookie) { getCookie(cookie)->ice_exception(ex); } void responseConcurrentCallback(Int number, const CookiePtr& cookie) { getCookie(cookie)->ice_response(number); } void exceptionConcurrentCallback(const Ice::Exception& ex, const CookiePtr& cookie) { getCookie(cookie)->ice_exception(ex); } void responseWaitCallback(const CookiePtr& cookie) { getCookie(cookie)->ice_response(); } void exceptionWaitCallback(const Ice::Exception& ex, const CookiePtr& cookie) { getCookie(cookie)->ice_exception(ex); } void responseCallbackWithPayload(const CookiePtr& cookie) { getCookie(cookie)->ice_response(); } void exceptionCallbackWithPayload(const Ice::Exception& ex, const CookiePtr& cookie) { getCookie(cookie)->ice_exception(ex); } }; typedef IceUtil::Handle AsyncCBPtr; CallbackReceiverI::CallbackReceiverI() : _callback(false), _waitCallback(false), _callbackWithPayload(false), _finishWaitCallback(false) { } void CallbackReceiverI::callback(const Current&) { Lock sync(*this); assert(!_callback); _callback = true; notifyAll(); } void CallbackReceiverI::callbackEx(const Current& current) { callback(current); CallbackException ex; ex.someValue = 3.14; ex.someString = "3.14"; throw ex; } void CallbackReceiverI::concurrentCallback_async(const AMD_CallbackReceiver_concurrentCallbackPtr& cb, Int number, const Current&) { Lock sync(*this); pair p; p.first = cb; p.second = number; _callbacks.push_back(p); notifyAll(); } void CallbackReceiverI::waitCallback(const Current&) { { Lock sync(*this); assert(!_waitCallback); _waitCallback = true; notifyAll(); } { Lock sync(*this); while(!_finishWaitCallback) { wait(); } _finishWaitCallback = false; } } void CallbackReceiverI::callbackWithPayload(const Ice::ByteSeq&, const Current&) { Lock sync(*this); assert(!_callbackWithPayload); _callbackWithPayload = true; notifyAll(); } void CallbackReceiverI::callbackOK() { Lock sync(*this); while(!_callback) { wait(); } _callback = false; } void CallbackReceiverI::waitCallbackOK() { Lock sync(*this); while(!_waitCallback) { wait(); } _waitCallback = false; } void CallbackReceiverI::callbackWithPayloadOK() { Lock sync(*this); while(!_callbackWithPayload) { wait(); } _callbackWithPayload = false; } void CallbackReceiverI::notifyWaitCallback() { Lock sync(*this); _finishWaitCallback = true; notifyAll(); }; void CallbackReceiverI::answerConcurrentCallbacks(unsigned int num) { Lock sync(*this); while(_callbacks.size() != num) { wait(); } for(vector >::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p) { p->first->ice_response(p->second); } _callbacks.clear(); } CallbackI::CallbackI() { } void CallbackI::initiateCallback_async(const AMD_Callback_initiateCallbackPtr& cb, const CallbackReceiverPrx& proxy, const Current& current) { if(proxy->ice_isTwoway()) { AsyncCBPtr acb = new AsyncCB(); proxy->begin_callback(current.ctx, newCallback_CallbackReceiver_callback(acb, &AsyncCB::responseCallback, &AsyncCB::exceptionCallback), newCookie(cb)); } else { proxy->callback(current.ctx); cb->ice_response(); } } void CallbackI::initiateCallbackEx_async(const AMD_Callback_initiateCallbackExPtr& cb, const CallbackReceiverPrx& proxy, const Current& current) { if(proxy->ice_isTwoway()) { AsyncCBPtr acb = new AsyncCB(); proxy->begin_callbackEx(current.ctx, newCallback_CallbackReceiver_callbackEx(acb, &AsyncCB::responseCallbackEx, &AsyncCB::exceptionCallbackEx), newCookie(cb)); } else { proxy->callbackEx(current.ctx); cb->ice_response(); } } void CallbackI::initiateConcurrentCallback_async(const AMD_Callback_initiateConcurrentCallbackPtr& cb, Int number, const CallbackReceiverPrx& proxy, const Current& current) { AsyncCBPtr acb = new AsyncCB(); proxy->begin_concurrentCallback(number, current.ctx, newCallback_CallbackReceiver_concurrentCallback(acb, &AsyncCB::responseConcurrentCallback, &AsyncCB::exceptionConcurrentCallback), newCookie(cb)); } void CallbackI::initiateWaitCallback_async(const AMD_Callback_initiateWaitCallbackPtr& cb, const CallbackReceiverPrx& proxy, const Current& current) { AsyncCBPtr acb = new AsyncCB(); proxy->begin_waitCallback(current.ctx, newCallback_CallbackReceiver_waitCallback(acb, &AsyncCB::responseWaitCallback, &AsyncCB::exceptionWaitCallback), newCookie(cb)); } void CallbackI::initiateCallbackWithPayload_async(const AMD_Callback_initiateCallbackWithPayloadPtr& cb, const CallbackReceiverPrx& proxy, const Current& current) { Ice::ByteSeq seq(1000 * 1024, 0); AsyncCBPtr acb = new AsyncCB(); proxy->begin_callbackWithPayload(seq, current.ctx, newCallback_CallbackReceiver_callbackWithPayload(acb, &AsyncCB::responseCallbackWithPayload, &AsyncCB::exceptionCallbackWithPayload), newCookie(cb)); } void CallbackI::shutdown(const Ice::Current& current) { current.adapter->getCommunicator()->shutdown(); }