diff options
Diffstat (limited to 'cpp/src/Ice/Proxy.cpp')
-rw-r--r-- | cpp/src/Ice/Proxy.cpp | 503 |
1 files changed, 503 insertions, 0 deletions
diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp new file mode 100644 index 00000000000..af0789dfd3b --- /dev/null +++ b/cpp/src/Ice/Proxy.cpp @@ -0,0 +1,503 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/Proxy.h> +#include <Ice/ProxyFactory.h> +#include <Ice/Object.h> +#include <Ice/ObjectAdapterFactory.h> +#include <Ice/Outgoing.h> +#include <Ice/Reference.h> +#include <Ice/Endpoint.h> +#include <Ice/Instance.h> +#include <Ice/Logger.h> +#include <Ice/TraceLevels.h> +#include <Ice/Emitter.h> +#include <Ice/Stream.h> +#include <Ice/LocalException.h> +#include <Ice/Functional.h> +#include <sstream> + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +void IceInternal::incRef(::IceProxy::Ice::Object* p) { p->__incRef(); } +void IceInternal::decRef(::IceProxy::Ice::Object* p) { p->__decRef(); } + +void IceInternal::incRef(::IceDelegate::Ice::Object* p) { p->__incRef(); } +void IceInternal::decRef(::IceDelegate::Ice::Object* p) { p->__decRef(); } + +void IceInternal::incRef(::IceDelegateM::Ice::Object* p) { p->__incRef(); } +void IceInternal::decRef(::IceDelegateM::Ice::Object* p) { p->__decRef(); } + +void +IceInternal::checkedCast(::IceProxy::Ice::Object* b, ::IceProxy::Ice::Object*& d) +{ + d = b; +} + +void +IceInternal::uncheckedCast(::IceProxy::Ice::Object* b, ::IceProxy::Ice::Object*& d) +{ + d = b; +} + +void +IceInternal::write(Stream* s, const ObjectPrx& v) +{ + s->instance()->proxyFactory()->proxyToStream(v, s); +} + +void +IceInternal::read(Stream* s, ObjectPrx& v) +{ + v = s->instance()->proxyFactory()->streamToProxy(s); +} + +Ice::ObjectPrxE::ObjectPrxE(const ObjectPrxE& p) : + _prx(p._prx) +{ +} + +Ice::ObjectPrxE::ObjectPrxE(const ObjectPrx& p) : + _prx(p) +{ +} + +Ice::ObjectPrxE::operator ObjectPrx() const +{ + return _prx; +} + +IceProxy::Ice::Object* +Ice::ObjectPrxE::operator->() const +{ + return _prx.get(); +} + +Ice::ObjectPrxE::operator bool() const +{ + return _prx.get() ? true : false; +} + +void +IceProxy::Ice::Object::_throw() +{ + throw ObjectPrxE(this); +} + +bool +IceProxy::Ice::Object::_isA(const string& s) +{ + int __cnt = 0; + while (true) + { + try + { + Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); + return __del->_isA(s); + } + catch (const LocationForward& __ex) + { + __locationForward(__ex); + } + catch (const NonRepeatable& __ex) + { + __handleException(*__ex.get(), __cnt); + } + catch (const LocalException& __ex) + { + __handleException(__ex, __cnt); + } + } +} + +void +IceProxy::Ice::Object::_ping() +{ + int __cnt = 0; + while (true) + { + try + { + Handle< ::IceDelegate::Ice::Object> __del = __getDelegate(); + __del->_ping(); + return; + } + catch (const LocationForward& __ex) + { + __locationForward(__ex); + } + catch (const NonRepeatable& __ex) + { + __handleException(*__ex.get(), __cnt); + } + catch (const LocalException& __ex) + { + __handleException(__ex, __cnt); + } + } +} + +bool +IceProxy::Ice::Object::operator==(const Object& r) const +{ + return _reference->identity == r._reference->identity; +} + +bool +IceProxy::Ice::Object::operator!=(const Object& r) const +{ + return _reference->identity != r._reference->identity; +} + +ObjectPrx +IceProxy::Ice::Object::_twoway() const +{ + ReferencePtr ref = _reference->changeMode(Reference::ModeTwoway); + if (ref == _reference) + { + return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); + } + else + { + ObjectPrx proxy(new ::IceProxy::Ice::Object()); + proxy->setup(ref); + return proxy; + } +} + +ObjectPrx +IceProxy::Ice::Object::_oneway() const +{ + ReferencePtr ref = _reference->changeMode(Reference::ModeOneway); + if (ref == _reference) + { + return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); + } + else + { + ObjectPrx proxy(new ::IceProxy::Ice::Object()); + proxy->setup(ref); + return proxy; + } +} + +ObjectPrx +IceProxy::Ice::Object::_secure() const +{ + ReferencePtr ref = _reference->changeMode(Reference::ModeSecure); + if (ref == _reference) + { + return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); + } + else + { + ObjectPrx proxy(new ::IceProxy::Ice::Object()); + proxy->setup(ref); + return proxy; + } +} + +ObjectPrx +IceProxy::Ice::Object::_datagram() const +{ + ReferencePtr ref = _reference->changeMode(Reference::ModeDatagram); + if (ref == _reference) + { + return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); + } + else + { + ObjectPrx proxy(new ::IceProxy::Ice::Object()); + proxy->setup(ref); + return proxy; + } +} + +ObjectPrx +IceProxy::Ice::Object::_timeout(int t) const +{ + ReferencePtr ref = _reference->changeTimeout(t); + if (ref == _reference) + { + return ObjectPrx(const_cast< ::IceProxy::Ice::Object*>(this)); + } + else + { + ObjectPrx proxy(new ::IceProxy::Ice::Object()); + proxy->setup(ref); + return proxy; + } +} + +ReferencePtr +IceProxy::Ice::Object::__reference() const +{ + return _reference; +} + +void +IceProxy::Ice::Object::__copyTo(::IceProxy::Ice::Object* to) const +{ + to->setup(_reference); +} + +void +IceProxy::Ice::Object::__handleException(const LocalException& ex, int& cnt) +{ + JTCSyncT<JTCMutex> sync(*this); + + _delegate = 0; + static const int max = 1; // TODO: Make number of retries configurable + + try + { + ex.raise(); + } + catch (const NoEndpointException&) + { + // + // We always retry on a no endpoint exception, as we might + // have a forwarded reference, but we retry with the original + // reference. + // + } + catch (const CloseConnectionException&) + { + // + // We always retry on a close connection exception, as this + // indicates graceful server shutdown. + // + // TODO: configurable timeout before we try again? + } + catch (const SocketException&) + { + ++cnt; + } + catch (const DNSException&) + { + ++cnt; + } + +#ifndef ICE_NO_TRACE + TraceLevelsPtr traceLevels = _reference->instance->traceLevels(); + LoggerPtr logger = _reference->instance->logger(); +#endif + + if(cnt > max) + { +#ifndef ICE_NO_TRACE + if (traceLevels->retry >= 1) + { + ostringstream s; + s << "cannot retry operation call because retry limit has been exceeded\n" << ex; + logger->trace(traceLevels->retryCat, s.str()); + } +#endif + ex.raise(); + } + +#ifndef ICE_NO_TRACE + if (traceLevels->retry >= 1) + { + ostringstream s; + s << "re-trying operation call because of exception\n" << ex; + logger->trace(traceLevels->retryCat, s.str()); + } +#endif + + // + // Reset the endpoints to the original endpoints upon retry + // + _reference = _reference->changeEndpoints(_reference->origEndpoints); +} + +void +IceProxy::Ice::Object::__locationForward(const LocationForward& ex) +{ + JTCSyncT<JTCMutex> sync(*this); + + if (_reference->identity != ex._prx->_reference->identity) + { + throw ReferenceIdentityException(__FILE__, __LINE__); + } + + _delegate = 0; + _reference = _reference->changeEndpoints(ex._prx->_reference->endpoints); + +/* +#ifndef ICE_NO_TRACE + TraceLevelsPtr traceLevels = _reference->instance->traceLevels(); + LoggerPtr logger = _reference->instance->logger(); + + if (traceLevels->locationForward >= 1) + { + ostringstream s; + s << "location forward for object with identity `" << _reference.identity << "'"; + logger->trace(traceLevels->locationForwardCat, s.str()); + } +#endif +*/ +} + +IceProxy::Ice::Object::Object() +{ +} + +IceProxy::Ice::Object::~Object() +{ +} + +Handle< ::IceDelegate::Ice::Object> +IceProxy::Ice::Object::__getDelegate() +{ + JTCSyncT<JTCMutex> sync(*this); + + if (!_delegate) + { + ObjectPtr obj = _reference->instance->objectAdapterFactory()->proxyToObject(this); + + if (obj) + { + _delegate = obj; + } + else + { + _delegate = __createDelegateM(); + _delegate->setup(_reference); + } + } + + return _delegate; +} + +Handle< ::IceDelegateM::Ice::Object> +IceProxy::Ice::Object::__createDelegateM() +{ + return Handle< ::IceDelegateM::Ice::Object>(new ::IceDelegateM::Ice::Object); +} + +void +IceProxy::Ice::Object::setup(const ReferencePtr& reference) +{ + // + // No need to synchronize, as this operation is only called + // upon initial initialization. + // + _reference = reference; +} + +IceDelegate::Ice::Object::Object() +{ +} + +IceDelegate::Ice::Object::~Object() +{ +} + +void +IceDelegate::Ice::Object::setup(const ::IceInternal::ReferencePtr&) +{ +} + +bool +IceDelegateM::Ice::Object::_isA(const string& s) +{ + Outgoing __out(__emitter(), __reference()); + Stream* __is = __out.is(); + Stream* __os = __out.os(); + __os->write("_isA"); + __os->write(s); + if (!__out.invoke()) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__); + } + bool __ret; + __is->read(__ret); + return __ret; +} + +void +IceDelegateM::Ice::Object::_ping() +{ + Outgoing __out(__emitter(), __reference()); + Stream* __os = __out.os(); + __os->write("_ping"); + if (!__out.invoke()) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__); + } +} + +IceDelegateM::Ice::Object::Object() +{ +} + +IceDelegateM::Ice::Object::~Object() +{ +} + +const EmitterPtr& +IceDelegateM::Ice::Object::__emitter() +{ + return _emitter; +} + +const ReferencePtr& +IceDelegateM::Ice::Object::__reference() +{ + return _reference; +} + +void +IceDelegateM::Ice::Object::setup(const ReferencePtr& reference) +{ + // + // No need to synchronize, as this operation is only called + // upon initial initialization. + // + _reference = reference; + vector<EndpointPtr> endpoints; + switch (_reference->mode) + { + case Reference::ModeTwoway: + case Reference::ModeOneway: + { + remove_copy_if(_reference->endpoints.begin(), _reference->endpoints.end(), back_inserter(endpoints), + not1(constMemFun(&Endpoint::regular))); + break; + } + + case Reference::ModeDatagram: + { + remove_copy_if(_reference->endpoints.begin(), _reference->endpoints.end(), back_inserter(endpoints), + not1(constMemFun(&Endpoint::datagram))); + break; + } + + case Reference::ModeSecure: + { + remove_copy_if(_reference->endpoints.begin(), _reference->endpoints.end(), back_inserter(endpoints), + not1(constMemFun(&Endpoint::secure))); + break; + } + } + + if (endpoints.empty()) + { + throw NoEndpointException(__FILE__, __LINE__); + } + + random_shuffle(endpoints.begin(), endpoints.end()); + + EmitterFactoryPtr factory = _reference->instance->emitterFactory(); + _emitter = factory->create(endpoints); +} |