diff options
329 files changed, 32762 insertions, 10954 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES index 6ac8d5ad362..e83e48ab889 100644 --- a/cpp/CHANGES +++ b/cpp/CHANGES @@ -1,6 +1,39 @@ Changes since version 3.2.X (binary incompatible) ------------------------------------------------- +- Improved Glacier2 to take advantage of the new non-blocking aspects + of Ice. Glacier2 now uses the thread pool concurrency model by + default and in buffered mode, Glacier2 only uses a single thread to + forward queued requests. As a result, Glacier2 now requires a fixed + number of threads regardless of the number of connected clients. + +- Modified the collocation optimization check to not perform DNS + lookups. Invocations on a direct proxy will use collocation + optimization only if the host and port of one of its endpoint + matches the host and port of one of the endpoint or published + endpoint of an object adapter from the same communicator. + +- Added proxy methods flushBatchRequests() and + flushBatchRequests_async() to respectively synchronously and + asynchronously flush the batch requests of the connection associated + with the proxy. Like AMI requests, flushBatchRequests_async() is + guaranteed to not block. + +- Added support for oneway AMI requests. The ice_response() method of + the AMI callback is never called for oneway requests sent with AMI. + Unlike regular oneway requests which might block until the request + is passed to the TCP/IP stack, oneway AMI requests can't block. + +- Added support for server-side non-blocking connection creation. + Accepting a connection from a client can no longer block a thread + from server thread pool. In particular, the connection validation + and the SSL handshake can't block anymore. + +- Added support for non-blocking AMI and batch requests. The DNS + lookup, endpoint resolution, connection establishment and sending + of the request is now done in the background by a separate thread + if necessary. + - Glacier2 filters are now disabled by default for IceGrid client and administrative sessions created with the IceGrid session managers. If you rely on these filters to be set, you now need diff --git a/cpp/allTests.py b/cpp/allTests.py index 019f7cb67eb..33bc0d41a0a 100755 --- a/cpp/allTests.py +++ b/cpp/allTests.py @@ -50,6 +50,7 @@ tests = [ "Ice/custom", "Ice/retry", "Ice/timeout", + "Ice/background", "Ice/servantLocator", "Ice/threads", "Ice/interceptor", diff --git a/cpp/demo/Freeze/casino/BetResolver.cpp b/cpp/demo/Freeze/casino/BetResolver.cpp index 642164de96d..10def583101 100644 --- a/cpp/demo/Freeze/casino/BetResolver.cpp +++ b/cpp/demo/Freeze/casino/BetResolver.cpp @@ -42,7 +42,7 @@ BetResolver::add(const CasinoStore::PersistentBetPrx& bet, Ice::Long closeTime) } virtual void - run() + runTimerTask() { try { diff --git a/cpp/include/Ice/Config.h b/cpp/include/Ice/Config.h index be46f18545f..8563409cd9b 100644 --- a/cpp/include/Ice/Config.h +++ b/cpp/include/Ice/Config.h @@ -71,4 +71,8 @@ inline int getSystemErrno() { return GetLastError(); } inline int getSystemErrno() { return errno; } #endif +#if defined(__linux) && !defined(ICE_NO_EPOLL) +# define ICE_USE_EPOLL 1 +#endif + #endif diff --git a/cpp/include/Ice/EndpointIF.h b/cpp/include/Ice/EndpointIF.h index 841a6948e3d..1e530d1e75d 100644 --- a/cpp/include/Ice/EndpointIF.h +++ b/cpp/include/Ice/EndpointIF.h @@ -17,8 +17,12 @@ namespace IceInternal { class EndpointI; -ICE_API Ice::LocalObject* upCast(IceInternal::EndpointI*); -typedef IceInternal::Handle<EndpointI> EndpointIPtr; +ICE_API Ice::LocalObject* upCast(EndpointI*); +typedef Handle<EndpointI> EndpointIPtr; + +class EndpointHostResolver; +ICE_API IceUtil::Shared* upCast(EndpointHostResolver*); +typedef Handle<EndpointHostResolver> EndpointHostResolverPtr; } diff --git a/cpp/include/Ice/Outgoing.h b/cpp/include/Ice/Outgoing.h index c2cdfc040b3..10f3db806e0 100644 --- a/cpp/include/Ice/Outgoing.h +++ b/cpp/include/Ice/Outgoing.h @@ -12,6 +12,8 @@ #include <IceUtil/Mutex.h> #include <IceUtil/Monitor.h> +#include <Ice/RequestHandlerF.h> +#include <Ice/InstanceF.h> #include <Ice/ConnectionIF.h> #include <Ice/ReferenceF.h> #include <Ice/BasicStream.h> @@ -59,15 +61,26 @@ private: bool _retry; }; -class ICE_API Outgoing : private IceUtil::noncopyable +class ICE_API OutgoingMessageCallback : private IceUtil::noncopyable { public: - Outgoing(Ice::ConnectionI*, Reference*, const std::string&, Ice::OperationMode, const Ice::Context*, bool); + virtual ~OutgoingMessageCallback() { } + + virtual void sent(bool) = 0; + virtual void finished(const Ice::LocalException&) = 0; +}; + +class ICE_API Outgoing : public OutgoingMessageCallback +{ +public: + + Outgoing(RequestHandler*, const std::string&, Ice::OperationMode, const Ice::Context*); bool invoke(); // Returns true if ok, false if user exception. void abort(const Ice::LocalException&); - void finished(BasicStream&); + virtual void sent(bool); + virtual void finished(BasicStream&); void finished(const Ice::LocalException&); // Inlined for speed optimization. @@ -77,11 +90,10 @@ public: private: // - // Optimization. The connection and the reference may not be + // Optimization. The request handler and the reference may not be // deleted while a stack-allocated Outgoing still holds it. // - Ice::ConnectionI* _connection; - Reference* _reference; + RequestHandler* _handler; std::auto_ptr<Ice::LocalException> _exception; @@ -91,13 +103,13 @@ private: StateInProgress, StateOK, StateUserException, - StateLocalException + StateLocalException, + StateFailed } _state; BasicStream _is; BasicStream _os; - - const bool _compress; + bool _sent; // // NOTE: we use an attribute for the monitor instead of inheriting @@ -109,6 +121,31 @@ private: IceUtil::Monitor<IceUtil::Mutex> _monitor; }; +class BatchOutgoing : public OutgoingMessageCallback +{ +public: + + BatchOutgoing(RequestHandler*); + BatchOutgoing(Ice::ConnectionI*, Instance*); + + void invoke(); + + virtual void sent(bool); + virtual void finished(const Ice::LocalException&); + + BasicStream* os() { return &_os; } + +private: + + IceUtil::Monitor<IceUtil::Mutex> _monitor; + RequestHandler* _handler; + Ice::ConnectionI* _connection; + bool _sent; + std::auto_ptr<Ice::LocalException> _exception; + + BasicStream _os; +}; + } #endif diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h index ffcc03236e0..8871ba08a68 100644 --- a/cpp/include/Ice/OutgoingAsync.h +++ b/cpp/include/Ice/OutgoingAsync.h @@ -11,8 +11,10 @@ #define ICE_OUTGOING_ASYNC_H #include <IceUtil/Monitor.h> -#include <IceUtil/RecMutex.h> +#include <IceUtil/Mutex.h> +#include <IceUtil/Timer.h> #include <Ice/OutgoingAsyncF.h> +#include <Ice/InstanceF.h> #include <Ice/ReferenceF.h> #include <Ice/ConnectionIF.h> #include <Ice/Current.h> @@ -21,22 +23,43 @@ namespace IceInternal { class BasicStream; +class LocalExceptionWrapper; +class Outgoing; + +class ICE_API OutgoingAsyncMessageCallback : virtual public IceUtil::Shared +{ +public: + + virtual ~OutgoingAsyncMessageCallback() { } + + virtual void __sent(Ice::ConnectionI*) = 0; + virtual void __finished(const Ice::LocalException&) = 0; +}; // // We need virtual inheritance from shared, because the user might use // multiple inheritance from IceUtil::Shared. // -class ICE_API OutgoingAsync : virtual public IceUtil::Shared +class ICE_API OutgoingAsync : public OutgoingAsyncMessageCallback, public IceUtil::TimerTask { public: OutgoingAsync(); virtual ~OutgoingAsync(); + void __sent(Ice::ConnectionI*); + + BasicStream* + __getOs() + { + return __os; + } + virtual void ice_exception(const Ice::Exception&) = 0; void __finished(BasicStream&); void __finished(const Ice::LocalException&); + void __finished(const LocalExceptionWrapper&); protected: @@ -50,17 +73,51 @@ protected: private: + void runTimerTask(); // Implementation of TimerTask::runTimerTask() + void warning(const std::exception&) const; void warning() const; void cleanup(); + bool _sent; + bool _response; ::Ice::ObjectPrx _proxy; - ::IceInternal::Handle< ::IceDelegate::Ice::Object> _delegate; + Handle< ::IceDelegate::Ice::Object> _delegate; int _cnt; Ice::OperationMode _mode; - IceUtil::Monitor<IceUtil::RecMutex> _monitor; + Ice::ConnectionIPtr _timerTaskConnection; + IceUtil::Monitor<IceUtil::Mutex> _monitor; +}; + +class ICE_API BatchOutgoingAsync : public OutgoingAsyncMessageCallback +{ +public: + + BatchOutgoingAsync(); + + void __prepare(const InstancePtr&); + virtual void __sent(Ice::ConnectionI*); + virtual void __finished(const Ice::LocalException&); + + BasicStream* + __getOs() + { + return _os; + } + + virtual void ice_exception(const Ice::Exception&) = 0; + +private: + + void warning(const std::exception&) const; + void warning() const; + + void cleanup(); + + IceUtil::Monitor<IceUtil::Mutex> _monitor; + BasicStream* _os; }; } @@ -98,6 +155,15 @@ protected: virtual void __response(bool); }; +class ICE_API AMI_Object_ice_flushBatchRequests : public IceInternal::BatchOutgoingAsync +{ +public: + + void __invoke(const Ice::ObjectPrx&); + + virtual void ice_exception(const Ice::Exception&) = 0; +}; + } #endif diff --git a/cpp/include/Ice/OutgoingAsyncF.h b/cpp/include/Ice/OutgoingAsyncF.h index 21f9b5f4737..769c319db85 100644 --- a/cpp/include/Ice/OutgoingAsyncF.h +++ b/cpp/include/Ice/OutgoingAsyncF.h @@ -21,6 +21,14 @@ class OutgoingAsync; ICE_API IceUtil::Shared* upCast(OutgoingAsync*); typedef IceInternal::Handle<OutgoingAsync> OutgoingAsyncPtr; +class OutgoingAsyncMessageCallback; +ICE_API IceUtil::Shared* upCast(OutgoingAsyncMessageCallback*); +typedef IceInternal::Handle<OutgoingAsyncMessageCallback> OutgoingAsyncMessageCallbackPtr; + +class BatchOutgoingAsync; +ICE_API IceUtil::Shared* upCast(BatchOutgoingAsync*); +typedef IceInternal::Handle<BatchOutgoingAsync> BatchOutgoingAsyncPtr; + } namespace Ice @@ -28,6 +36,7 @@ namespace Ice class AMI_Object_ice_invoke; class AMI_Array_Object_ice_invoke; +class AMI_Object_ice_flushBatchRequests; } @@ -36,6 +45,7 @@ namespace IceInternal ICE_API IceUtil::Shared* upCast(::Ice::AMI_Object_ice_invoke*); ICE_API IceUtil::Shared* upCast(::Ice::AMI_Array_Object_ice_invoke*); +ICE_API IceUtil::Shared* upCast(::Ice::AMI_Object_ice_flushBatchRequests*); } @@ -44,6 +54,7 @@ namespace Ice typedef IceInternal::Handle<AMI_Object_ice_invoke> AMI_Object_ice_invokePtr; typedef IceInternal::Handle<AMI_Array_Object_ice_invoke> AMI_Array_Object_ice_invokePtr; +typedef IceInternal::Handle<AMI_Object_ice_flushBatchRequests> AMI_Object_ice_flushBatchRequestsPtr; } diff --git a/cpp/include/Ice/ProtocolPluginFacade.h b/cpp/include/Ice/ProtocolPluginFacade.h index 7228cba5b48..31ff388284f 100644 --- a/cpp/include/Ice/ProtocolPluginFacade.h +++ b/cpp/include/Ice/ProtocolPluginFacade.h @@ -15,6 +15,7 @@ #include <Ice/CommunicatorF.h> #include <Ice/EndpointFactoryF.h> #include <Ice/InstanceF.h> +#include <Ice/EndpointIF.h> namespace IceInternal { @@ -51,10 +52,20 @@ public: const char* getNetworkTraceCategory() const; // + // Get the endpoint host resolver. + // + EndpointHostResolverPtr getEndpointHostResolver() const; + + // // Register an EndpointFactory. // void addEndpointFactory(const EndpointFactoryPtr&) const; + // + // Get an EndpointFactory. + // + EndpointFactoryPtr getEndpointFactory(Ice::Short) const; + private: ProtocolPluginFacade(const Ice::CommunicatorPtr&); diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h index 2e2696b0c86..c3112addc6a 100644 --- a/cpp/include/Ice/Proxy.h +++ b/cpp/include/Ice/Proxy.h @@ -15,6 +15,7 @@ #include <Ice/ProxyF.h> #include <Ice/ProxyFactoryF.h> #include <Ice/ConnectionIF.h> +#include <Ice/RequestHandlerF.h> #include <Ice/EndpointIF.h> #include <Ice/Endpoint.h> #include <Ice/ObjectF.h> @@ -235,6 +236,9 @@ public: ::Ice::ConnectionPtr ice_getConnection(); ::Ice::ConnectionPtr ice_getCachedConnection() const; + void ice_flushBatchRequests(); + void ice_flushBatchRequests_async(const ::Ice::AMI_Object_ice_flushBatchRequestsPtr&); + ::IceInternal::ReferencePtr __reference() const; void __copyFrom(const ::Ice::ObjectPrx&); void __handleException(const ::IceInternal::Handle< ::IceDelegate::Ice::Object>&, @@ -246,7 +250,9 @@ public: void __checkTwowayOnly(const char*) const; void __checkTwowayOnly(const ::std::string&) const; - ::IceInternal::Handle< ::IceDelegate::Ice::Object> __getDelegate(); + ::IceInternal::Handle< ::IceDelegate::Ice::Object> __getDelegate(bool); + void __setRequestHandler(const ::IceInternal::Handle< ::IceDelegate::Ice::Object>&, + const ::IceInternal::RequestHandlerPtr&); protected: @@ -299,8 +305,10 @@ public: virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&, ::std::vector< ::Ice::Byte>&, const ::Ice::Context*) = 0; + virtual void ice_flushBatchRequests() = 0; - virtual ::Ice::ConnectionIPtr __getConnection(bool&) const = 0; + virtual ::IceInternal::RequestHandlerPtr __getRequestHandler() const = 0; + virtual void __setRequestHandler(const ::IceInternal::RequestHandlerPtr&) = 0; }; } } @@ -321,20 +329,20 @@ public: virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&, ::std::vector< ::Ice::Byte>&, const ::Ice::Context*); + virtual void ice_flushBatchRequests(); - virtual ::Ice::ConnectionIPtr __getConnection(bool&) const; + virtual ::IceInternal::RequestHandlerPtr __getRequestHandler() const; + virtual void __setRequestHandler(const ::IceInternal::RequestHandlerPtr&); void __copyFrom(const ::IceInternal::Handle< ::IceDelegateM::Ice::Object>&); protected: - ::IceInternal::ReferencePtr __reference; - ::Ice::ConnectionIPtr __connection; - bool __compress; + ::IceInternal::RequestHandlerPtr __handler; private: - void setup(const ::IceInternal::ReferencePtr&); + void setup(const ::IceInternal::ReferencePtr&, const ::Ice::ObjectPrx&, bool); friend class ::IceProxy::Ice::Object; }; @@ -354,8 +362,10 @@ public: virtual bool ice_invoke(const ::std::string&, ::Ice::OperationMode, const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&, ::std::vector< ::Ice::Byte>&, const ::Ice::Context*); + virtual void ice_flushBatchRequests(); - virtual ::Ice::ConnectionIPtr __getConnection(bool&) const; + virtual ::IceInternal::RequestHandlerPtr __getRequestHandler() const; + virtual void __setRequestHandler(const ::IceInternal::RequestHandlerPtr&); void __copyFrom(const ::IceInternal::Handle< ::IceDelegateD::Ice::Object>&); diff --git a/cpp/include/Ice/RequestHandlerF.h b/cpp/include/Ice/RequestHandlerF.h new file mode 100644 index 00000000000..ee313002dae --- /dev/null +++ b/cpp/include/Ice/RequestHandlerF.h @@ -0,0 +1,25 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_REQUEST_HANDLER_F_H +#define ICE_REQUEST_HANDLER_F_H + +#include <IceUtil/Shared.h> +#include <Ice/Handle.h> + +namespace IceInternal +{ + +class RequestHandler; +ICE_API IceUtil::Shared* upCast(RequestHandler*); +typedef IceInternal::Handle<RequestHandler> RequestHandlerPtr; + +} + +#endif diff --git a/cpp/include/IceUtil/Timer.h b/cpp/include/IceUtil/Timer.h index 246d87dcb7a..3725f9e4d46 100644 --- a/cpp/include/IceUtil/Timer.h +++ b/cpp/include/IceUtil/Timer.h @@ -25,7 +25,7 @@ class Timer; typedef IceUtil::Handle<Timer> TimerPtr; // -// Extend the TimerTask class and override the run() method to execute +// Extend the TimerTask class and override the runTimerTask() method to execute // code at a specific time or repeatedly. // class ICE_UTIL_API TimerTask : virtual public IceUtil::Shared @@ -34,9 +34,7 @@ public: virtual ~TimerTask() { } - virtual bool operator<(const TimerTask& r) const; - - virtual void run() = 0; + virtual void runTimerTask() = 0; }; typedef IceUtil::Handle<TimerTask> TimerTaskPtr; @@ -95,7 +93,17 @@ private: IceUtil::Monitor<IceUtil::Mutex> _monitor; bool _destroyed; std::set<Token> _tokens; - std::map<TimerTaskPtr, IceUtil::Time> _tasks; + + class TimerTaskCompare : public std::binary_function<TimerTaskPtr, TimerTaskPtr, bool> + { + public: + + bool operator()(const TimerTaskPtr& lhs, const TimerTaskPtr& rhs) const + { + return lhs.get() < rhs.get(); + } + }; + std::map<TimerTaskPtr, IceUtil::Time, TimerTaskCompare> _tasks; IceUtil::Time _wakeUpTime; }; typedef IceUtil::Handle<Timer> TimerPtr; @@ -118,7 +126,7 @@ Timer::Token::operator<(const Timer::Token& r) const return false; } - return task < r.task; + return task.get() < r.task.get(); } } diff --git a/cpp/src/Glacier2/Blobject.cpp b/cpp/src/Glacier2/Blobject.cpp index bc5995fb547..6ae716c5cfe 100644 --- a/cpp/src/Glacier2/Blobject.cpp +++ b/cpp/src/Glacier2/Blobject.cpp @@ -15,73 +15,77 @@ using namespace Glacier2; static const string serverForwardContext = "Glacier2.Server.ForwardContext"; static const string clientForwardContext = "Glacier2.Client.ForwardContext"; -static const string serverBuffered = "Glacier2.Server.Buffered"; -static const string clientBuffered = "Glacier2.Client.Buffered"; static const string serverAlwaysBatch = "Glacier2.Server.AlwaysBatch"; static const string clientAlwaysBatch = "Glacier2.Client.AlwaysBatch"; static const string serverTraceRequest = "Glacier2.Server.Trace.Request"; static const string clientTraceRequest = "Glacier2.Client.Trace.Request"; static const string serverTraceOverride = "Glacier2.Server.Trace.Override"; static const string clientTraceOverride = "Glacier2.Client.Trace.Override"; -static const string serverSleepTime = "Glacier2.Server.SleepTime"; -static const string clientSleepTime = "Glacier2.Client.SleepTime"; -Glacier2::Blobject::Blobject(const CommunicatorPtr& communicator, bool reverse, const Ice::Context& sslContext) : - _communicator(communicator), - _properties(_communicator->getProperties()), - _logger(_communicator->getLogger()), +namespace +{ + +class AMI_Array_Object_ice_invokeI : public AMI_Array_Object_ice_invoke +{ +public: + + AMI_Array_Object_ice_invokeI(const AMD_Array_Object_ice_invokePtr& amdCB) : + _amdCB(amdCB) + { + } + + virtual void + ice_response(bool ok, const pair<const Byte*, const Byte*>& outParams) + { + if(_amdCB) + { + _amdCB->ice_response(ok, outParams); + } + } + + virtual void + ice_exception(const Exception& ex) + { + if(_amdCB) + { + _amdCB->ice_exception(ex); + } + } + +private: + + const AMD_Array_Object_ice_invokePtr _amdCB; +}; + +} + +Glacier2::Blobject::Blobject(const InstancePtr& instance, bool reverse, const Ice::Context& sslContext) : + _instance(instance), _reverse(reverse), _forwardContext(_reverse ? - _properties->getPropertyAsInt(serverForwardContext) > 0 : - _properties->getPropertyAsInt(clientForwardContext) > 0), - _buffered(_reverse ? - _properties->getPropertyAsIntWithDefault(serverBuffered, 1) > 0 : - _properties->getPropertyAsIntWithDefault(clientBuffered, 1) > 0), + _instance->properties()->getPropertyAsInt(serverForwardContext) > 0 : + _instance->properties()->getPropertyAsInt(clientForwardContext) > 0), _alwaysBatch(_reverse ? - _properties->getPropertyAsInt(serverAlwaysBatch) > 0 : - _properties->getPropertyAsInt(clientAlwaysBatch) > 0), + _instance->properties()->getPropertyAsInt(serverAlwaysBatch) > 0 : + _instance->properties()->getPropertyAsInt(clientAlwaysBatch) > 0), _requestTraceLevel(_reverse ? - _properties->getPropertyAsInt(serverTraceRequest) : - _properties->getPropertyAsInt(clientTraceRequest)), + _instance->properties()->getPropertyAsInt(serverTraceRequest) : + _instance->properties()->getPropertyAsInt(clientTraceRequest)), _overrideTraceLevel(reverse ? - _properties->getPropertyAsInt(serverTraceOverride) : - _properties->getPropertyAsInt(clientTraceOverride)), + _instance->properties()->getPropertyAsInt(serverTraceOverride) : + _instance->properties()->getPropertyAsInt(clientTraceOverride)), _sslContext(sslContext) { - - if(_buffered) + RequestQueueThreadPtr t = _reverse ? _instance->serverRequestQueueThread() : _instance->clientRequestQueueThread(); + if(t) { - try + if(reverse) { - IceUtil::Time sleepTime = _reverse ? - IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(serverSleepTime)) : - IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(clientSleepTime)); - - const_cast<RequestQueuePtr&>(_requestQueue) = new RequestQueue(sleepTime); - - Int threadStackSize = _properties->getPropertyAsInt("Ice.ThreadPerConnection.StackSize"); - - _requestQueue->start(static_cast<size_t>(threadStackSize)); - - // - // See the comment in Glacier2::RequestQueue::destroy() - // for why we detach the thread. - // - _requestQueue->getThreadControl().detach(); + const_cast<RequestQueuePtr&>(_requestQueue) = new RequestQueue(t); } - catch(const IceUtil::Exception& ex) + else { - { - Error out(_logger); - out << "cannot create thread for request queue:\n" << ex; - } - - if(_requestQueue) - { - _requestQueue->destroy(); - } - - throw; + const_cast<RequestQueuePtr&>(_requestQueue) = new RequestQueue(t); } } } @@ -91,12 +95,6 @@ Glacier2::Blobject::~Blobject() } void -Glacier2::Blobject::destroy() -{ - _requestQueue->destroy(); -} - -void Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePtr& amdCB, const std::pair<const Ice::Byte*, const Ice::Byte*>& inParams, const Current& current) { @@ -114,7 +112,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt // if(current.requestId == 0) { - if(_alwaysBatch && _buffered) + if(_alwaysBatch && _requestQueue) { proxy = proxy->ice_batchOneway(); } @@ -147,7 +145,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt case 'o': { - if(_alwaysBatch && _buffered) + if(_alwaysBatch && _requestQueue) { proxy = proxy->ice_batchOneway(); } @@ -160,7 +158,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt case 'd': { - if(_alwaysBatch && _buffered) + if(_alwaysBatch && _requestQueue) { proxy = proxy->ice_batchDatagram(); } @@ -173,7 +171,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt case 'O': { - if(_buffered) + if(_requestQueue) { proxy = proxy->ice_batchOneway(); } @@ -186,7 +184,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt case 'D': { - if(_buffered) + if(_requestQueue) { proxy = proxy->ice_batchDatagram(); } @@ -211,7 +209,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt default: { - Warning out(_logger); + Warning out(_instance->logger()); out << "unknown forward option `" << option << "'"; break; } @@ -221,13 +219,13 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt if(_requestTraceLevel >= 1) { - Trace out(_logger, "Glacier2"); + Trace out(_instance->logger(), "Glacier2"); if(_reverse) { out << "reverse "; } out << "routing"; - if(_buffered) + if(_requestQueue) { out << " (buffered)"; } @@ -237,11 +235,11 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt } if(_reverse) { - out << "\nidentity = " << _communicator->identityToString(proxy->ice_getIdentity()); + out << "\nidentity = " << _instance->communicator()->identityToString(proxy->ice_getIdentity()); } else { - out << "\nproxy = " << _communicator->proxyToString(proxy); + out << "\nproxy = " << _instance->communicator()->proxyToString(proxy); } out << "\noperation = " << current.operation; out << "\ncontext = "; @@ -256,7 +254,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt } } - if(_buffered) + if(_requestQueue) { // // If we are in buffered mode, we create a new request and add @@ -278,7 +276,7 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt if(override && _overrideTraceLevel >= 1) { - Trace out(_logger, "Glacier2"); + Trace out(_instance->logger(), "Glacier2"); if(_reverse) { out << "reverse "; @@ -286,11 +284,11 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt out << "routing override"; if(_reverse) { - out << "\nidentity = " << _communicator->identityToString(proxy->ice_getIdentity()); + out << "\nidentity = " << _instance->communicator()->identityToString(proxy->ice_getIdentity()); } else { - out << "\nproxy = " << _communicator->proxyToString(proxy); + out << "\nproxy = " << _instance->communicator()->proxyToString(proxy); } out << "\noperation = " << current.operation; out << "\ncontext = "; @@ -311,48 +309,49 @@ Glacier2::Blobject::invoke(ObjectPrx& proxy, const AMD_Array_Object_ice_invokePt // If we are in not in buffered mode, we send the request // directly. // - - bool ok; - ByteSeq outParams; + assert(!proxy->ice_isBatchOneway() && !proxy->ice_isBatchDatagram()); try { + AMI_Array_Object_ice_invokePtr amiCB; + if(proxy->ice_isTwoway()) + { + amiCB = new AMI_Array_Object_ice_invokeI(amdCB); + } + else + { + amiCB = new AMI_Array_Object_ice_invokeI(0); + } + if(_forwardContext) { if(_sslContext.size() > 0) { Ice::Context ctx = current.ctx; ctx.insert(_sslContext.begin(), _sslContext.end()); - ok = proxy->ice_invoke(current.operation, current.mode, inParams, outParams, ctx); + proxy->ice_invoke_async(amiCB, current.operation, current.mode, inParams); } else { - ok = proxy->ice_invoke(current.operation, current.mode, inParams, outParams, current.ctx); + proxy->ice_invoke_async(amiCB, current.operation, current.mode, inParams, current.ctx); } } else { if(_sslContext.size() > 0) { - ok = proxy->ice_invoke(current.operation, current.mode, inParams, outParams, _sslContext); + proxy->ice_invoke_async(amiCB, current.operation, current.mode, inParams, _sslContext); } else { - ok = proxy->ice_invoke(current.operation, current.mode, inParams, outParams); + proxy->ice_invoke_async(amiCB, current.operation, current.mode, inParams); } } - pair<const Byte*, const Byte*> outPair; - if(outParams.size() == 0) - { - outPair.first = outPair.second = 0; - } - else + if(!proxy->ice_isTwoway()) { - outPair.first = &outParams[0]; - outPair.second = outPair.first + outParams.size(); + amdCB->ice_response(true, pair<const Byte*, const Byte*>(0, 0)); } - amdCB->ice_response(ok, outPair); } catch(const LocalException& ex) { diff --git a/cpp/src/Glacier2/Blobject.h b/cpp/src/Glacier2/Blobject.h index afda9383a7e..ab6ebf8b3ff 100644 --- a/cpp/src/Glacier2/Blobject.h +++ b/cpp/src/Glacier2/Blobject.h @@ -12,6 +12,7 @@ #include <Ice/Ice.h> #include <Glacier2/RequestQueue.h> +#include <Glacier2/Instance.h> namespace Glacier2 { @@ -20,25 +21,20 @@ class Blobject : public Ice::BlobjectArrayAsync { public: - Blobject(const Ice::CommunicatorPtr&, bool, const Ice::Context&); + Blobject(const InstancePtr&, bool, const Ice::Context&); virtual ~Blobject(); - virtual void destroy(); - protected: void invoke(Ice::ObjectPrx&, const Ice::AMD_Array_Object_ice_invokePtr&, const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); - const Ice::CommunicatorPtr _communicator; - const Ice::PropertiesPtr _properties; - const Ice::LoggerPtr _logger; + const InstancePtr _instance; private: const bool _reverse; const bool _forwardContext; - const bool _buffered; const bool _alwaysBatch; const int _requestTraceLevel; const int _overrideTraceLevel; diff --git a/cpp/src/Glacier2/ClientBlobject.cpp b/cpp/src/Glacier2/ClientBlobject.cpp index a1e32dca027..daf772c3c83 100644 --- a/cpp/src/Glacier2/ClientBlobject.cpp +++ b/cpp/src/Glacier2/ClientBlobject.cpp @@ -16,14 +16,14 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::ClientBlobject::ClientBlobject(const CommunicatorPtr& communicator, +Glacier2::ClientBlobject::ClientBlobject(const InstancePtr& instance, const FilterManagerPtr& filters, const Ice::Context& sslContext): - Glacier2::Blobject(communicator, false, sslContext), - _routingTable(new RoutingTable(communicator)), + Glacier2::Blobject(instance, false, sslContext), + _routingTable(new RoutingTable(_instance->communicator())), _filters(filters), - _rejectTraceLevel(_properties->getPropertyAsInt("Glacier2.Client.Trace.Reject")) + _rejectTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")) { } @@ -117,9 +117,9 @@ Glacier2::ClientBlobject::ice_invoke_async(const Ice::AMD_Array_Object_ice_invok { if(_rejectTraceLevel >= 1) { - Trace out(_logger, "Glacier2"); + Trace out(_instance->logger(), "Glacier2"); out << "rejecting request: " << rejectedFilters << "\n"; - out << "identity: " << _communicator->identityToString(current.id); + out << "identity: " << _instance->communicator()->identityToString(current.id); } ObjectNotExistException ex(__FILE__, __LINE__); diff --git a/cpp/src/Glacier2/ClientBlobject.h b/cpp/src/Glacier2/ClientBlobject.h index 5385a0f2c0b..62824646190 100644 --- a/cpp/src/Glacier2/ClientBlobject.h +++ b/cpp/src/Glacier2/ClientBlobject.h @@ -31,7 +31,7 @@ class ClientBlobject : public Glacier2::Blobject { public: - ClientBlobject(const Ice::CommunicatorPtr&, const FilterManagerPtr&, const Ice::Context&); + ClientBlobject(const InstancePtr&, const FilterManagerPtr&, const Ice::Context&); virtual ~ClientBlobject(); virtual void ice_invoke_async(const Ice::AMD_Array_Object_ice_invokePtr&, diff --git a/cpp/src/Glacier2/FilterManager.cpp b/cpp/src/Glacier2/FilterManager.cpp index 48112725aa6..079dd964b14 100755 --- a/cpp/src/Glacier2/FilterManager.cpp +++ b/cpp/src/Glacier2/FilterManager.cpp @@ -109,13 +109,14 @@ Glacier2::FilterManager::~FilterManager() void Glacier2::FilterManager::destroy() { - if(_adapter) + Ice::ObjectAdapterPtr adapter = _instance->serverObjectAdapter(); + if(adapter) { try { if(_categoriesPrx) { - _adapter->remove(_categoriesPrx->ice_getIdentity()); + adapter->remove(_categoriesPrx->ice_getIdentity()); } } catch(const Exception&) @@ -125,7 +126,7 @@ Glacier2::FilterManager::destroy() { if(_adapterIdsPrx) { - _adapter->remove(_adapterIdsPrx->ice_getIdentity()); + adapter->remove(_adapterIdsPrx->ice_getIdentity()); } } catch(const Exception&) @@ -135,7 +136,7 @@ Glacier2::FilterManager::destroy() { if(_identitiesPrx) { - _adapter->remove(_identitiesPrx->ice_getIdentity()); + adapter->remove(_identitiesPrx->ice_getIdentity()); } } catch(const Exception&) @@ -144,21 +145,22 @@ Glacier2::FilterManager::destroy() } } -Glacier2::FilterManager::FilterManager(const ObjectAdapterPtr& adapter, const Glacier2::StringSetIPtr& categories, +Glacier2::FilterManager::FilterManager(const InstancePtr& instance, const Glacier2::StringSetIPtr& categories, const Glacier2::StringSetIPtr& adapters, const Glacier2::IdentitySetIPtr& identities) : _categories(categories), _adapters(adapters), _identities(identities), - _adapter(adapter) + _instance(instance) { try { - if(_adapter) + Ice::ObjectAdapterPtr adapter = _instance->serverObjectAdapter(); + if(adapter) { - _categoriesPrx = Glacier2::StringSetPrx::uncheckedCast(_adapter->addWithUUID(_categories)); - _adapterIdsPrx = Glacier2::StringSetPrx::uncheckedCast(_adapter->addWithUUID(_adapters)); - _identitiesPrx = Glacier2::IdentitySetPrx::uncheckedCast(_adapter->addWithUUID(_identities)); + _categoriesPrx = Glacier2::StringSetPrx::uncheckedCast(adapter->addWithUUID(_categories)); + _adapterIdsPrx = Glacier2::StringSetPrx::uncheckedCast(adapter->addWithUUID(_adapters)); + _identitiesPrx = Glacier2::IdentitySetPrx::uncheckedCast(adapter->addWithUUID(_identities)); } } catch(...) @@ -169,10 +171,9 @@ Glacier2::FilterManager::FilterManager(const ObjectAdapterPtr& adapter, const Gl } Glacier2::FilterManager* -Glacier2::FilterManager::create(const CommunicatorPtr& communicator, const ObjectAdapterPtr& adapter, const string& userId, - const bool allowAddUser) +Glacier2::FilterManager::create(const InstancePtr& instance, const string& userId, const bool allowAddUser) { - PropertiesPtr props = communicator->getProperties(); + PropertiesPtr props = instance->properties(); string allow = props->getProperty("Glacier2.Filter.Category.Accept"); vector<string> allowSeq; stringToSeq(allow, allowSeq); @@ -211,8 +212,8 @@ Glacier2::FilterManager::create(const CommunicatorPtr& communicator, const Objec // IdentitySeq allowIdSeq; allow = props->getProperty("Glacier2.Filter.Identity.Accept"); - stringToSeq(communicator, allow, allowIdSeq); + stringToSeq(instance->communicator(), allow, allowIdSeq); Glacier2::IdentitySetIPtr identityFilter = new Glacier2::IdentitySetI(allowIdSeq); - return new Glacier2::FilterManager(adapter, categoryFilter, adapterIdFilter, identityFilter); + return new Glacier2::FilterManager(instance, categoryFilter, adapterIdFilter, identityFilter); } diff --git a/cpp/src/Glacier2/FilterManager.h b/cpp/src/Glacier2/FilterManager.h index 71881846e81..db74035f80d 100755 --- a/cpp/src/Glacier2/FilterManager.h +++ b/cpp/src/Glacier2/FilterManager.h @@ -14,6 +14,7 @@ // It'd be better if we didn't have to include this everywhere, but // this is the most expeditious approach for now. // +#include <Glacier2/Instance.h> #include <Glacier2/FilterI.h> #include <Ice/ObjectAdapter.h> @@ -67,7 +68,7 @@ public: } static FilterManager* - create(const Ice::CommunicatorPtr&, const Ice::ObjectAdapterPtr&, const std::string&, const bool); + create(const InstancePtr&, const std::string&, const bool); private: @@ -78,9 +79,9 @@ private: const StringSetIPtr _categories; const StringSetIPtr _adapters; const IdentitySetIPtr _identities; - const Ice::ObjectAdapterPtr _adapter; + const InstancePtr _instance; - FilterManager(const Ice::ObjectAdapterPtr& , const StringSetIPtr&, const StringSetIPtr&, const IdentitySetIPtr&); + FilterManager(const InstancePtr& , const StringSetIPtr&, const StringSetIPtr&, const IdentitySetIPtr&); }; }; diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp index 9cbeadab7a6..6745551c474 100644 --- a/cpp/src/Glacier2/Glacier2Router.cpp +++ b/cpp/src/Glacier2/Glacier2Router.cpp @@ -11,6 +11,7 @@ #include <IceUtil/UUID.h> #include <IceUtil/Options.h> #include <Ice/Service.h> +#include <Glacier2/Instance.h> #include <Glacier2/RouterI.h> #include <Glacier2/Session.h> #include <Glacier2/SessionRouterI.h> @@ -60,6 +61,7 @@ private: void usage(const std::string&); + InstancePtr _instance; SessionRouterIPtr _sessionRouter; }; @@ -428,12 +430,16 @@ Glacier2::RouterService::start(int argc, char* argv[]) } // + // Create the instance object. + // + _instance = new Instance(communicator(), clientAdapter, serverAdapter); + + // // Create the session router. The session router registers itself // and all required servant locators, so no registration has to be // done here. // - _sessionRouter = new SessionRouterI(clientAdapter, serverAdapter, verifier, sessionManager, sslVerifier, - sslSessionManager); + _sessionRouter = new SessionRouterI(_instance, verifier, sessionManager, sslVerifier, sslSessionManager); // // If we have an admin adapter, we add an admin object. @@ -482,6 +488,12 @@ Glacier2::RouterService::stop() _sessionRouter->destroy(); _sessionRouter = 0; } + + if(_instance) + { + _instance->destroy(); + _instance = 0; + } return true; } @@ -493,11 +505,6 @@ Glacier2::RouterService::initializeCommunicator(int& argc, char* argv[], initData.properties = createProperties(argc, argv, initializationData.properties); // - // Glacier2 always runs in thread-per-connection mode. - // - initData.properties->setProperty("Ice.ThreadPerConnection", "1"); - - // // Make sure that Glacier2 doesn't use a router. // initData.properties->setProperty("Ice.Default.Router", ""); @@ -508,17 +515,6 @@ Glacier2::RouterService::initializeCommunicator(int& argc, char* argv[], // initData.properties->setProperty("Ice.ACM.Client", "0"); initData.properties->setProperty("Ice.ACM.Server", "0"); - - // - // Ice.MonitorConnections defaults to the smaller of Ice.ACM.Client - // or Ice.ACM.Server, which we set to 0 above. However, we still want - // the connection monitor thread for AMI timeouts. We only set - // this value if it hasn't been set explicitly already. - // - if(initData.properties->getProperty("Ice.MonitorConnections").empty()) - { - initData.properties->setProperty("Ice.MonitorConnections", "60"); - } // // We do not need to set Ice.RetryIntervals to -1, i.e., we do diff --git a/cpp/src/Glacier2/Instance.cpp b/cpp/src/Glacier2/Instance.cpp new file mode 100644 index 00000000000..00f3042d401 --- /dev/null +++ b/cpp/src/Glacier2/Instance.cpp @@ -0,0 +1,59 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Glacier2/Instance.h> + +using namespace std; +using namespace Glacier2; + +static const string serverSleepTime = "Glacier2.Server.SleepTime"; +static const string clientSleepTime = "Glacier2.Client.SleepTime"; +static const string serverBuffered = "Glacier2.Server.Buffered"; +static const string clientBuffered = "Glacier2.Client.Buffered"; + +Glacier2::Instance::Instance(const Ice::CommunicatorPtr& communicator, const Ice::ObjectAdapterPtr& clientAdapter, + const Ice::ObjectAdapterPtr& serverAdapter) : + _communicator(communicator), + _properties(communicator->getProperties()), + _logger(communicator->getLogger()), + _clientAdapter(clientAdapter), + _serverAdapter(serverAdapter) +{ + if(_properties->getPropertyAsIntWithDefault(serverBuffered, 1) > 0) + { + IceUtil::Time sleepTime = IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(serverSleepTime)); + const_cast<RequestQueueThreadPtr&>(_serverRequestQueueThread) = new RequestQueueThread(sleepTime); + _serverRequestQueueThread->start(); + } + + if(_properties->getPropertyAsIntWithDefault(clientBuffered, 1) > 0) + { + IceUtil::Time sleepTime = IceUtil::Time::milliSeconds(_properties->getPropertyAsInt(clientSleepTime)); + const_cast<RequestQueueThreadPtr&>(_clientRequestQueueThread) = new RequestQueueThread(sleepTime); + _clientRequestQueueThread->start(); + } +} + +Glacier2::Instance::~Instance() +{ +} + +void +Glacier2::Instance::destroy() +{ + if(_clientRequestQueueThread) + { + _clientRequestQueueThread->destroy(); + } + + if(_serverRequestQueueThread) + { + _serverRequestQueueThread->destroy(); + } +} diff --git a/cpp/src/Glacier2/Instance.h b/cpp/src/Glacier2/Instance.h new file mode 100644 index 00000000000..dbe05d48e56 --- /dev/null +++ b/cpp/src/Glacier2/Instance.h @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef GLACIER2_INSTANCE_H +#define GLACIER2_INSTANCE_H + +#include <Ice/CommunicatorF.h> +#include <Ice/ObjectAdapterF.h> +#include <Ice/PropertiesF.h> +#include <IceUtil/Time.h> + +#include <Glacier2/RequestQueue.h> + +namespace Glacier2 +{ + +class Instance : public IceUtil::Shared +{ +public: + + Instance(const Ice::CommunicatorPtr&, const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&); + ~Instance(); + + Ice::CommunicatorPtr communicator() const { return _communicator; } + Ice::ObjectAdapterPtr clientObjectAdapter() const { return _clientAdapter; } + Ice::ObjectAdapterPtr serverObjectAdapter() const { return _serverAdapter; } + Ice::PropertiesPtr properties() const { return _properties; } + Ice::LoggerPtr logger() const { return _logger; } + + RequestQueueThreadPtr clientRequestQueueThread() const { return _clientRequestQueueThread; } + RequestQueueThreadPtr serverRequestQueueThread() const { return _serverRequestQueueThread; } + + void destroy(); + +private: + + const Ice::CommunicatorPtr _communicator; + const Ice::PropertiesPtr _properties; + const Ice::LoggerPtr _logger; + const Ice::ObjectAdapterPtr _clientAdapter; + const Ice::ObjectAdapterPtr _serverAdapter; + const RequestQueueThreadPtr _clientRequestQueueThread; + const RequestQueueThreadPtr _serverRequestQueueThread; +}; +typedef IceUtil::Handle<Instance> InstancePtr; + +} // End namespace Glacier2 + +#endif diff --git a/cpp/src/Glacier2/Makefile b/cpp/src/Glacier2/Makefile index 07f73a0be00..fab4fe99ae5 100644 --- a/cpp/src/Glacier2/Makefile +++ b/cpp/src/Glacier2/Makefile @@ -27,6 +27,7 @@ ROBJS = Blobject.o \ ClientBlobject.o \ CryptPermissionsVerifierI.o \ Glacier2Router.o \ + Instance.o \ ProxyVerifier.o \ RequestQueue.o \ RouterI.o \ diff --git a/cpp/src/Glacier2/Makefile.mak b/cpp/src/Glacier2/Makefile.mak index 8eda88543f4..88ed24437df 100644 --- a/cpp/src/Glacier2/Makefile.mak +++ b/cpp/src/Glacier2/Makefile.mak @@ -33,6 +33,7 @@ ROBJS = Blobject.obj \ ClientBlobject.obj \ CryptPermissionsVerifierI.obj \ Glacier2Router.obj \ + Instance.obj \ ProxyVerifier.obj \ RequestQueue.obj \ RouterI.obj \ diff --git a/cpp/src/Glacier2/RequestQueue.cpp b/cpp/src/Glacier2/RequestQueue.cpp index 399884cf2f2..e508fa1ad51 100644 --- a/cpp/src/Glacier2/RequestQueue.cpp +++ b/cpp/src/Glacier2/RequestQueue.cpp @@ -14,43 +14,40 @@ using namespace std; using namespace Ice; using namespace Glacier2; -namespace Glacier2 +namespace { // // AMI callback class for twoway requests // -// NOTE: the received response isn't sent back directly with the AMD -// callback. Instead it's queued and the request queue thread is -// responsible for sending back the response. It's necessary because -// sending back the response might block. -// class AMI_Array_Object_ice_invokeI : public AMI_Array_Object_ice_invoke { public: - - AMI_Array_Object_ice_invokeI(const RequestQueuePtr& requestQueue, const AMD_Array_Object_ice_invokePtr& amdCB) : - _requestQueue(requestQueue), - _amdCB(amdCB) + + AMI_Array_Object_ice_invokeI(const AMD_Array_Object_ice_invokePtr& amdCB) : _amdCB(amdCB) { - assert(_amdCB); } - + virtual void ice_response(bool ok, const pair<const Byte*, const Byte*>& outParams) { - _requestQueue->addResponse(new Response(_amdCB, ok, outParams)); + if(_amdCB) + { + _amdCB->ice_response(ok, outParams); + } } virtual void ice_exception(const Exception& ex) { - _requestQueue->addResponse(new Response(_amdCB, ex)); + if(_amdCB) + { + _amdCB->ice_exception(ex); + } } private: - const RequestQueuePtr _requestQueue; const AMD_Array_Object_ice_invokePtr _amdCB; }; @@ -72,9 +69,7 @@ Glacier2::Request::Request(const ObjectPrx& proxy, const std::pair<const Byte*, // if(!_proxy->ice_isTwoway()) { - bool ok = true; - pair<const Byte*, const Byte*> outParams(0, 0); - _amdCB->ice_response(ok, outParams); + _amdCB->ice_response(true, pair<const Byte*, const Byte*>(0, 0)); } Context::const_iterator p = current.ctx.find("_ovrd"); @@ -86,7 +81,7 @@ Glacier2::Request::Request(const ObjectPrx& proxy, const std::pair<const Byte*, bool -Glacier2::Request::invoke(const RequestQueuePtr& requestQueue) +Glacier2::Request::invoke() { pair<const Byte*, const Byte*> inPair; if(_inParams.size() == 0) @@ -98,69 +93,73 @@ Glacier2::Request::invoke(const RequestQueuePtr& requestQueue) inPair.first = &_inParams[0]; inPair.second = inPair.first + _inParams.size(); } - if(_proxy->ice_isTwoway()) + + if(_proxy->ice_isBatchOneway() || _proxy->ice_isBatchDatagram()) { - AMI_Array_Object_ice_invokePtr cb = new AMI_Array_Object_ice_invokeI(requestQueue, _amdCB); + ByteSeq outParams; if(_forwardContext) - { + { if(_sslContext.size() > 0) { Ice::Context ctx = _current.ctx; ctx.insert(_sslContext.begin(), _sslContext.end()); - _proxy->ice_invoke_async(cb, _current.operation, _current.mode, inPair, ctx); + _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, ctx); } else { - _proxy->ice_invoke_async(cb, _current.operation, _current.mode, inPair, _current.ctx); + _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _current.ctx); } } else { if(_sslContext.size() > 0) { - _proxy->ice_invoke_async(cb, _current.operation, _current.mode, inPair, _sslContext); + _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _sslContext); } else { - _proxy->ice_invoke_async(cb, _current.operation, _current.mode, inPair); + _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams); } } - return true; // A twoway method is being dispatched. + return true; // Batch invocation. } else { - try + AMI_Array_Object_ice_invokePtr amiCB; + if(_proxy->ice_isTwoway()) + { + amiCB = new AMI_Array_Object_ice_invokeI(_amdCB); + } + else { - ByteSeq outParams; - if(_forwardContext) + amiCB = new AMI_Array_Object_ice_invokeI(0); + } + + if(_forwardContext) + { + if(_sslContext.size() > 0) { - if(_sslContext.size() > 0) - { - Ice::Context ctx = _current.ctx; - ctx.insert(_sslContext.begin(), _sslContext.end()); - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, ctx); - } - else - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _current.ctx); - } + Ice::Context ctx = _current.ctx; + ctx.insert(_sslContext.begin(), _sslContext.end()); + _proxy->ice_invoke_async(amiCB, _current.operation, _current.mode, inPair, ctx); } else { - if(_sslContext.size() > 0) - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams, _sslContext); - } - else - { - _proxy->ice_invoke(_current.operation, _current.mode, inPair, outParams); - } + _proxy->ice_invoke_async(amiCB, _current.operation, _current.mode, inPair, _current.ctx); } } - catch(const LocalException&) + else { + if(_sslContext.size() > 0) + { + _proxy->ice_invoke_async(amiCB, _current.operation, _current.mode, inPair, _sslContext); + } + else + { + _proxy->ice_invoke_async(amiCB, _current.operation, _current.mode, inPair); + } } - return false; + return false; // Not a batch invocation. } } @@ -195,74 +194,68 @@ Glacier2::Request::override(const RequestPtr& other) const return _override == other->_override; } -bool -Glacier2::Request::isBatch() const -{ - return _proxy->ice_isBatchOneway() || _proxy->ice_isBatchDatagram(); -} - -ConnectionPtr -Glacier2::Request::getConnection() const -{ - return _proxy->ice_getConnection(); -} - -Glacier2::Response::Response(const AMD_Array_Object_ice_invokePtr& amdCB, bool ok, - const pair<const Byte*, const Byte*>& outParams) : - _amdCB(amdCB), - _ok(ok), - _outParams(outParams.first, outParams.second) +Glacier2::RequestQueue::RequestQueue(const RequestQueueThreadPtr& requestQueueThread) : + _requestQueueThread(requestQueueThread) { } -Glacier2::Response::Response(const AMD_Array_Object_ice_invokePtr& amdCB, const Exception& ex) : - _amdCB(amdCB), - _ok(false), - _exception(ex.ice_clone()) +bool +Glacier2::RequestQueue::addRequest(const RequestPtr& request) { + IceUtil::Mutex::Lock lock(*this); + for(vector<RequestPtr>::iterator p = _requests.begin(); p != _requests.end(); ++p) + { + // + // If the new request overrides an old one, then abort the old + // request and replace it with the new request. + // + if(request->override(*p)) + { + *p = request; + return true; + } + } + + // + // No override, we add the new request. + // + if(_requests.empty()) + { + _requestQueueThread->flushRequestQueue(this); // This might throw if the thread is destroyed. + } + _requests.push_back(request); + return false; } void -Glacier2::Response::invoke() +Glacier2::RequestQueue::flushRequests(set<Ice::ObjectPrx>& batchProxies) { - if(_exception.get()) + IceUtil::Mutex::Lock lock(*this); + for(vector<RequestPtr>::const_iterator p = _requests.begin(); p != _requests.end(); ++p) { - _amdCB->ice_exception(*_exception.get()); - } - else - { - pair<const Byte*, const Byte*> outPair; - if(_outParams.size() == 0) - { - outPair.first = outPair.second = 0; - } - else + if((*p)->invoke()) // If batch invocation, add the proxy to the batch proxy set. { - outPair.first = &_outParams[0]; - outPair.second = outPair.first + _outParams.size(); + batchProxies.insert((*p)->getProxy()); } - _amdCB->ice_response(_ok, outPair); } + _requests.clear(); } -Glacier2::RequestQueue::RequestQueue(const IceUtil::Time& sleepTime) : +Glacier2::RequestQueueThread::RequestQueueThread(const IceUtil::Time& sleepTime) : _sleepTime(sleepTime), _destroy(false), _sleep(false) { } -Glacier2::RequestQueue::~RequestQueue() +Glacier2::RequestQueueThread::~RequestQueueThread() { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - assert(_destroy); - assert(_requests.empty()); - assert(_responses.empty()); + assert(_queues.empty()); } void -Glacier2::RequestQueue::destroy() +Glacier2::RequestQueueThread::destroy() { { IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); @@ -273,82 +266,42 @@ Glacier2::RequestQueue::destroy() notify(); } - // - // We don't want to wait for the RequestQueue thread, because this - // destroy() operation is called when sessions expire or are - // destroyed, in which case we do not want the session handler - // thread to block here. Therefore we don't call join(), but - // instead detach the thread right after we start it. - // - //getThreadControl().join(); + getThreadControl().join(); } -bool -Glacier2::RequestQueue::addRequest(const RequestPtr& request) +void +Glacier2::RequestQueueThread::flushRequestQueue(const RequestQueuePtr& queue) { IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - if(_destroy) { - throw ObjectNotExistException(__FILE__, __LINE__); - } - - for(vector<RequestPtr>::iterator p = _requests.begin(); p != _requests.end(); ++p) - { - // - // If the new request overrides an old one, then abort the old - // request and replace it with the new request. - // - if(request->override(*p)) - { - *p = request; - return true; - } + throw Ice::ObjectNotExistException(__FILE__, __LINE__); } - // - // No override, we add the new request. - // - _requests.push_back(request); - if(!_sleep) + if(_queues.empty() && !_sleep) { - // - // No need to notify if the request queue thread is sleeping, - // once it wakes up it will check if there's requests to send. - // notify(); } - return false; + _queues.push_back(queue); } void -Glacier2::RequestQueue::addResponse(const ResponsePtr& response) +Glacier2::RequestQueueThread::run() { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - _responses.push_back(response); - notify(); -} - -void -Glacier2::RequestQueue::run() -{ - RequestQueuePtr self = this; // This is to avoid creating a temporary Ptr for each call to Request::invoke() - ptrdiff_t dispatchCount = 0; // The dispatch count keeps track of the number of outstanding twoway requests. while(true) { - vector<RequestPtr> requests; - vector<ResponsePtr> responses; + vector<RequestQueuePtr> queues; { IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); // - // Wait indefinitely if there's no requests/responses to + // Wait indefinitely if there's no requests to // send. If the queue is being destroyed we still need to // wait until all the responses for twoway requests are // received. // - while((!_destroy || dispatchCount != 0) && _responses.empty() && (_requests.empty() || _sleep)) + while(!_destroy && (_queues.empty() || _sleep)) { if(_sleep) { @@ -361,6 +314,7 @@ Glacier2::RequestQueue::run() { _sleepDuration -= IceUtil::Time::now(IceUtil::Time::Monotonic) - now; } + if(_sleepDuration <= IceUtil::Time()) { _sleep = false; @@ -373,90 +327,54 @@ Glacier2::RequestQueue::run() } // - // If the queue is being destroyed and there's no requests - // or responses to send, we're done. + // If the queue is being destroyed and there's no requests or responses + // to send, we're done. // - if(_destroy && _requests.empty() && _responses.empty()) + if(_destroy && _queues.empty()) { - assert(dispatchCount == 0); // We would have blocked in the wait() above otherwise. return; } - // - // If there's requests to sent and we're not sleeping, - // send the requests. If a sleep time is configured, we - // set the sleep duration and set the sleep flag to make - // sure we'll sleep again once we're done sending requests - // and responses. - // - if(!_requests.empty() && !_sleep) - { - requests.swap(_requests); - if(_sleepTime > IceUtil::Time()) - { - _sleep = true; - _sleepDuration = _sleepTime; - } - } - if(!_responses.empty()) + assert(!_queues.empty() && !_sleep); + + queues.swap(_queues); + + if(_sleepTime > IceUtil::Time()) { - responses.swap(_responses); + _sleep = true; + _sleepDuration = _sleepTime; } } - // - // Send requests, flush batch requests, and sleep outside the - // thread synchronization, so that new messages can be added - // while this is being done. - // + set<Ice::ObjectPrx> flushProxySet; + for(vector<RequestQueuePtr>::const_iterator p = queues.begin(); p != queues.end(); ++p) + { + (*p)->flushRequests(flushProxySet); + } - set<ConnectionPtr> flushSet; - - for(vector<RequestPtr>::const_iterator p = requests.begin(); p != requests.end(); ++p) + set<Ice::ConnectionPtr> flushConnectionSet; + for(set<Ice::ObjectPrx>::const_iterator q = flushProxySet.begin(); q != flushProxySet.end(); ++q) { - if((*p)->isBatch()) - { - try - { - flushSet.insert((*p)->getConnection()); - } - catch(const LocalException&) - { - // Ignore. - } - } - // - // Invoke returns true if the request expects a response. - // If that's the case we increment the dispatch count to - // ensure that the thread won't be destroyed before the - // response is received. + // As an optimization, we only flush the proxy batch requests if we didn't + // already flush the requests of a proxy which is using the same connection. // - if((*p)->invoke(self)) // Exceptions are caught within invoke(). + Ice::ConnectionPtr connection = (*q)->ice_getCachedConnection(); + if(!connection || flushConnectionSet.find(connection) == flushConnectionSet.end()) { - ++dispatchCount; - } - } + class FlushCB : public AMI_Object_ice_flushBatchRequests + { + public: - for(set<ConnectionPtr>::const_iterator q = flushSet.begin(); q != flushSet.end(); ++q) - { - try - { - (*q)->flushBatchRequests(); - } - catch(const LocalException&) - { - // Ignore. - } - } + virtual void ice_exception(const Ice::Exception&) { } // Ignore. + }; + (*q)->ice_flushBatchRequests_async(new FlushCB()); - // - // Send the responses and decrement the dispatch count. - // - for(vector<ResponsePtr>::const_iterator r = responses.begin(); r != responses.end(); ++r) - { - (*r)->invoke(); + if(connection) + { + flushConnectionSet.insert(connection); + } + } } - dispatchCount -= responses.size(); } } diff --git a/cpp/src/Glacier2/RequestQueue.h b/cpp/src/Glacier2/RequestQueue.h index 2599b24f7aa..1ecba68e343 100644 --- a/cpp/src/Glacier2/RequestQueue.h +++ b/cpp/src/Glacier2/RequestQueue.h @@ -20,8 +20,8 @@ namespace Glacier2 class Request; typedef IceUtil::Handle<Request> RequestPtr; -class RequestQueue; -typedef IceUtil::Handle<RequestQueue> RequestQueuePtr; +class RequestQueueThread; +typedef IceUtil::Handle<RequestQueueThread> RequestQueueThreadPtr; class Request : public IceUtil::Shared { @@ -30,10 +30,9 @@ public: Request(const Ice::ObjectPrx&, const std::pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&, bool, const Ice::Context&, const Ice::AMD_Array_Object_ice_invokePtr&); - bool invoke(const RequestQueuePtr&); + bool invoke(); bool override(const RequestPtr&) const; - bool isBatch() const; - Ice::ConnectionPtr getConnection() const; + const Ice::ObjectPrx& getProxy() const { return _proxy; } private: @@ -46,47 +45,42 @@ private: const Ice::AMD_Array_Object_ice_invokePtr _amdCB; }; -class Response : public IceUtil::Shared +class RequestQueue : public IceUtil::Mutex, public IceUtil::Shared { public: - Response(const Ice::AMD_Array_Object_ice_invokePtr&, bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&); - Response(const Ice::AMD_Array_Object_ice_invokePtr&, const Ice::Exception&); + RequestQueue(const RequestQueueThreadPtr&); - void invoke(); - -private: + bool addRequest(const RequestPtr&); + void flushRequests(std::set<Ice::ObjectPrx>&); - const Ice::AMD_Array_Object_ice_invokePtr _amdCB; - const bool _ok; - const Ice::ByteSeq _outParams; - const std::auto_ptr<Ice::Exception> _exception; +private: + + const RequestQueueThreadPtr _requestQueueThread; + std::vector<RequestPtr> _requests; }; +typedef IceUtil::Handle<RequestQueue> RequestQueuePtr; -class Response; -typedef IceUtil::Handle<Response> ResponsePtr; -class RequestQueue : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> +class RequestQueueThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> { public: - RequestQueue(const IceUtil::Time&); - virtual ~RequestQueue(); - + RequestQueueThread(const IceUtil::Time&); + virtual ~RequestQueueThread(); + + void flushRequestQueue(const RequestQueuePtr&); void destroy(); - bool addRequest(const RequestPtr&); - void addResponse(const ResponsePtr&); virtual void run(); private: const IceUtil::Time _sleepTime; - std::vector<RequestPtr> _requests; - std::vector<ResponsePtr> _responses; bool _destroy; bool _sleep; IceUtil::Time _sleepDuration; + std::vector<RequestQueuePtr> _queues; }; } diff --git a/cpp/src/Glacier2/RouterI.cpp b/cpp/src/Glacier2/RouterI.cpp index ee6dde8edd4..07431ee0389 100644 --- a/cpp/src/Glacier2/RouterI.cpp +++ b/cpp/src/Glacier2/RouterI.cpp @@ -18,13 +18,11 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::RouterI::RouterI(const ObjectAdapterPtr& clientAdapter, const ObjectAdapterPtr& serverAdapter, - const ConnectionPtr& connection, const string& userId, const SessionPrx& session, - const Identity& controlId, const FilterManagerPtr& filters, +Glacier2::RouterI::RouterI(const InstancePtr& instance, const ConnectionPtr& connection, const string& userId, + const SessionPrx& session, const Identity& controlId, const FilterManagerPtr& filters, const Ice::Context& sslContext) : - _communicator(clientAdapter->getCommunicator()), - _clientBlobject(new ClientBlobject(_communicator, filters, sslContext)), - _serverAdapter(serverAdapter), + _instance(instance), + _clientBlobject(new ClientBlobject(_instance, filters, sslContext)), _connection(connection), _userId(userId), _session(session), @@ -36,13 +34,13 @@ Glacier2::RouterI::RouterI(const ObjectAdapterPtr& clientAdapter, const ObjectAd // If Glacier2 will be used with pre 3.2 clients, then the client proxy must be set. // Otherwise getClientProxy just needs to return a nil proxy. // - if(_communicator->getProperties()->getPropertyAsInt("Glacier2.ReturnClientProxy") > 0) + if(_instance->properties()->getPropertyAsInt("Glacier2.ReturnClientProxy") > 0) { const_cast<Ice::ObjectPrx&>(_clientProxy) = - clientAdapter->createProxy(_communicator->stringToIdentity("dummy")); + _instance->clientObjectAdapter()->createProxy(_instance->communicator()->stringToIdentity("dummy")); } - if(serverAdapter) + if(_instance->serverObjectAdapter()) { ObjectPrx& serverProxy = const_cast<ObjectPrx&>(_serverProxy); Identity ident; @@ -55,10 +53,10 @@ Glacier2::RouterI::RouterI(const ObjectAdapterPtr& clientAdapter, const ObjectAd const unsigned char c = static_cast<unsigned char>(buf[i]); // A value between 0-255 ident.category[i] = 33 + c % (127-33); // We use ASCII 33-126 (from ! to ~, w/o space). } - serverProxy = serverAdapter->createProxy(ident); + serverProxy = _instance->serverObjectAdapter()->createProxy(ident); ServerBlobjectPtr& serverBlobject = const_cast<ServerBlobjectPtr&>(_serverBlobject); - serverBlobject = new ServerBlobject(_communicator, _connection); + serverBlobject = new ServerBlobject(_instance, _connection); } } @@ -67,27 +65,20 @@ Glacier2::RouterI::~RouterI() } void -Glacier2::RouterI::destroy() +Glacier2::RouterI::destroy(const AMI_Session_destroyPtr& amiCB) { _connection->close(true); - _clientBlobject->destroy(); - - if(_serverBlobject) - { - _serverBlobject->destroy(); - } - if(_session) { - if(_serverAdapter) + if(_instance->serverObjectAdapter()) { try { // // Remove the session control object. // - _serverAdapter->remove(_controlId); + _instance->serverObjectAdapter()->remove(_controlId); } catch(const NotRegisteredException&) { @@ -100,17 +91,13 @@ Glacier2::RouterI::destroy() } } - // - // This can raise an exception, therefore it must be the last - // statement in this destroy() function. - // if(_sslContext.size() > 0) { - _session->destroy(_sslContext); + _session->destroy_async(amiCB, _sslContext); } else { - _session->destroy(); + _session->destroy_async(amiCB); } } } @@ -154,18 +141,18 @@ Glacier2::RouterI::getCategoryForClient(const Ice::Current&) const return 0; } -SessionPrx -Glacier2::RouterI::createSession(const std::string&, const std::string&, const Current&) +void +Glacier2::RouterI::createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, + const Current&) { assert(false); // Must not be called in this router implementation. - return 0; } -SessionPrx -Glacier2::RouterI::createSessionFromSecureConnection(const Current&) +void +Glacier2::RouterI::createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, + const Current&) { assert(false); // Must not be called in this router implementation. - return 0; } void diff --git a/cpp/src/Glacier2/RouterI.h b/cpp/src/Glacier2/RouterI.h index 64bccd5d50c..077161ee178 100644 --- a/cpp/src/Glacier2/RouterI.h +++ b/cpp/src/Glacier2/RouterI.h @@ -29,19 +29,21 @@ class RouterI : public Router, public IceUtil::Mutex { public: - RouterI(const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&, const Ice::ConnectionPtr&, const std::string&, - const SessionPrx&, const Ice::Identity&, const FilterManagerPtr&, const Ice::Context& sslContext); + RouterI(const InstancePtr&, const Ice::ConnectionPtr&, const std::string&, const SessionPrx&, const Ice::Identity&, + const FilterManagerPtr&, const Ice::Context&); virtual ~RouterI(); - void destroy(); + void destroy(const AMI_Session_destroyPtr&); - virtual Ice::ObjectPrx getClientProxy(const Ice::Current&) const; - virtual Ice::ObjectPrx getServerProxy(const Ice::Current&) const; + virtual Ice::ObjectPrx getClientProxy(const Ice::Current& = Ice::Current()) const; + virtual Ice::ObjectPrx getServerProxy(const Ice::Current& = Ice::Current()) const; virtual void addProxy(const Ice::ObjectPrx&, const Ice::Current&); virtual Ice::ObjectProxySeq addProxies(const Ice::ObjectProxySeq&, const Ice::Current&); virtual std::string getCategoryForClient(const Ice::Current&) const; - virtual SessionPrx createSession(const std::string&, const std::string&, const Ice::Current&); - virtual SessionPrx createSessionFromSecureConnection(const Ice::Current&); + virtual void createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, + const Ice::Current&); + virtual void createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, + const Ice::Current&); virtual void destroySession(const ::Ice::Current&); virtual Ice::Long getSessionTimeout(const ::Ice::Current&) const; @@ -56,12 +58,11 @@ public: private: - const Ice::CommunicatorPtr _communicator; + const InstancePtr _instance; const Ice::ObjectPrx _clientProxy; const Ice::ObjectPrx _serverProxy; const ClientBlobjectPtr _clientBlobject; const ServerBlobjectPtr _serverBlobject; - const Ice::ObjectAdapterPtr _serverAdapter; const Ice::ConnectionPtr _connection; const std::string _userId; const SessionPrx _session; diff --git a/cpp/src/Glacier2/ServerBlobject.cpp b/cpp/src/Glacier2/ServerBlobject.cpp index aafc1c8429f..0915655ebed 100644 --- a/cpp/src/Glacier2/ServerBlobject.cpp +++ b/cpp/src/Glacier2/ServerBlobject.cpp @@ -13,8 +13,8 @@ using namespace std; using namespace Ice; using namespace Glacier2; -Glacier2::ServerBlobject::ServerBlobject(const CommunicatorPtr& communicator, const ConnectionPtr& connection) : - Glacier2::Blobject(communicator, true, Ice::Context()), +Glacier2::ServerBlobject::ServerBlobject(const InstancePtr& instance, const ConnectionPtr& connection) : + Glacier2::Blobject(instance, true, Ice::Context()), _connection(connection) { } diff --git a/cpp/src/Glacier2/ServerBlobject.h b/cpp/src/Glacier2/ServerBlobject.h index 200a951cc59..4dda0036748 100644 --- a/cpp/src/Glacier2/ServerBlobject.h +++ b/cpp/src/Glacier2/ServerBlobject.h @@ -22,7 +22,7 @@ class ServerBlobject : public Glacier2::Blobject { public: - ServerBlobject(const Ice::CommunicatorPtr&, const Ice::ConnectionPtr&); + ServerBlobject(const InstancePtr&, const Ice::ConnectionPtr&); virtual ~ServerBlobject(); virtual void ice_invoke_async(const Ice::AMD_Array_Object_ice_invokePtr&, diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp index 95945659800..9e05665ce3c 100644 --- a/cpp/src/Glacier2/SessionRouterI.cpp +++ b/cpp/src/Glacier2/SessionRouterI.cpp @@ -28,12 +28,11 @@ class SessionControlI : public SessionControl { public: - SessionControlI(const SessionRouterIPtr& sessionRouter, const ConnectionPtr& connection, - const FilterManagerPtr& filterManager, IceUtil::Time timeout) : + SessionControlI(const SessionRouterIPtr& sessionRouter, const ConnectionPtr& connection, + const FilterManagerPtr& filterManager) : _sessionRouter(sessionRouter), _connection(connection), - _filters(filterManager), - _timeout(static_cast<int>(timeout.toSeconds())) + _filters(filterManager) { } @@ -56,9 +55,9 @@ public: } virtual int - getSessionTimeout(const Current&) + getSessionTimeout(const Current& current) { - return _timeout; + return static_cast<int>(_sessionRouter->getSessionTimeout(current)); } virtual void @@ -73,7 +72,6 @@ private: const SessionRouterIPtr _sessionRouter; const ConnectionPtr _connection; const FilterManagerPtr _filters; - const int _timeout; }; class ClientLocator : public ServantLocator @@ -136,123 +134,494 @@ private: const SessionRouterIPtr _sessionRouter; }; -class UserPasswordAuthorizer : public Authorizer +class UserPasswordCreateSession : public CreateSession { public: - UserPasswordAuthorizer(const PermissionsVerifierPrx& verifier, const string& user, const string& password) : - _verifier(verifier), _user(user), _password(password) + UserPasswordCreateSession(const AMD_Router_createSessionPtr& amdCB, const string& user, const string& password, + const Ice::Current& current, const SessionRouterIPtr& sessionRouter) : + CreateSession(sessionRouter, user, current, Ice::Context()), + _amdCB(amdCB), + _password(password) { } - virtual bool - authorize(string& reason, const Ice::Context& ctx) + virtual void + authorize() { - if(_verifier) + assert(_sessionRouter->_verifier); + + class CheckPermissionsCB : public AMI_PermissionsVerifier_checkPermissions { - return _verifier->checkPermissions(_user, _password, reason, ctx); + public: + + CheckPermissionsCB(const UserPasswordCreateSessionPtr& session, bool hasSessionManager) : + _session(session), + _hasSessionManager(hasSessionManager) + { + } + + virtual void + ice_response(bool ok, const string& reason) + { + if(ok) + { + _session->authorized(_hasSessionManager); + } + else + { + _session->exception(PermissionDeniedException(reason.empty() ? "permission denied" : reason)); + } + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + if(dynamic_cast<const CollocationOptimizationException*>(&ex)) + { + _session->authorizeCollocated(); + } + else + { + _session->unexpectedAuthorizeException(ex); + } + } + + private: + + const UserPasswordCreateSessionPtr _session; + const bool _hasSessionManager; + }; + + AMI_PermissionsVerifier_checkPermissionsPtr cb = new CheckPermissionsCB(this, _sessionRouter->_sessionManager); + _sessionRouter->_verifier->checkPermissions_async(cb, _user, _password, _current.ctx); + } + + virtual void + authorizeCollocated() + { + try + { + string reason; + if(_sessionRouter->_verifier->checkPermissions(_user, _password, reason, _current.ctx)) + { + authorized(_sessionRouter->_sessionManager); + } + else + { + exception(PermissionDeniedException(reason.empty() ? "permission denied" : reason)); + } + } + catch(const Ice::Exception& ex) + { + unexpectedAuthorizeException(ex); } - reason = "No PermissionsVerifier is available"; - return false; + } + + virtual FilterManagerPtr + createFilterManager() + { + return FilterManager::create(_instance, _user, true); + } + + virtual void + createSession() + { + class CreateCB : public AMI_SessionManager_create + { + public: + + CreateCB(const CreateSessionPtr& session) : _session(session) + { + } + + virtual void + ice_response(const SessionPrx& session) + { + _session->sessionCreated(session); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + try + { + ex.ice_throw(); + } + catch(const CannotCreateSessionException& ex) + { + _session->exception(ex); + } + catch(const Ice::Exception& ex) + { + _session->unexpectedCreateSessionException(ex); + } + } + + private: + + const CreateSessionPtr _session; + }; + _sessionRouter->_sessionManager->create_async(new CreateCB(this), _user, _control, _current.ctx); + } + + virtual void + finished(const SessionPrx& session) + { + _amdCB->ice_response(session); + } + + virtual void + finished(const Ice::Exception& ex) + { + _amdCB->ice_exception(ex); } private: - const PermissionsVerifierPrx _verifier; - const string _user; + const AMD_Router_createSessionPtr _amdCB; const string _password; }; -class SSLPasswordAuthorizer : public Authorizer +class SSLCreateSession : public CreateSession { public: - SSLPasswordAuthorizer(const SSLPermissionsVerifierPrx& verifier, const SSLInfo& info) : - _verifier(verifier), _info(info) + SSLCreateSession(const AMD_Router_createSessionFromSecureConnectionPtr& amdCB, const string& user, + const SSLInfo& sslInfo, const Ice::Current& current, const SessionRouterIPtr& sessionRouter, + const Ice::Context& sslContext) : + CreateSession(sessionRouter, user, current, sslContext), + _amdCB(amdCB), + _sslInfo(sslInfo) + { + } + + virtual void + authorize() { + assert(_sessionRouter->_verifier); + + class AuthorizeCB : public AMI_SSLPermissionsVerifier_authorize + { + public: + + AuthorizeCB(const SSLCreateSessionPtr& session, bool hasSessionManager) : + _session(session), + _hasSessionManager(hasSessionManager) + { + } + + virtual void + ice_response(bool ok, const string& reason) + { + if(ok) + { + _session->authorized(_hasSessionManager); + } + else + { + _session->exception(PermissionDeniedException(reason.empty() ? "permission denied" : reason)); + } + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + if(dynamic_cast<const CollocationOptimizationException*>(&ex)) + { + _session->authorizeCollocated(); + } + else + { + _session->unexpectedAuthorizeException(ex); + } + } + + private: + + const SSLCreateSessionPtr _session; + const bool _hasSessionManager; + }; + + AMI_SSLPermissionsVerifier_authorizePtr cb = new AuthorizeCB(this, _sessionRouter->_sessionManager); + _sessionRouter->_sslVerifier->authorize_async(cb, _sslInfo, _current.ctx); } - virtual bool - authorize(string& reason, const Ice::Context& ctx) + virtual void + authorizeCollocated() { - if(_verifier) + try + { + string reason; + if(_sessionRouter->_sslVerifier->authorize(_sslInfo, reason, _current.ctx)) + { + authorized(_sessionRouter->_sessionManager); + } + else + { + exception(PermissionDeniedException(reason.empty() ? "permission denied" : reason)); + } + } + catch(const Ice::Exception& ex) { - return _verifier->authorize(_info, reason, ctx); + unexpectedAuthorizeException(ex); } + } - reason = "No SSLPermissionsVerifier is available"; - return false; + virtual FilterManagerPtr + createFilterManager() + { + return FilterManager::create(_instance, _user, false); + } + + virtual void + createSession() + { + class CreateCB : public AMI_SSLSessionManager_create + { + public: + + CreateCB(const CreateSessionPtr& session) : _session(session) + { + } + + virtual void + ice_response(const SessionPrx& session) + { + _session->sessionCreated(session); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + try + { + ex.ice_throw(); + } + catch(const CannotCreateSessionException& ex) + { + _session->exception(ex); + } + catch(const Ice::Exception& ex) + { + _session->unexpectedCreateSessionException(ex); + } + } + + private: + + const CreateSessionPtr _session; + }; + _sessionRouter->_sslSessionManager->create_async(new CreateCB(this), _sslInfo, _control, _current.ctx); + } + + virtual void + finished(const SessionPrx& session) + { + _amdCB->ice_response(session); + } + + virtual void + finished(const Ice::Exception& ex) + { + _amdCB->ice_exception(ex); } private: - const SSLPermissionsVerifierPrx _verifier; - const SSLInfo _info; + const AMD_Router_createSessionFromSecureConnectionPtr _amdCB; + const SSLInfo _sslInfo; }; -class UserSessionFactory : public SessionFactory +class DestroyCB : public AMI_Session_destroy { public: - UserSessionFactory(const SessionManagerPrx& manager, const string& user) : - _manager(manager), _user(user) + DestroyCB(int traceLevel, const LoggerPtr& logger) : + _logger(traceLevel > 0 ? logger : LoggerPtr()) + { + } + + virtual void + ice_response() { } - virtual SessionPrx - create(const SessionControlPrx& control, const Ice::Context& ctx) + virtual void + ice_exception(const Ice::Exception& ex) { - return _manager->create(_user, control, ctx); + if(_logger) + { + Trace out(_logger, "Glacier2"); + out << "exception while destroying session\n" << ex; + } } private: - const SessionManagerPrx _manager; - const string _user; + LoggerPtr _logger; }; -class SSLSessionFactory : public SessionFactory +} + +using namespace Glacier2; + +Glacier2::CreateSession::CreateSession(const SessionRouterIPtr& sessionRouter, const string& user, + const Ice::Current& current, const Ice::Context& sslContext) : + _instance(sessionRouter->_instance), + _sessionRouter(sessionRouter), + _user(user), + _current(current), + _sslContext(sslContext) { -public: +} + +void +Glacier2::CreateSession::create() +{ + try + { + if(_sessionRouter->startCreateSession(this, _current.con)) + { + authorize(); + } + } + catch(const Ice::Exception& ex) + { + finished(ex); + } +} + +void +Glacier2::CreateSession::addPendingCallback(const CreateSessionPtr& callback) +{ + _pendingCallbacks.push_back(callback); +} - SSLSessionFactory(const SSLSessionManagerPrx& manager, const SSLInfo& info) : - _manager(manager), _info(info) +void +Glacier2::CreateSession::authorized(bool createSession) +{ + // + // Create the filter manager now as it's required for the session control object. + // + _filterManager = createFilterManager(); + + // + // If we have a session manager configured, we create a client-visible session object, + // otherwise, we return a null session proxy. + // + if(createSession) { + if(_instance->serverObjectAdapter()) + { + Ice::ObjectPtr obj = new SessionControlI(_sessionRouter, _current.con, _filterManager); + _control = SessionControlPrx::uncheckedCast(_instance->serverObjectAdapter()->addWithUUID(obj)); + } + this->createSession(); } + else + { + sessionCreated(0); + } +} - virtual SessionPrx - create(const SessionControlPrx& control, const Ice::Context& ctx) +void +Glacier2::CreateSession::unexpectedAuthorizeException(const Ice::Exception& ex) +{ + if(_sessionRouter->sessionTraceLevel() >= 1) { - return _manager->create(_info, control, ctx); + Warning out(_instance->logger()); + out << "exception while verifying permissions:\n" << ex; } + exception(PermissionDeniedException("internal server error")); +} -private: +void +Glacier2::CreateSession::sessionCreated(const SessionPrx& session) +{ + // + // Create the session router object. + // + RouterIPtr router; + try + { + router = new RouterI(_instance, _current.con, _user, session, + _control ? _control->ice_getIdentity() : Ice::Identity(), _filterManager, _sslContext); + } + catch(const Ice::Exception& ex) + { + session->destroy_async(new DestroyCB(0, 0)); + unexpectedCreateSessionException(ex); + return; + } - const SSLSessionManagerPrx _manager; - const SSLInfo _info; -}; + // + // Notify the router that the creation is finished. + // + try + { + _sessionRouter->finishCreateSession(_current.con, router); + finished(session); + } + catch(const Ice::Exception& ex) + { + finished(ex); + } + for(vector<CreateSessionPtr>::const_iterator p = _pendingCallbacks.begin(); p != _pendingCallbacks.end(); ++p) + { + (*p)->create(); + } } -using namespace Glacier2; +void +Glacier2::CreateSession::unexpectedCreateSessionException(const Ice::Exception& ex) +{ + if(_sessionRouter->sessionTraceLevel() >= 1) + { + Trace out(_instance->logger(), "Glacier2"); + out << "exception while creating session with session manager:\n" << ex; + } + exception(CannotCreateSessionException("internal server error")); +} + +void +Glacier2::CreateSession::exception(const Ice::Exception& ex) +{ + _sessionRouter->finishCreateSession(_current.con, 0); + + finished(ex); + + if(_control) + { + try + { + _instance->serverObjectAdapter()->remove(_control->ice_getIdentity()); + } + catch(const Exception&) + { + } + } -Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter, - const ObjectAdapterPtr& serverAdapter, + for(vector<CreateSessionPtr>::const_iterator p = _pendingCallbacks.begin(); p != _pendingCallbacks.end(); ++p) + { + (*p)->create(); + } +} + +Glacier2::SessionRouterI::SessionRouterI(const InstancePtr& instance, const PermissionsVerifierPrx& verifier, const SessionManagerPrx& sessionManager, const SSLPermissionsVerifierPrx& sslVerifier, const SSLSessionManagerPrx& sslSessionManager) : - _properties(clientAdapter->getCommunicator()->getProperties()), - _logger(clientAdapter->getCommunicator()->getLogger()), - _sessionTraceLevel(_properties->getPropertyAsInt("Glacier2.Trace.Session")), - _rejectTraceLevel(_properties->getPropertyAsInt("Glacier2.Client.Trace.Reject")), - _clientAdapter(clientAdapter), - _serverAdapter(serverAdapter), + _instance(instance), + _sessionTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Trace.Session")), + _rejectTraceLevel(_instance->properties()->getPropertyAsInt("Glacier2.Client.Trace.Reject")), _verifier(verifier), _sessionManager(sessionManager), _sslVerifier(sslVerifier), _sslSessionManager(sslSessionManager), - _sessionTimeout(IceUtil::Time::seconds(_properties->getPropertyAsInt("Glacier2.SessionTimeout"))), + _sessionTimeout(IceUtil::Time::seconds(_instance->properties()->getPropertyAsInt("Glacier2.SessionTimeout"))), _sessionThread(_sessionTimeout > IceUtil::Time() ? new SessionThread(this, _sessionTimeout) : 0), _routersByConnectionHint(_routersByConnection.end()), _routersByCategoryHint(_routersByCategory.end()), @@ -263,24 +632,24 @@ Glacier2::SessionRouterI::SessionRouterI(const ObjectAdapterPtr& clientAdapter, // Glacier2 router Ice object. // Identity routerId; - routerId.category = _properties->getPropertyWithDefault("Glacier2.InstanceName", "Glacier2"); + routerId.category = _instance->properties()->getPropertyWithDefault("Glacier2.InstanceName", "Glacier2"); routerId.name = "router"; - _clientAdapter->add(this, routerId); + _instance->clientObjectAdapter()->add(this, routerId); // // All other calls on the client object adapter are dispatched to // a router servant based on connection information. // - _clientAdapter->addServantLocator(new ClientLocator(this), ""); + _instance->clientObjectAdapter()->addServantLocator(new ClientLocator(this), ""); // // If there is a server object adapter, all calls on this adapter // are dispatched to a router servant based on the category field // of the identity. // - if(_serverAdapter) + if(_instance->serverObjectAdapter()) { - _serverAdapter->addServantLocator(new ServerLocator(this), ""); + _instance->serverObjectAdapter()->addServantLocator(new ServerLocator(this), ""); } if(_sessionThread) @@ -329,20 +698,7 @@ Glacier2::SessionRouterI::destroy() // for(map<ConnectionPtr, RouterIPtr>::iterator p = routers.begin(); p != routers.end(); ++p) { - RouterIPtr router = p->second; - - try - { - router->destroy(); - } - catch(const Exception& ex) - { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "exception while destroying session\n" << ex; - } - } + p->second->destroy(new DestroyCB(_sessionTraceLevel, _instance->logger())); } if(sessionThread) @@ -388,26 +744,28 @@ Glacier2::SessionRouterI::getCategoryForClient(const Ice::Current& current) cons return getRouter(current.con, current.id)->getServerProxy(current)->ice_getIdentity().category; } -SessionPrx -Glacier2::SessionRouterI::createSession(const std::string& userId, const std::string& password, const Current& current) +void +Glacier2::SessionRouterI::createSession_async(const AMD_Router_createSessionPtr& amdCB, const std::string& userId, + const std::string& password, const Current& current) { - SessionFactoryPtr factory; - if(_sessionManager) + if(!_verifier) { - factory = new UserSessionFactory(_sessionManager, userId); + amdCB->ice_exception(PermissionDeniedException("no configured permissions verifier")); + return; } - return createSessionInternal(userId, true, new UserPasswordAuthorizer(_verifier, userId, password), factory, - Ice::Context(), current); + + CreateSessionPtr session = new UserPasswordCreateSession(amdCB, userId, password, current, this); + session->create(); } -SessionPrx -Glacier2::SessionRouterI::createSessionFromSecureConnection(const Current& current) +void +Glacier2::SessionRouterI::createSessionFromSecureConnection_async( + const AMD_Router_createSessionFromSecureConnectionPtr& amdCB, const Current& current) { if(!_sslVerifier) { - PermissionDeniedException exc; - exc.reason = "no configured ssl permissions verifier"; - throw exc; + amdCB->ice_exception(PermissionDeniedException("no configured ssl permissions verifier")); + return; } string userDN; @@ -437,7 +795,7 @@ Glacier2::SessionRouterI::createSessionFromSecureConnection(const Current& curre userDN = info.certs[0]->getSubjectDN(); } - if(_properties->getPropertyAsInt("Glacier2.AddSSLContext") > 0) + if(_instance->properties()->getPropertyAsInt("Glacier2.AddSSLContext") > 0) { sslCtx["SSL.Active"] = "1"; sslCtx["SSL.Cipher"] = sslinfo.cipher; @@ -457,24 +815,17 @@ Glacier2::SessionRouterI::createSessionFromSecureConnection(const Current& curre } catch(const IceSSL::ConnectionInvalidException&) { - PermissionDeniedException exc; - exc.reason = "not ssl connection"; - throw exc; + amdCB->ice_exception(PermissionDeniedException("not ssl connection")); + return; } catch(const IceSSL::CertificateEncodingException&) { - PermissionDeniedException exc; - exc.reason = "certificate encoding exception"; - throw exc; + amdCB->ice_exception(PermissionDeniedException("certificate encoding exception")); + return; } - SessionFactoryPtr factory; - if(_sslSessionManager) - { - factory = new SSLSessionFactory(_sslSessionManager, sslinfo); - } - return createSessionInternal(userDN, false, new SSLPasswordAuthorizer(_sslVerifier, sslinfo), factory, sslCtx, - current); + CreateSessionPtr session = new SSLCreateSession(amdCB, userDN, sslinfo, current, this, sslCtx); + session->create(); } void @@ -519,7 +870,7 @@ Glacier2::SessionRouterI::destroySession(const ConnectionPtr& connection) _routersByConnection.erase(p++); _routersByConnectionHint = p; - if(_serverAdapter) + if(_instance->serverObjectAdapter()) { string category = router->getServerProxy(Current())->ice_getIdentity().category; assert(!category.empty()); @@ -532,25 +883,13 @@ Glacier2::SessionRouterI::destroySession(const ConnectionPtr& connection) // We destroy the router outside the thread synchronization, to // avoid deadlocks. // - try + if(_sessionTraceLevel >= 1) { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "destroying session\n"; - out << router->toString(); - } - - router->destroy(); - } - catch(const Exception& ex) - { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "exception while destroying session\n" << ex; - } + Trace out(_instance->logger(), "Glacier2"); + out << "destroying session\n" << router->toString(); } + + router->destroy(new DestroyCB(_sessionTraceLevel, _instance->logger())); } Ice::Long @@ -588,9 +927,9 @@ Glacier2::SessionRouterI::getRouter(const ConnectionPtr& connection, const Ice:: { if(_rejectTraceLevel >= 1) { - Trace out(_logger, "Glacier2"); + Trace out(_instance->logger(), "Glacier2"); out << "rejecting request. no session is associated with the connection.\n"; - out << "identity: " << _clientAdapter->getCommunicator()->identityToString(id); + out << "identity: " << _instance->communicator()->identityToString(id); } connection->close(true); throw ObjectNotExistException(__FILE__, __LINE__); @@ -655,7 +994,7 @@ Glacier2::SessionRouterI::expireSessions() _routersByConnection.erase(p++); _routersByConnectionHint = p; - if(_serverAdapter) + if(_instance->serverObjectAdapter()) { string category = router->getServerProxy(Current())->ice_getIdentity().category; assert(!category.empty()); @@ -676,319 +1015,114 @@ Glacier2::SessionRouterI::expireSessions() // for(vector<RouterIPtr>::iterator p = routers.begin(); p != routers.end(); ++p) { - RouterIPtr router = *p; - - try - { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "expiring session\n"; - out << router->toString(); - } - - router->destroy(); - } - catch(const Exception& ex) + if(_sessionTraceLevel >= 1) { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "exception while expiring session\n" << ex; - } + Trace out(_instance->logger(), "Glacier2"); + out << "expiring session\n" << (*p)->toString(); } + + (*p)->destroy(new DestroyCB(_sessionTraceLevel, _instance->logger())); } } -SessionPrx -Glacier2::SessionRouterI::createSessionInternal(const string& userId, bool allowAddUserMode, - const AuthorizerPtr& authorizer, const SessionFactoryPtr& factory, - const Ice::Context& sslContext, const Current& current) +bool +Glacier2::SessionRouterI::startCreateSession(const CreateSessionPtr& cb, const ConnectionPtr& connection) { - { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - - if(_destroy) - { - current.con->close(true); - throw ObjectNotExistException(__FILE__, __LINE__); - } - - // - // Check whether a session already exists for the connection. - // - { - map<ConnectionPtr, RouterIPtr>::iterator p; - if(_routersByConnectionHint != _routersByConnection.end() && - _routersByConnectionHint->first == current.con) - { - p = _routersByConnectionHint; - } - else - { - p = _routersByConnection.find(current.con); - } - - if(p != _routersByConnection.end()) - { - CannotCreateSessionException exc; - exc.reason = "session exists"; - throw exc; - } - } + IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - // - // If some other thread is currently trying to create a - // session, we wait until this thread is finished. - // - bool searchAgain = false; - while(_pending.find(current.con) != _pending.end()) - { - wait(); - - if(_destroy) - { - current.con->close(true); - throw ObjectNotExistException(__FILE__, __LINE__); - } - - searchAgain = true; - } - - // - // Check for existing sessions again if we waited above, as - // new sessions have been added in the meantime. - // - if(searchAgain) - { - map<ConnectionPtr, RouterIPtr>::iterator p; - if(_routersByConnectionHint != _routersByConnection.end() && - _routersByConnectionHint->first == current.con) - { - p = _routersByConnectionHint; - } - else - { - p = _routersByConnection.find(current.con); - } - - if(p != _routersByConnection.end()) - { - CannotCreateSessionException exc; - exc.reason = "session exists"; - throw exc; - } - } - - // - // No session exists yet, so we will try to create one. To - // avoid that other threads try to create sessions for the - // same connection, we add our endpoints to _pending. - // - _pending.insert(current.con); + if(_destroy) + { + connection->close(true); + throw ObjectNotExistException(__FILE__, __LINE__); } - try + // + // Check whether a session already exists for the connection. + // { - // - // Authorize. - // - string reason; - bool ok; - - try + map<ConnectionPtr, RouterIPtr>::iterator p; + if(_routersByConnectionHint != _routersByConnection.end() && + _routersByConnectionHint->first == connection) { - ok = authorizer->authorize(reason, current.ctx); + p = _routersByConnectionHint; } - catch(const Exception& ex) + else { - if(_sessionTraceLevel >= 1) - { - Warning out(_logger); - out << "exception while verifying password:\n" << ex; - } - - PermissionDeniedException exc; - exc.reason = "internal server error"; - throw exc; + p = _routersByConnection.find(connection); } - - if(!ok) + + if(p != _routersByConnection.end()) { - PermissionDeniedException exc; - if(reason.empty()) - { - exc.reason = "permission denied"; - } - else - { - exc.reason = reason; - } + CannotCreateSessionException exc; + exc.reason = "session exists"; throw exc; } } - catch(const Exception& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); + map<ConnectionPtr, CreateSessionPtr>::iterator p = _pending.find(connection); + if(p != _pending.end()) + { // - // Signal other threads that we are done with trying to - // establish a session for our connection; + // If some other thread is currently trying to create a + // session, we wait until this thread is finished. // - _pending.erase(current.con); - notify(); - - ex.ice_throw(); + p->second->addPendingCallback(cb); + return false; } - - - SessionPrx session; - Identity controlId; - RouterIPtr router; - - try + else { // - // The client blobject requires direct access to the full filter - // servant, but proliferating the implementation of the servant - // throughout the router code is undesirable. To avoid lots of - // physical interdependencies, we create the filters and - // clientblobject together and pass the clientblobject to the - // router. We create the clientblobject here since it is - // responsible for creating the filters and we want them to be - // accessible during session creation. + // No session exists yet, so we will try to create one. To + // avoid that other threads try to create sessions for the + // same connection, we add our endpoints to _pending. // - FilterManagerPtr filterManager = FilterManager::create(_clientAdapter->getCommunicator(), _serverAdapter, - userId, allowAddUserMode); + _pending.insert(make_pair(connection, cb)); + return true; + } +} - // - // If we have a session manager configured, we create a - // client-visible session object. - // - if(factory) - { - SessionControlPrx control; - if(_serverAdapter) - { - control = SessionControlPrx::uncheckedCast( - _serverAdapter->addWithUUID( - new SessionControlI(this, current.con, filterManager, _sessionTimeout))); - controlId = control->ice_getIdentity(); - } - session = factory->create(control, current.ctx); - } +void +Glacier2::SessionRouterI::finishCreateSession(const ConnectionPtr& connection, const RouterIPtr& router) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - // - // Add a new per-client router. - // - router = new RouterI(_clientAdapter, _serverAdapter, current.con, userId, - session, controlId, filterManager, sslContext); - } - catch(const Exception& ex) + // + // Signal other threads that we are done with trying to + // establish a session for our connection; + // + _pending.erase(connection); + notify(); + + if(!router) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - - // - // Signal other threads that we are done with trying to - // establish a session for our connection; - // - _pending.erase(current.con); - notify(); - - assert(!router); - - if(session) - { - if(_serverAdapter) - { - try - { - _serverAdapter->remove(controlId); - } - catch(const Exception&) - { - // Ignore all exceptions here. - } - } - try - { - session->destroy(); - } - catch(const Exception&) - { - // Ignore all exceptions here. - } - } - - try - { - ex.ice_throw(); - } - catch(const Glacier2::CannotCreateSessionException&) - { - throw; - } - catch(const Exception&) - { - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "exception while creating session with session manager:\n" << ex; - } - - CannotCreateSessionException exc; - exc.reason = "internal server error"; - throw exc; - } + return; } + if(_destroy) { - IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this); - - // - // Signal other threads that we are done with trying to - // establish a session for our connection; - // - _pending.erase(current.con); - notify(); - - if(_destroy) - { - try - { - router->destroy(); - } - catch(const Exception&) - { - // Ignore all exceptions here. - } - - current.con->close(true); - throw ObjectNotExistException(__FILE__, __LINE__); - } - - _routersByConnectionHint = _routersByConnection.insert( - _routersByConnectionHint, pair<const ConnectionPtr, RouterIPtr>(current.con, router)); - - if(_serverAdapter) - { - string category = router->getServerProxy(current)->ice_getIdentity().category; - assert(!category.empty()); - pair<map<string, RouterIPtr>::iterator, bool> rc = - _routersByCategory.insert(pair<const string, RouterIPtr>(category, router)); - assert(rc.second); - _routersByCategoryHint = rc.first; - } - - if(_sessionTraceLevel >= 1) - { - Trace out(_logger, "Glacier2"); - out << "created session\n"; - out << router->toString(); - } + router->destroy(new DestroyCB(0, 0)); + connection->close(true); + throw ObjectNotExistException(__FILE__, __LINE__); + } + + _routersByConnectionHint = _routersByConnection.insert( + _routersByConnectionHint, pair<const ConnectionPtr, RouterIPtr>(connection, router)); + + if(_instance->serverObjectAdapter()) + { + string category = router->getServerProxy()->ice_getIdentity().category; + assert(!category.empty()); + pair<map<string, RouterIPtr>::iterator, bool> rc = + _routersByCategory.insert(pair<const string, RouterIPtr>(category, router)); + assert(rc.second); + _routersByCategoryHint = rc.first; + } + + if(_sessionTraceLevel >= 1) + { + Trace out(_instance->logger(), "Glacier2"); + out << "created session\n" << router->toString(); } - - return session; } Glacier2::SessionRouterI::SessionThread::SessionThread(const SessionRouterIPtr& sessionRouter, diff --git a/cpp/src/Glacier2/SessionRouterI.h b/cpp/src/Glacier2/SessionRouterI.h index 9be3f25e2b0..6ab526ffbd0 100644 --- a/cpp/src/Glacier2/SessionRouterI.h +++ b/cpp/src/Glacier2/SessionRouterI.h @@ -15,6 +15,7 @@ #include <Ice/Ice.h> #include <Glacier2/PermissionsVerifierF.h> #include <Glacier2/Router.h> +#include <Glacier2/Instance.h> #include <set> #include <IceUtil/DisableWarnings.h> @@ -27,28 +28,58 @@ typedef IceUtil::Handle<RouterI> RouterIPtr; class SessionRouterI; typedef IceUtil::Handle<SessionRouterI> SessionRouterIPtr; -class Authorizer : public IceUtil::Shared +class FilterManager; +typedef IceUtil::Handle<FilterManager> FilterManagerPtr; + +class CreateSession; +typedef IceUtil::Handle<CreateSession> CreateSessionPtr; + +class CreateSession : public IceUtil::Shared { public: - virtual bool authorize(std::string&, const Ice::Context&) = 0; -}; -typedef IceUtil::Handle<Authorizer> AuthorizerPtr; + CreateSession(const SessionRouterIPtr&, const std::string&, const Ice::Current&, const Ice::Context&); -class SessionFactory : public IceUtil::Shared -{ -public: + void create(); + void addPendingCallback(const CreateSessionPtr&); + + void authorized(bool); + void unexpectedAuthorizeException(const Ice::Exception&); + + void sessionCreated(const SessionPrx&); + void unexpectedCreateSessionException(const Ice::Exception&); - virtual SessionPrx create(const SessionControlPrx&, const Ice::Context&) = 0; + void exception(const Ice::Exception&); + + virtual void authorize() = 0; + virtual void createSession() = 0; + virtual FilterManagerPtr createFilterManager() = 0; + virtual void finished(const SessionPrx&) = 0; + virtual void finished(const Ice::Exception&) = 0; + +protected: + + const InstancePtr _instance; + const SessionRouterIPtr _sessionRouter; + const std::string _user; + const Ice::Current _current; + Ice::Context _sslContext; + std::vector<CreateSessionPtr> _pendingCallbacks; + SessionControlPrx _control; + FilterManagerPtr _filterManager; }; -typedef IceUtil::Handle<SessionFactory> SessionFactoryPtr; + +class UserPasswordCreateSession; +typedef IceUtil::Handle<UserPasswordCreateSession> UserPasswordCreateSessionPtr; + +class SSLCreateSession; +typedef IceUtil::Handle<SSLCreateSession> SSLCreateSessionPtr; class SessionRouterI : public Router, public IceUtil::Monitor<IceUtil::Mutex> { public: - SessionRouterI(const Ice::ObjectAdapterPtr&, const Ice::ObjectAdapterPtr&, - const PermissionsVerifierPrx&, const SessionManagerPrx&, + SessionRouterI(const InstancePtr&, const PermissionsVerifierPrx&, const SessionManagerPrx&, const SSLPermissionsVerifierPrx&, const SSLSessionManagerPrx&); virtual ~SessionRouterI(); void destroy(); @@ -58,8 +89,10 @@ public: virtual void addProxy(const Ice::ObjectPrx&, const Ice::Current&); virtual Ice::ObjectProxySeq addProxies(const Ice::ObjectProxySeq&, const Ice::Current&); virtual std::string getCategoryForClient(const Ice::Current&) const; - virtual SessionPrx createSession(const std::string&, const std::string&, const Ice::Current&); - virtual SessionPrx createSessionFromSecureConnection(const Ice::Current&); + virtual void createSession_async(const AMD_Router_createSessionPtr&, const std::string&, const std::string&, + const Ice::Current&); + virtual void createSessionFromSecureConnection_async(const AMD_Router_createSessionFromSecureConnectionPtr&, + const Ice::Current&); virtual void destroySession(const ::Ice::Current&); virtual Ice::Long getSessionTimeout(const ::Ice::Current&) const; @@ -70,17 +103,19 @@ public: void destroySession(const ::Ice::ConnectionPtr&); + int sessionTraceLevel() const { return _sessionTraceLevel; } + private: - SessionPrx createSessionInternal(const std::string&, bool, const AuthorizerPtr&, const SessionFactoryPtr&, - const Ice::Context&, const Ice::Current&); + bool startCreateSession(const CreateSessionPtr&, const Ice::ConnectionPtr&); + void finishCreateSession(const Ice::ConnectionPtr&, const RouterIPtr&); + friend class Glacier2::CreateSession; + friend class Glacier2::UserPasswordCreateSession; + friend class Glacier2::SSLCreateSession; - const Ice::PropertiesPtr _properties; - const Ice::LoggerPtr _logger; + const InstancePtr _instance; const int _sessionTraceLevel; const int _rejectTraceLevel; - const Ice::ObjectAdapterPtr _clientAdapter; - const Ice::ObjectAdapterPtr _serverAdapter; const PermissionsVerifierPrx _verifier; const SessionManagerPrx _sessionManager; const SSLPermissionsVerifierPrx _sslVerifier; @@ -111,7 +146,7 @@ private: std::map<std::string, RouterIPtr> _routersByCategory; mutable std::map<std::string, RouterIPtr>::iterator _routersByCategoryHint; - std::set<Ice::ConnectionPtr> _pending; + std::map<Ice::ConnectionPtr, CreateSessionPtr> _pending; bool _destroy; }; diff --git a/cpp/src/Ice/.depend b/cpp/src/Ice/.depend index 569597da8fb..d4cede0d2a0 100644 --- a/cpp/src/Ice/.depend +++ b/cpp/src/Ice/.depend @@ -1,92 +1,97 @@ -Acceptor$(OBJEXT): Acceptor.cpp ../Ice/Acceptor.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/AcceptorF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TransceiverF.h -Application$(OBJEXT): Application.cpp ../../include/Ice/Application.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/ArgVector.h ../Ice/GC.h ../../include/IceUtil/Thread.h -Buffer$(OBJEXT): Buffer.cpp ../../include/Ice/Buffer.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h -BasicStream$(OBJEXT): BasicStream.cpp ../../include/IceUtil/DisableWarnings.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/ProxyFactory.h ../../include/Ice/ObjectFactory.h ../Ice/ObjectFactoryManager.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../Ice/TraceUtil.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h -BuiltinSequences$(OBJEXT): BuiltinSequences.cpp ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -CommunicatorI$(OBJEXT): CommunicatorI.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/CommunicatorI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/DynamicLibraryF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Communicator.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h ../Ice/ObjectFactoryManager.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../Ice/ConnectorF.h ../../include/Ice/LoggerUtil.h ../Ice/DefaultsAndOverrides.h ../Ice/TraceLevels.h ../Ice/GC.h -Communicator$(OBJEXT): Communicator.cpp ../../include/Ice/Communicator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -ConnectionFactory$(OBJEXT): ConnectionFactory.cpp ../Ice/ConnectionFactory.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/TransceiverF.h ../Ice/RouterInfoF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../../include/Ice/Properties.h ../Ice/Transceiver.h ../Ice/Connector.h ../Ice/Acceptor.h ../Ice/ThreadPool.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/Reference.h ../Ice/EndpointI.h ../Ice/RouterInfo.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Random.h -ConnectionI$(OBJEXT): ConnectionI.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/ConnectionI.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/Ice/Connection.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Properties.h ../Ice/TraceUtil.h ../Ice/DefaultsAndOverrides.h ../Ice/Transceiver.h ../Ice/ThreadPool.h ../Ice/ConnectionMonitor.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/ConnectorF.h ../Ice/EndpointI.h ../Ice/AcceptorF.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h -ConnectionMonitor$(OBJEXT): ConnectionMonitor.cpp ../Ice/ConnectionMonitor.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/Ice/ConnectionMonitorF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/InstanceF.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LoggerUtil.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h -Connection$(OBJEXT): Connection.cpp ../../include/Ice/Connection.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -Connector$(OBJEXT): Connector.cpp ../Ice/Connector.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/ConnectorF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TransceiverF.h -Current$(OBJEXT): Current.cpp ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -DefaultsAndOverrides$(OBJEXT): DefaultsAndOverrides.cpp ../Ice/DefaultsAndOverrides.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalException.h -Direct$(OBJEXT): Direct.cpp ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ReferenceF.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../Ice/ServantManager.h ../../include/Ice/ServantLocator.h ../Ice/Reference.h ../Ice/ReferenceFactoryF.h ../Ice/SharedContext.h ../../include/Ice/LocalException.h -DispatchInterceptor$(OBJEXT): DispatchInterceptor.cpp ../../include/Ice/DispatchInterceptor.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/Ice/GCShared.h ../../include/Ice/Config.h ../../include/Ice/GCCountMap.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../Ice/IncomingRequest.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Direct.h ../../include/Ice/ReferenceF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h -DynamicLibrary$(OBJEXT): DynamicLibrary.cpp ../../include/Ice/DynamicLibrary.h ../../include/Ice/DynamicLibraryF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h -EndpointFactoryManager$(OBJEXT): EndpointFactoryManager.cpp ../Ice/EndpointFactoryManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/InstanceF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/EndpointIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/EndpointFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/Endpoint.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../Ice/UnknownEndpointI.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/DefaultsAndOverrides.h -EndpointFactory$(OBJEXT): EndpointFactory.cpp ../../include/Ice/EndpointFactory.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/EndpointIF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/EndpointFactoryF.h -Endpoint$(OBJEXT): Endpoint.cpp ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -EndpointI$(OBJEXT): EndpointI.cpp ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h -EventHandler$(OBJEXT): EventHandler.cpp ../Ice/EventHandler.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/EventHandlerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h -Exception$(OBJEXT): Exception.cpp ../../include/Ice/Exception.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/Plugin.h ../../include/IceUtil/StringUtil.h -FacetMap$(OBJEXT): FacetMap.cpp ../../include/Ice/FacetMap.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +Acceptor$(OBJEXT): Acceptor.cpp ../Ice/Acceptor.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/AcceptorF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TransceiverF.h +Application$(OBJEXT): Application.cpp ../../include/Ice/Application.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/ArgVector.h ../Ice/GC.h +Buffer$(OBJEXT): Buffer.cpp ../../include/Ice/Buffer.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h +BasicStream$(OBJEXT): BasicStream.cpp ../../include/IceUtil/DisableWarnings.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/ProxyFactory.h ../../include/Ice/ObjectFactory.h ../Ice/ObjectFactoryManager.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../Ice/TraceUtil.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h +BuiltinSequences$(OBJEXT): BuiltinSequences.cpp ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +CommunicatorI$(OBJEXT): CommunicatorI.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/CommunicatorI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/DynamicLibraryF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Communicator.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h ../Ice/ObjectFactoryManager.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../Ice/ConnectorF.h ../../include/Ice/LoggerUtil.h ../Ice/DefaultsAndOverrides.h ../Ice/TraceLevels.h ../Ice/GC.h +Communicator$(OBJEXT): Communicator.cpp ../../include/Ice/Communicator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +ConnectRequestHandler$(OBJEXT): ConnectRequestHandler.cpp ../Ice/ConnectRequestHandler.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Mutex.h ../Ice/RequestHandler.h ../../include/IceUtil/Shared.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../../include/Ice/RouterF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/RouterInfo.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/ConnectionRequestHandler.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/TransceiverF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/SelectorThread.h ../Ice/Selector.h ../../include/Ice/Properties.h +ConnectionFactory$(OBJEXT): ConnectionFactory.cpp ../Ice/ConnectionFactory.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/RouterInfoF.h ../Ice/EndpointI.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../../include/Ice/Properties.h ../Ice/Transceiver.h ../Ice/Connector.h ../Ice/Acceptor.h ../Ice/ThreadPool.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/Reference.h ../Ice/RouterInfo.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Random.h +ConnectionI$(OBJEXT): ConnectionI.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/ConnectionI.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/Ice/Connection.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Properties.h ../Ice/TraceUtil.h ../Ice/DefaultsAndOverrides.h ../Ice/Transceiver.h ../Ice/ThreadPool.h ../Ice/ConnectionMonitor.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/ConnectorF.h ../Ice/EndpointI.h ../Ice/AcceptorF.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h +ConnectionMonitor$(OBJEXT): ConnectionMonitor.cpp ../Ice/ConnectionMonitor.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/Ice/ConnectionMonitorF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/InstanceF.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/SelectorThread.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LoggerUtil.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h +Connection$(OBJEXT): Connection.cpp ../../include/Ice/Connection.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +ConnectionRequestHandler$(OBJEXT): ConnectionRequestHandler.cpp ../Ice/ConnectionRequestHandler.h ../Ice/RequestHandler.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/InstanceF.h ../../include/Ice/RouterF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/ConnectionI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../Ice/RouterInfo.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h +Connector$(OBJEXT): Connector.cpp ../Ice/Connector.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/ConnectorF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TransceiverF.h +Current$(OBJEXT): Current.cpp ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +DefaultsAndOverrides$(OBJEXT): DefaultsAndOverrides.cpp ../Ice/DefaultsAndOverrides.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalException.h +Direct$(OBJEXT): Direct.cpp ../../include/Ice/Direct.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ReferenceF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../Ice/ServantManager.h ../../include/Ice/ServantLocator.h ../Ice/Reference.h ../Ice/ReferenceFactoryF.h ../Ice/SharedContext.h ../../include/Ice/LocalException.h +DispatchInterceptor$(OBJEXT): DispatchInterceptor.cpp ../../include/Ice/DispatchInterceptor.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/Ice/GCShared.h ../../include/Ice/Config.h ../../include/Ice/GCCountMap.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../Ice/IncomingRequest.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Direct.h ../../include/Ice/ReferenceF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h +DynamicLibrary$(OBJEXT): DynamicLibrary.cpp ../../include/Ice/DynamicLibrary.h ../../include/Ice/DynamicLibraryF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h +EndpointFactoryManager$(OBJEXT): EndpointFactoryManager.cpp ../Ice/EndpointFactoryManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/InstanceF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/EndpointIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/EndpointFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/Endpoint.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../Ice/UnknownEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/DefaultsAndOverrides.h +EndpointFactory$(OBJEXT): EndpointFactory.cpp ../../include/Ice/EndpointFactory.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/EndpointIF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/EndpointFactoryF.h +Endpoint$(OBJEXT): Endpoint.cpp ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +EndpointI$(OBJEXT): EndpointI.cpp ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/Network.h +EventHandler$(OBJEXT): EventHandler.cpp ../Ice/EventHandler.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/EventHandlerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h +Exception$(OBJEXT): Exception.cpp ../../include/Ice/Exception.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h ../../include/Ice/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/Plugin.h ../../include/IceUtil/StringUtil.h +FacetMap$(OBJEXT): FacetMap.cpp ../../include/Ice/FacetMap.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h FactoryTableDef$(OBJEXT): FactoryTableDef.cpp ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Mutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/IceUtil/Handle.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/UserExceptionFactory.h FactoryTable$(OBJEXT): FactoryTable.cpp ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Mutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/IceUtil/Handle.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/UserExceptionFactory.h -GC$(OBJEXT): GC.cpp ../../include/IceUtil/Time.h ../../include/IceUtil/Config.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../Ice/GC.h ../../include/Ice/Config.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/GCShared.h ../../include/Ice/GCCountMap.h -Identity$(OBJEXT): Identity.cpp ../../include/Ice/Identity.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -IdentityUtil$(OBJEXT): IdentityUtil.cpp ../../include/Ice/IdentityUtil.h ../../include/Ice/Identity.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/IceUtil/StringUtil.h -ImplicitContextI$(OBJEXT): ImplicitContextI.cpp ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/IceUtil/StaticMutex.h -ImplicitContext$(OBJEXT): ImplicitContext.cpp ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -IncomingAsync$(OBJEXT): IncomingAsync.cpp ../../include/Ice/IncomingAsync.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/ServantLocator.h ../Ice/ConnectionI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/ReplyStatus.h ../../include/IceUtil/StaticMutex.h -Incoming$(OBJEXT): Incoming.cpp ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/IncomingAsync.h ../Ice/IncomingRequest.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../Ice/ServantManager.h ../Ice/ConnectionI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/ReplyStatus.h ../../include/IceUtil/StringUtil.h -Initialize$(OBJEXT): Initialize.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/ArgVector.h ../../include/IceUtil/Config.h ../Ice/GC.h ../../include/Ice/Config.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/CommunicatorI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Communicator.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/PropertiesI.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../Ice/StreamI.h ../../include/Ice/Stream.h ../Ice/LoggerI.h ../../include/Ice/Logger.h -Instance$(OBJEXT): Instance.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/Instance.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../Ice/RouterInfo.h ../../include/Ice/RouterF.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/LocatorF.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h ../Ice/ThreadPool.h ../Ice/EventHandlerF.h ../Ice/ConnectionFactory.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/TransceiverF.h ../Ice/EventHandler.h ../Ice/ConnectionMonitor.h ../Ice/ObjectFactoryManager.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../Ice/PropertiesI.h ../../include/Ice/Properties.h ../Ice/LoggerI.h ../../include/Ice/Logger.h ../Ice/Network.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/TcpEndpointI.h ../Ice/EndpointI.h ../../include/Ice/EndpointFactory.h ../Ice/UdpEndpointI.h ../../include/Ice/DynamicLibrary.h ../Ice/PluginManagerI.h ../../include/Ice/Plugin.h ../../include/Ice/LoggerUtil.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/UUID.h ../../include/Ice/Communicator.h ../../include/Ice/ImplicitContextF.h ../Ice/SysLoggerI.h -LocalException$(OBJEXT): LocalException.cpp ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -LocalObject$(OBJEXT): LocalObject.cpp ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h -LocatorInfo$(OBJEXT): LocatorInfo.cpp ../Ice/LocatorInfo.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Time.h ../Ice/LocatorInfoF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Locator.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Direct.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/Reference.h ../../include/Ice/RouterF.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h -Locator$(OBJEXT): Locator.cpp ../../include/Ice/Locator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Direct.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -LoggerI$(OBJEXT): LoggerI.cpp ../../include/IceUtil/Time.h ../../include/IceUtil/Config.h ../Ice/LoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h -Logger$(OBJEXT): Logger.cpp ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -LoggerUtil$(OBJEXT): LoggerUtil.cpp ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Logger.h -Network$(OBJEXT): Network.cpp ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/Network.h ../../include/Ice/Config.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h -ObjectAdapterFactory$(OBJEXT): ObjectAdapterFactory.cpp ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/IceUtil/UUID.h -ObjectAdapterI$(OBJEXT): ObjectAdapterI.cpp ../../include/IceUtil/UUID.h ../../include/IceUtil/Config.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../Ice/ObjectAdapterFactory.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../Ice/ProxyFactory.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/ConnectionFactory.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ServantManager.h ../Ice/RouterInfo.h ../../include/Ice/Properties.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LoggerUtil.h ../Ice/ThreadPool.h ../../include/Ice/Communicator.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/Router.h ../Ice/DefaultsAndOverrides.h ../Ice/TraceLevels.h ../Ice/PropertyNames.h -ObjectAdapter$(OBJEXT): ObjectAdapter.cpp ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -ObjectFactoryManager$(OBJEXT): ObjectFactoryManager.cpp ../Ice/ObjectFactoryManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectFactory.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h -ObjectFactory$(OBJEXT): ObjectFactory.cpp ../../include/Ice/ObjectFactory.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -Object$(OBJEXT): Object.cpp ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/Ice/GCShared.h ../../include/Ice/Config.h ../../include/Ice/GCCountMap.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/IncomingAsync.h ../Ice/IncomingRequest.h ../../include/Ice/Direct.h ../../include/Ice/ReferenceF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Stream.h -OutgoingAsync$(OBJEXT): OutgoingAsync.cpp ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/RecMutex.h ../../include/Ice/OutgoingAsyncF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ReferenceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Current.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../Ice/ConnectionI.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Reference.h ../Ice/ReferenceFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/BuiltinSequences.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/LocatorInfo.h ../Ice/ProxyFactory.h ../Ice/RouterInfo.h ../Ice/ReplyStatus.h -Outgoing$(OBJEXT): Outgoing.cpp ../../include/Ice/Outgoing.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ConnectionIF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ReferenceF.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../Ice/ConnectionI.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../Ice/ReplyStatus.h -PluginManagerI$(OBJEXT): PluginManagerI.cpp ../Ice/PluginManagerI.h ../../include/Ice/Plugin.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/LoggerF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/InstanceF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/DynamicLibrary.h ../../include/Ice/Communicator.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Initialize.h ../../include/Ice/LocalException.h -Plugin$(OBJEXT): Plugin.cpp ../../include/Ice/Plugin.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/LoggerF.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -Process$(OBJEXT): Process.cpp ../../include/Ice/Process.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -PropertiesI$(OBJEXT): PropertiesI.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/Config.h ../Ice/PropertiesI.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Properties.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/LocalException.h ../Ice/PropertyNames.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h -Properties$(OBJEXT): Properties.cpp ../../include/Ice/Properties.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +GC$(OBJEXT): GC.cpp ../../include/IceUtil/Time.h ../../include/IceUtil/Config.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../Ice/GC.h ../../include/Ice/Config.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/GCShared.h ../../include/Ice/GCCountMap.h +Identity$(OBJEXT): Identity.cpp ../../include/Ice/Identity.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +IdentityUtil$(OBJEXT): IdentityUtil.cpp ../../include/Ice/IdentityUtil.h ../../include/Ice/Identity.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/IceUtil/StringUtil.h +ImplicitContextI$(OBJEXT): ImplicitContextI.cpp ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/IceUtil/StaticMutex.h +ImplicitContext$(OBJEXT): ImplicitContext.cpp ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +IncomingAsync$(OBJEXT): IncomingAsync.cpp ../../include/Ice/IncomingAsync.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/ServantLocator.h ../Ice/ConnectionI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../Ice/ReplyStatus.h ../../include/IceUtil/StaticMutex.h +Incoming$(OBJEXT): Incoming.cpp ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/IncomingAsync.h ../Ice/IncomingRequest.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../Ice/ServantManager.h ../Ice/ConnectionI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/ReplyStatus.h ../../include/IceUtil/StringUtil.h +Initialize$(OBJEXT): Initialize.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/ArgVector.h ../../include/IceUtil/Config.h ../Ice/GC.h ../../include/Ice/Config.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/CommunicatorI.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Communicator.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/PropertiesI.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../Ice/StreamI.h ../../include/Ice/Stream.h ../Ice/LoggerI.h ../../include/Ice/Logger.h +Instance$(OBJEXT): Instance.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/Instance.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../Ice/RouterInfo.h ../../include/Ice/RouterF.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/LocatorF.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/ProxyFactory.h ../Ice/ThreadPool.h ../Ice/EventHandlerF.h ../Ice/Selector.h ../Ice/SelectorThread.h ../Ice/ConnectionFactory.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/TransceiverF.h ../Ice/EventHandler.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/EndpointI.h ../Ice/ConnectionMonitor.h ../Ice/ObjectFactoryManager.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../Ice/PropertiesI.h ../../include/Ice/Properties.h ../Ice/LoggerI.h ../../include/Ice/Logger.h ../Ice/Network.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/TcpEndpointI.h ../../include/Ice/EndpointFactory.h ../Ice/UdpEndpointI.h ../../include/Ice/DynamicLibrary.h ../Ice/PluginManagerI.h ../../include/Ice/Plugin.h ../../include/Ice/LoggerUtil.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/UUID.h ../../include/Ice/Communicator.h ../../include/Ice/ImplicitContextF.h ../Ice/SysLoggerI.h +LocalException$(OBJEXT): LocalException.cpp ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +LocalObject$(OBJEXT): LocalObject.cpp ../../include/Ice/LocalObject.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h +LocatorInfo$(OBJEXT): LocatorInfo.cpp ../Ice/LocatorInfo.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Time.h ../Ice/LocatorInfoF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/LocatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Locator.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Direct.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/Reference.h ../../include/Ice/RouterF.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h +Locator$(OBJEXT): Locator.cpp ../../include/Ice/Locator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Direct.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +LoggerI$(OBJEXT): LoggerI.cpp ../../include/IceUtil/Time.h ../../include/IceUtil/Config.h ../Ice/LoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/StaticMutex.h +Logger$(OBJEXT): Logger.cpp ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +LoggerUtil$(OBJEXT): LoggerUtil.cpp ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Logger.h +Network$(OBJEXT): Network.cpp ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/Network.h ../../include/Ice/Config.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h +ObjectAdapterFactory$(OBJEXT): ObjectAdapterFactory.cpp ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/IceUtil/UUID.h +ObjectAdapterI$(OBJEXT): ObjectAdapterI.cpp ../../include/IceUtil/UUID.h ../../include/IceUtil/Config.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/RouterInfoF.h ../Ice/ConnectorF.h ../Ice/LocatorInfoF.h ../Ice/ThreadPoolF.h ../../include/Ice/BuiltinSequences.h ../Ice/ObjectAdapterFactory.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ReferenceFactoryF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../Ice/ProxyFactory.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/ConnectionFactory.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/SelectorThread.h ../Ice/Selector.h ../Ice/ServantManager.h ../Ice/RouterInfo.h ../../include/Ice/Properties.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LoggerUtil.h ../Ice/ThreadPool.h ../../include/Ice/Communicator.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/Router.h ../Ice/DefaultsAndOverrides.h ../Ice/TraceLevels.h ../Ice/PropertyNames.h +ObjectAdapter$(OBJEXT): ObjectAdapter.cpp ../../include/Ice/ObjectAdapter.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +ObjectFactoryManager$(OBJEXT): ObjectFactoryManager.cpp ../Ice/ObjectFactoryManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectFactory.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h +ObjectFactory$(OBJEXT): ObjectFactory.cpp ../../include/Ice/ObjectFactory.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +Object$(OBJEXT): Object.cpp ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/Ice/GCShared.h ../../include/Ice/Config.h ../../include/Ice/GCCountMap.h ../../include/Ice/ObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Incoming.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/IncomingAsync.h ../Ice/IncomingRequest.h ../../include/Ice/Direct.h ../../include/Ice/ReferenceF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Stream.h +OutgoingAsync$(OBJEXT): OutgoingAsync.cpp ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ReferenceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Current.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/SelectorThread.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../Ice/RequestHandler.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/Instance.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/BuiltinSequences.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/LocatorInfo.h ../Ice/ProxyFactory.h ../Ice/RouterInfo.h ../Ice/ReplyStatus.h +Outgoing$(OBJEXT): Outgoing.cpp ../../include/Ice/Outgoing.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/RequestHandlerF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ReferenceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../Ice/RequestHandler.h ../../include/Ice/OutgoingAsyncF.h ../Ice/ConnectionI.h ../../include/IceUtil/Thread.h ../../include/Ice/Connection.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/CommunicatorF.h ../../include/Ice/ConnectionFactoryF.h ../Ice/TransceiverF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/LoggerF.h ../Ice/TraceLevelsF.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThread.h ../../include/IceUtil/Timer.h ../Ice/SelectorThreadF.h ../Ice/Selector.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/Direct.h ../Ice/ReplyStatus.h +PluginManagerI$(OBJEXT): PluginManagerI.cpp ../Ice/PluginManagerI.h ../../include/Ice/Plugin.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/LoggerF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/InstanceF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/DynamicLibrary.h ../../include/Ice/Communicator.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Initialize.h ../../include/Ice/LocalException.h +Plugin$(OBJEXT): Plugin.cpp ../../include/Ice/Plugin.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/LoggerF.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +Process$(OBJEXT): Process.cpp ../../include/Ice/Process.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +PropertiesI$(OBJEXT): PropertiesI.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/Config.h ../Ice/PropertiesI.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Properties.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/LocalException.h ../Ice/PropertyNames.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h +Properties$(OBJEXT): Properties.cpp ../../include/Ice/Properties.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h PropertyNames$(OBJEXT): PropertyNames.cpp ../Ice/PropertyNames.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h Protocol$(OBJEXT): Protocol.cpp ../../include/Ice/Protocol.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h -ProtocolPluginFacade$(OBJEXT): ProtocolPluginFacade.cpp ../../include/Ice/ProtocolPluginFacade.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/ProtocolPluginFacadeF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointFactoryF.h ../../include/Ice/InstanceF.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointFactoryManager.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h -ProxyFactory$(OBJEXT): ProxyFactory.cpp ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Time.h ../Ice/ProxyFactory.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ReferenceF.h ../../include/Ice/ProxyF.h ../../include/Ice/Exception.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/LocatorInfo.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h -Proxy$(OBJEXT): Proxy.cpp ../../include/Ice/Proxy.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyF.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/Ice/Handle.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../Ice/ProxyFactory.h ../../include/Ice/InstanceF.h ../Ice/ReferenceFactory.h ../Ice/ReferenceFactoryF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../../include/Ice/RouterF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/BuiltinSequences.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/ConnectorF.h ../Ice/ThreadPoolF.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/Process.h ../../include/Ice/Incoming.h ../Ice/RouterInfo.h ../Ice/LocatorInfo.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../../include/Ice/Stream.h -ReferenceFactory$(OBJEXT): ReferenceFactory.cpp ../../include/Ice/Communicator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/ReferenceFactory.h ../Ice/ReferenceFactoryF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../../include/Ice/InstanceF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/BuiltinSequences.h ../Ice/ProxyFactory.h ../../include/Ice/LocalException.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/Initialize.h ../../include/Ice/StringConverter.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/RouterInfo.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Properties.h ../Ice/DefaultsAndOverrides.h ../Ice/PropertyNames.h ../../include/IceUtil/StringUtil.h -Reference$(OBJEXT): Reference.cpp ../Ice/Reference.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ReferenceF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/ReferenceFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/InstanceF.h ../../include/Ice/RouterF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/ReferenceFactory.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/RouterInfo.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/ConnectionFactory.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/Random.h -RouterInfo$(OBJEXT): RouterInfo.cpp ../Ice/RouterInfo.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/RouterInfoF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/RouterF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Router.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/LocatorF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h -Router$(OBJEXT): Router.cpp ../../include/Ice/Router.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -ServantLocator$(OBJEXT): ServantLocator.cpp ../../include/Ice/ServantLocator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -ServantManager$(OBJEXT): ServantManager.cpp ../Ice/ServantManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Identity.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/IceUtil/StringUtil.h -Service$(OBJEXT): Service.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/ArgVector.h ../../include/Ice/Service.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Application.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h ../Ice/LoggerI.h ../Ice/Network.h -SliceChecksumDict$(OBJEXT): SliceChecksumDict.cpp ../../include/Ice/SliceChecksumDict.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -SliceChecksums$(OBJEXT): SliceChecksums.cpp ../../include/Ice/SliceChecksums.h ../../include/Ice/SliceChecksumDict.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h -Stats$(OBJEXT): Stats.cpp ../../include/Ice/Stats.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h -StreamI$(OBJEXT): StreamI.cpp ../Ice/StreamI.h ../../include/Ice/Stream.h ../../include/Ice/StreamF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/BuiltinSequences.h -Stream$(OBJEXT): Stream.cpp ../../include/Ice/Stream.h ../../include/Ice/StreamF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Object.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h -StringConverter$(OBJEXT): StringConverter.cpp ../../include/Ice/StringConverter.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h ../../include/IceUtil/IceUtil.h ../../include/IceUtil/AbstractMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Algorithm.h ../../include/IceUtil/ArgVector.h ../../include/IceUtil/Base64.h ../../include/IceUtil/Cache.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/CountDownLatch.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/Functional.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/MD5.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Options.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/OutputUtil.h ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Random.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/UUID.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Timer.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h +ProtocolPluginFacade$(OBJEXT): ProtocolPluginFacade.cpp ../../include/Ice/ProtocolPluginFacade.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ProtocolPluginFacadeF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointFactoryF.h ../../include/Ice/InstanceF.h ../../include/Ice/EndpointIF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointFactoryManager.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h +ProxyFactory$(OBJEXT): ProxyFactory.cpp ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Time.h ../Ice/ProxyFactory.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ReferenceF.h ../../include/Ice/ProxyF.h ../../include/Ice/Exception.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/ReferenceFactory.h ../Ice/Reference.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/LocatorInfo.h ../../include/Ice/Properties.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h +Proxy$(OBJEXT): Proxy.cpp ../../include/Ice/Proxy.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ProxyF.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/IceUtil/Handle.h ../../include/Ice/Handle.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../Ice/ProxyFactory.h ../../include/Ice/InstanceF.h ../Ice/ReferenceFactory.h ../Ice/ReferenceFactoryF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../../include/Ice/RouterF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/BuiltinSequences.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/FacetMap.h ../../include/Ice/ObjectAdapterFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ServantManagerF.h ../Ice/ConnectorF.h ../Ice/ThreadPoolF.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../Ice/ConnectRequestHandler.h ../Ice/RequestHandler.h ../Ice/RouterInfo.h ../Ice/ConnectionRequestHandler.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/AcceptorF.h ../Ice/Instance.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/Process.h ../../include/Ice/Incoming.h ../Ice/LocatorInfo.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/SelectorThread.h ../Ice/Selector.h ../../include/Ice/Stream.h +ReferenceFactory$(OBJEXT): ReferenceFactory.cpp ../../include/Ice/Communicator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/PropertiesF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../Ice/ReferenceFactory.h ../Ice/ReferenceFactoryF.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../../include/Ice/InstanceF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../../include/Ice/BuiltinSequences.h ../Ice/ProxyFactory.h ../../include/Ice/LocalException.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/Initialize.h ../../include/Ice/StringConverter.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/EndpointFactoryManager.h ../../include/Ice/EndpointFactoryF.h ../Ice/RouterInfo.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Properties.h ../Ice/DefaultsAndOverrides.h ../Ice/PropertyNames.h ../../include/IceUtil/StringUtil.h +Reference$(OBJEXT): Reference.cpp ../Ice/Reference.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/RecMutex.h ../../include/Ice/ReferenceF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/ReferenceFactoryF.h ../../include/Ice/EndpointIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h ../../include/Ice/InstanceF.h ../../include/Ice/RouterF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocatorF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h ../Ice/ReferenceFactory.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../Ice/Instance.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/LoggerF.h ../../include/Ice/StringConverter.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/EndpointI.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../Ice/RouterInfo.h ../../include/Ice/Router.h ../Ice/LocatorInfo.h ../../include/Ice/Locator.h ../../include/Ice/IncomingAsync.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/ConnectionI.h ../../include/Ice/Connection.h ../Ice/EventHandler.h ../Ice/EventHandlerF.h ../Ice/SelectorThread.h ../Ice/Selector.h ../Ice/ConnectionFactory.h ../../include/Ice/LoggerUtil.h ../Ice/TraceLevels.h ../Ice/DefaultsAndOverrides.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/Random.h +RequestHandler$(OBJEXT): RequestHandler.cpp ../Ice/RequestHandler.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/LocalObject.h ../../include/Ice/LocalObjectF.h +RouterInfo$(OBJEXT): RouterInfo.cpp ../Ice/RouterInfo.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/RouterInfoF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/RouterF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Router.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LocalException.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/Reference.h ../../include/IceUtil/RecMutex.h ../Ice/ReferenceFactoryF.h ../../include/Ice/LocatorF.h ../Ice/LocatorInfoF.h ../Ice/SharedContext.h +Router$(OBJEXT): Router.cpp ../../include/Ice/Router.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/ObjectFactory.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +Selector$(OBJEXT): Selector.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/Selector.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/ProxyHandle.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h +SelectorThread$(OBJEXT): SelectorThread.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/SelectorThread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Timer.h ../../include/Ice/Config.h ../Ice/SelectorThreadF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/Selector.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h +ServantLocator$(OBJEXT): ServantLocator.cpp ../../include/Ice/ServantLocator.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +ServantManager$(OBJEXT): ServantManager.cpp ../Ice/ServantManager.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Identity.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LoggerUtil.h ../../include/Ice/LoggerF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/Direct.h ../../include/IceUtil/StringUtil.h +Service$(OBJEXT): Service.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/ArgVector.h ../../include/Ice/Service.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/LocalException.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/Logger.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Application.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h ../Ice/LoggerI.h ../Ice/Network.h +SliceChecksumDict$(OBJEXT): SliceChecksumDict.cpp ../../include/Ice/SliceChecksumDict.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +SliceChecksums$(OBJEXT): SliceChecksums.cpp ../../include/Ice/SliceChecksums.h ../../include/Ice/SliceChecksumDict.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/StaticMutex.h +Stats$(OBJEXT): Stats.cpp ../../include/Ice/Stats.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/DisableWarnings.h +StreamI$(OBJEXT): StreamI.cpp ../Ice/StreamI.h ../../include/Ice/Stream.h ../../include/Ice/StreamF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/BuiltinSequences.h +Stream$(OBJEXT): Stream.cpp ../../include/Ice/Stream.h ../../include/Ice/StreamF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h +StringConverter$(OBJEXT): StringConverter.cpp ../../include/Ice/StringConverter.h ../../include/Ice/Config.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Handle.h ../../include/IceUtil/IceUtil.h ../../include/IceUtil/AbstractMutex.h ../../include/IceUtil/Algorithm.h ../../include/IceUtil/ArgVector.h ../../include/IceUtil/Base64.h ../../include/IceUtil/Cache.h ../../include/IceUtil/CountDownLatch.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/CtrlCHandler.h ../../include/IceUtil/Functional.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/MD5.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Options.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/OutputUtil.h ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Random.h ../../include/IceUtil/ScopedArray.h ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/StringUtil.h ../../include/IceUtil/UUID.h ../../include/IceUtil/Unicode.h ../../include/IceUtil/Timer.h ../../include/Ice/LocalException.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h SysLoggerI$(OBJEXT): SysLoggerI.cpp ../Ice/SysLoggerI.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h -TcpAcceptor$(OBJEXT): TcpAcceptor.cpp ../Ice/TcpAcceptor.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/Acceptor.h ../Ice/AcceptorF.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h -TcpConnector$(OBJEXT): TcpConnector.cpp ../Ice/TcpConnector.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/Connector.h ../Ice/ConnectorF.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TcpEndpointI.h ../Ice/EndpointI.h ../../include/Ice/Endpoint.h ../../include/Ice/EndpointIF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h -TcpEndpointI$(OBJEXT): TcpEndpointI.cpp ../Ice/TcpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/TcpAcceptor.h ../Ice/TraceLevelsF.h ../Ice/Acceptor.h ../Ice/TcpConnector.h ../Ice/Connector.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/DefaultsAndOverrides.h -TcpTransceiver$(OBJEXT): TcpTransceiver.cpp ../Ice/TcpTransceiver.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TransceiverF.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../Ice/Network.h -ThreadPool$(OBJEXT): ThreadPool.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/ThreadPool.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../Ice/ThreadPoolF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../Ice/EventHandlerF.h ../Ice/EventHandler.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Network.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/ConnectorF.h ../../include/Ice/Properties.h -TraceLevels$(OBJEXT): TraceLevels.cpp ../Ice/TraceLevels.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/TraceLevelsF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/InstanceF.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h -TraceUtil$(OBJEXT): TraceUtil.cpp ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/StringUtil.h ../Ice/TraceUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/TraceLevelsF.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/Logger.h ../Ice/ReplyStatus.h -Transceiver$(OBJEXT): Transceiver.cpp ../Ice/Transceiver.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../Ice/TransceiverF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h -UdpConnector$(OBJEXT): UdpConnector.cpp ../Ice/UdpConnector.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/Connector.h ../Ice/ConnectorF.h ../Ice/UdpTransceiver.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../Ice/UdpEndpointI.h ../Ice/EndpointI.h ../../include/Ice/Endpoint.h ../../include/Ice/EndpointIF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h -UdpEndpointI$(OBJEXT): UdpEndpointI.cpp ../Ice/UdpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/UdpConnector.h ../Ice/Connector.h ../Ice/UdpTransceiver.h ../Ice/TraceLevelsF.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/DefaultsAndOverrides.h -UdpTransceiver$(OBJEXT): UdpTransceiver.cpp ../Ice/UdpTransceiver.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TransceiverF.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../Ice/Network.h ../../include/Ice/Properties.h -UnknownEndpointI$(OBJEXT): UnknownEndpointI.cpp ../Ice/UnknownEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/IceUtil/Base64.h -DLLMain$(OBJEXT): DLLMain.cpp ../Ice/EventLoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Service.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/RecMutex.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Application.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h -EventLoggerI$(OBJEXT): EventLoggerI.cpp ../Ice/EventLoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/EventLoggerMsg.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/IceUtil/StaticMutex.h +TcpAcceptor$(OBJEXT): TcpAcceptor.cpp ../Ice/TcpAcceptor.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/Acceptor.h ../Ice/AcceptorF.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Selector.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h +TcpConnector$(OBJEXT): TcpConnector.cpp ../Ice/TcpConnector.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/Connector.h ../Ice/ConnectorF.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Selector.h ../Ice/TcpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/EndpointIF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../Ice/Network.h +TcpEndpointI$(OBJEXT): TcpEndpointI.cpp ../Ice/TcpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/TcpAcceptor.h ../Ice/TraceLevelsF.h ../Ice/Acceptor.h ../Ice/TcpConnector.h ../Ice/Connector.h ../Ice/TcpTransceiver.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Selector.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/DefaultsAndOverrides.h +TcpTransceiver$(OBJEXT): TcpTransceiver.cpp ../Ice/TcpTransceiver.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TransceiverF.h ../Ice/Selector.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../Ice/Network.h +ThreadPool$(OBJEXT): ThreadPool.cpp ../../include/IceUtil/DisableWarnings.h ../Ice/ThreadPool.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../Ice/ThreadPoolF.h ../../include/Ice/Handle.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../Ice/EventHandlerF.h ../Ice/Selector.h ../Ice/EventHandler.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Network.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../Ice/ObjectAdapterFactory.h ../Ice/ObjectAdapterI.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../Ice/ConnectorF.h ../../include/Ice/Properties.h +TraceLevels$(OBJEXT): TraceLevels.cpp ../Ice/TraceLevels.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/TraceLevelsF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/PropertiesF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/BuiltinSequences.h +TraceUtil$(OBJEXT): TraceUtil.cpp ../../include/IceUtil/StaticMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/StringUtil.h ../Ice/TraceUtil.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/TraceLevelsF.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/InstanceF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/Logger.h ../Ice/ReplyStatus.h +Transceiver$(OBJEXT): Transceiver.cpp ../Ice/Transceiver.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../Ice/TransceiverF.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/Selector.h ../../include/Ice/InstanceF.h +UdpConnector$(OBJEXT): UdpConnector.cpp ../Ice/UdpConnector.h ../Ice/TransceiverF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/InstanceF.h ../Ice/Connector.h ../Ice/ConnectorF.h ../Ice/UdpTransceiver.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Selector.h ../Ice/UdpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/EndpointIF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h +UdpEndpointI$(OBJEXT): UdpEndpointI.cpp ../Ice/UdpEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../Ice/UdpConnector.h ../Ice/Connector.h ../Ice/UdpTransceiver.h ../Ice/TraceLevelsF.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/Selector.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/DefaultsAndOverrides.h +UdpTransceiver$(OBJEXT): UdpTransceiver.cpp ../Ice/UdpTransceiver.h ../../include/Ice/InstanceF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../Ice/TraceLevelsF.h ../../include/Ice/LoggerF.h ../../include/Ice/LocalObjectF.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/StatsF.h ../Ice/Transceiver.h ../Ice/TransceiverF.h ../Ice/Selector.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/CommunicatorF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/StringConverter.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../Ice/TraceLevels.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../Ice/Network.h ../../include/Ice/Properties.h +UnknownEndpointI$(OBJEXT): UnknownEndpointI.cpp ../Ice/UnknownEndpointI.h ../Ice/EndpointI.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/Endpoint.h ../../include/Ice/LocalObjectF.h ../../include/Ice/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../../include/Ice/EndpointIF.h ../../include/Ice/InstanceF.h ../Ice/TransceiverF.h ../Ice/ConnectorF.h ../Ice/AcceptorF.h ../../include/Ice/EndpointFactory.h ../../include/Ice/EndpointFactoryF.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/Ice/StringConverter.h ../../include/IceUtil/Unicode.h ../Ice/Instance.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Timer.h ../../include/Ice/CommunicatorF.h ../../include/Ice/StatsF.h ../Ice/TraceLevelsF.h ../Ice/DefaultsAndOverridesF.h ../Ice/RouterInfoF.h ../Ice/LocatorInfoF.h ../Ice/ReferenceFactoryF.h ../../include/Ice/ProxyFactoryF.h ../Ice/ThreadPoolF.h ../Ice/SelectorThreadF.h ../../include/Ice/ConnectionFactoryF.h ../../include/Ice/ConnectionMonitorF.h ../Ice/ObjectFactoryManagerF.h ../../include/Ice/ObjectAdapterFactoryF.h ../Ice/EndpointFactoryManagerF.h ../../include/Ice/DynamicLibraryF.h ../../include/Ice/PluginF.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Proxy.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/Ice/BuiltinSequences.h ../Ice/SharedContext.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/LocalException.h ../../include/Ice/FacetMap.h ../../include/Ice/Process.h ../../include/Ice/Outgoing.h ../../include/Ice/OutgoingAsync.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/IceUtil/Base64.h +DLLMain$(OBJEXT): DLLMain.cpp ../Ice/EventLoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/ImplicitContextI.h ../../include/Ice/ImplicitContext.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/LocalException.h ../../include/Ice/BuiltinSequences.h ../../include/Ice/Service.h ../../include/Ice/Ice.h ../../include/Ice/Initialize.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/InstanceF.h ../../include/Ice/LoggerF.h ../../include/Ice/StatsF.h ../../include/Ice/StringConverter.h ../../include/Ice/Properties.h ../../include/Ice/Outgoing.h ../../include/IceUtil/Monitor.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Time.h ../../include/Ice/BasicStream.h ../../include/Ice/ObjectFactoryF.h ../../include/Ice/Buffer.h ../../include/Ice/Protocol.h ../../include/IceUtil/Unicode.h ../../include/Ice/Incoming.h ../../include/Ice/ServantLocatorF.h ../../include/Ice/ServantManagerF.h ../../include/Ice/Direct.h ../../include/Ice/LoggerUtil.h ../../include/Ice/Stats.h ../../include/Ice/Communicator.h ../../include/Ice/RouterF.h ../../include/Ice/LocatorF.h ../../include/Ice/PluginF.h ../../include/Ice/ImplicitContextF.h ../../include/Ice/ObjectFactory.h ../../include/Ice/ObjectAdapter.h ../../include/Ice/FacetMap.h ../../include/Ice/ServantLocator.h ../../include/Ice/OutgoingAsync.h ../../include/IceUtil/Timer.h ../../include/IceUtil/Thread.h ../../include/Ice/IncomingAsync.h ../../include/Ice/Process.h ../../include/Ice/Application.h ../../include/Ice/Connection.h ../../include/Ice/Functional.h ../../include/IceUtil/Functional.h ../../include/Ice/Stream.h ../../include/Ice/Locator.h ../../include/Ice/UserExceptionFactory.h ../../include/Ice/FactoryTable.h ../../include/Ice/FactoryTableDef.h ../../include/IceUtil/StaticMutex.h ../../include/Ice/UserExceptionFactoryF.h ../../include/Ice/ProcessF.h ../../include/Ice/Router.h ../../include/Ice/DispatchInterceptor.h ../../include/Ice/IconvStringConverter.h +EventLoggerI$(OBJEXT): EventLoggerI.cpp ../Ice/EventLoggerI.h ../../include/Ice/Logger.h ../../include/Ice/LocalObjectF.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/Ice/Handle.h ../../include/IceUtil/Handle.h ../../include/Ice/Config.h ../../include/Ice/ProxyHandle.h ../../include/Ice/ProxyF.h ../../include/Ice/ObjectF.h ../../include/Ice/GCCountMap.h ../../include/Ice/GCShared.h ../../include/Ice/Exception.h ../../include/Ice/LocalObject.h ../../include/Ice/UndefSysMacros.h ../Ice/EventLoggerMsg.h ../../include/Ice/LocalException.h ../../include/Ice/Proxy.h ../../include/Ice/ProxyFactoryF.h ../../include/Ice/ConnectionIF.h ../../include/Ice/RequestHandlerF.h ../../include/Ice/EndpointIF.h ../../include/Ice/Endpoint.h ../../include/Ice/ObjectAdapterF.h ../../include/Ice/ReferenceF.h ../../include/Ice/OutgoingAsyncF.h ../../include/Ice/Current.h ../../include/Ice/ConnectionF.h ../../include/Ice/Identity.h ../../include/Ice/StreamF.h ../../include/Ice/CommunicatorF.h ../../include/Ice/BuiltinSequences.h ../Ice/Network.h ../../include/Ice/PropertiesF.h ../../include/Ice/Object.h ../../include/Ice/IncomingAsyncF.h ../../include/Ice/LoggerF.h ../../include/IceUtil/StaticMutex.h BuiltinSequences.cpp: ../../../slice/Ice/BuiltinSequences.ice CommunicatorF.cpp: ../../../slice/Ice/CommunicatorF.ice Communicator.cpp: ../../../slice/Ice/Communicator.ice ../../../slice/Ice/LoggerF.ice ../../../slice/Ice/StatsF.ice ../../../slice/Ice/ObjectAdapterF.ice ../../../slice/Ice/PropertiesF.ice ../../../slice/Ice/ObjectFactoryF.ice ../../../slice/Ice/RouterF.ice ../../../slice/Ice/LocatorF.ice ../../../slice/Ice/PluginF.ice ../../../slice/Ice/ImplicitContextF.ice ../../../slice/Ice/Current.ice ../../../slice/Ice/ConnectionF.ice ../../../slice/Ice/Identity.ice diff --git a/cpp/src/Ice/ConnectRequestHandler.cpp b/cpp/src/Ice/ConnectRequestHandler.cpp new file mode 100644 index 00000000000..f306b6c26b6 --- /dev/null +++ b/cpp/src/Ice/ConnectRequestHandler.cpp @@ -0,0 +1,412 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/ConnectRequestHandler.h> +#include <Ice/ConnectionRequestHandler.h> +#include <Ice/Instance.h> +#include <Ice/Proxy.h> +#include <Ice/ConnectionI.h> +#include <Ice/RouterInfo.h> +#include <Ice/Outgoing.h> +#include <Ice/OutgoingAsync.h> +#include <Ice/Protocol.h> +#include <Ice/Properties.h> + +using namespace std; +using namespace IceInternal; + +ConnectRequestHandler::ConnectRequestHandler(const ReferencePtr& ref, + const Ice::ObjectPrx& proxy, + const Handle< ::IceDelegate::Ice::Object>& delegate) : + RequestHandler(ref), + _proxy(proxy), + _delegate(delegate), + _response(ref->getMode() == Reference::ModeTwoway), + _batchAutoFlush( + ref->getInstance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.BatchAutoFlush", 1) > 0), + _initialized(false), + _flushing(false), + _batchRequestInProgress(false), + _batchRequestsSize(sizeof(requestBatchHdr)), + _batchStream(ref->getInstance().get(), _batchAutoFlush), + _updateRequestHandler(false) +{ +} + +ConnectRequestHandler::~ConnectRequestHandler() +{ +} + +RequestHandlerPtr +ConnectRequestHandler::connect() +{ + _reference->getConnection(this); + + Lock sync(*this); + if(_connection) + { + return new ConnectionRequestHandler(_reference, _connection, _compress); + } + else + { + _updateRequestHandler = true; // The proxy request handler will be updated when the connection is set. + return this; + } +} + +void +ConnectRequestHandler::prepareBatchRequest(BasicStream* os) +{ + { + Lock sync(*this); + while(_batchRequestInProgress) + { + wait(); + } + + if(!initialized()) + { + _batchRequestInProgress = true; + _batchStream.swap(*os); + return; + } + } + _connection->prepareBatchRequest(os); +} + +void +ConnectRequestHandler::finishBatchRequest(BasicStream* os) +{ + { + Lock sync(*this); + if(!initialized()) + { + assert(_batchRequestInProgress); + _batchRequestInProgress = false; + notifyAll(); + + _batchStream.swap(*os); + + if(!_batchAutoFlush && + _batchStream.b.size() + _batchRequestsSize > _reference->getInstance()->messageSizeMax()) + { + throw Ice::MemoryLimitException(__FILE__, __LINE__); + } + + _batchRequestsSize += _batchStream.b.size(); + + Request req; + req.os = new BasicStream(_reference->getInstance().get(), _batchAutoFlush); + req.os->swap(_batchStream); + _requests.push_back(req); + return; + } + } + _connection->finishBatchRequest(os, _compress); +} + +void +ConnectRequestHandler::abortBatchRequest() +{ + { + Lock sync(*this); + if(!initialized()) + { + assert(_batchRequestInProgress); + _batchRequestInProgress = false; + notifyAll(); + + BasicStream dummy(_reference->getInstance().get(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestsSize = sizeof(requestBatchHdr); + + return; + } + } + _connection->abortBatchRequest(); +} + +Ice::ConnectionI* +ConnectRequestHandler::sendRequest(Outgoing* out) +{ + return (!getConnection(true)->sendRequest(out, _compress, _response) || _response) ? _connection.get() : 0; +} + +void +ConnectRequestHandler::sendAsyncRequest(const OutgoingAsyncPtr& out) +{ + try + { + { + Lock sync(*this); + if(!initialized()) + { + Request req; + req.out = out; + _requests.push_back(req); + return; + } + } + _connection->sendAsyncRequest(out, _compress, _response); + } + catch(const LocalExceptionWrapper& ex) + { + out->__finished(ex); + } + catch(const Ice::LocalException& ex) + { + out->__finished(ex); + } +} + +bool +ConnectRequestHandler::flushBatchRequests(BatchOutgoing* out) +{ + return getConnection(true)->flushBatchRequests(out); +} + +void +ConnectRequestHandler::flushAsyncBatchRequests(const BatchOutgoingAsyncPtr& out) +{ + try + { + { + Lock sync(*this); + if(!initialized()) + { + Request req; + req.batchOut = out; + _requests.push_back(req); + return; + } + } + _connection->flushAsyncBatchRequests(out); + } + catch(const Ice::LocalException& ex) + { + out->__finished(ex); + } +} + +Ice::ConnectionIPtr +ConnectRequestHandler::getConnection(bool waitInit) +{ + if(waitInit) + { + // + // Wait for the connection establishment to complete or fail. + // + Lock sync(*this); + while(!_initialized && !_exception.get()) + { + wait(); + } + } + + if(_exception.get()) + { + _exception->ice_throw(); + return false; // Keep the compiler happy. + } + else + { + assert(!waitInit || _initialized); + return _connection; + } +} + +void +ConnectRequestHandler::setConnection(const Ice::ConnectionIPtr& connection, bool compress) +{ + { + Lock sync(*this); + _connection = connection; + _compress = compress; + } + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + RouterInfoPtr ri = _reference->getRouterInfo(); + if(ri) + { + if(!ri->addProxy(_proxy, this)) + { + return; // The request handler will be initialized once addProxy returns. + } + } + + flushRequests(); +} + +void +ConnectRequestHandler::setException(const Ice::LocalException& ex) +{ + { + Lock sync(*this); + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + _proxy = 0; // Break cyclic reference count. + _delegate = 0; // Break cyclic reference count. + notifyAll(); + } + + for(vector<Request>::const_iterator p = _requests.begin(); p != _requests.end(); ++p) + { + if(p->out) + { + p->out->__finished(ex); + } + else if(p->batchOut) + { + p->batchOut->__finished(ex); + } + else + { + assert(p->os); + delete p->os; + } + } + _requests.clear(); +} + +void +ConnectRequestHandler::addedProxy() +{ + flushRequests(); +} + +bool +ConnectRequestHandler::initialized() +{ + // Must be called with the mutex locked. + + if(_initialized) + { + assert(_connection); + return true; + } + else + { + while(_flushing) + { + wait(); + } + + if(_exception.get()) + { + _exception->ice_throw(); + return false; // Keep the compiler happy. + } + else + { + return _initialized; + } + } +} + +void +ConnectRequestHandler::flushRequests() +{ + { + Lock sync(*this); + assert(_connection); + + while(_batchRequestInProgress) + { + wait(); + } + + // + // We set the _flushing flag to true to prevent any additional queuing. Callers + // might block for a little while as the queued requests are being sent but this + // shouldn't be an issue as the request sends are non-blocking. + // + _flushing = true; + } + + for(vector<Request>::const_iterator p = _requests.begin(); p != _requests.end(); ++p) + { + // _requests is immutable when _flushing = true + if(p->out) + { + try + { + _connection->sendAsyncRequest(p->out, _compress, _response); + } + catch(const LocalExceptionWrapper& ex) + { + p->out->__finished(ex); + } + catch(const Ice::LocalException& ex) + { + p->out->__finished(ex); + } + } + else if(p->batchOut) + { + try + { + _connection->flushAsyncBatchRequests(p->batchOut); + } + catch(const Ice::LocalException& ex) + { + p->batchOut->__finished(ex); + } + } + else + { + assert(p->os); + if(_exception.get()) + { + delete p->os; + } + else + { + // + // TODO: Add sendBatchRequest() method to ConnectionI? + // + try + { + BasicStream os(p->os->instance()); + _connection->prepareBatchRequest(&os); + const Ice::Byte* bytes; + p->os->i = p->os->b.begin(); + p->os->readBlob(bytes, p->os->b.size()); + os.writeBlob(bytes, p->os->b.size()); + _connection->finishBatchRequest(&os, _compress); + delete p->os; + } + catch(const Ice::LocalException& ex) + { + delete p->os; + _connection->abortBatchRequest(); + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + } + } + } + } + _requests.clear(); + + { + Lock sync(*this); + _initialized = true; + _flushing = false; + notifyAll(); + } + + if(_updateRequestHandler && !_exception.get()) + { + _proxy->__setRequestHandler(_delegate, new ConnectionRequestHandler(_reference, _connection, _compress)); + } + _proxy = 0; // Break cyclic reference count. + _delegate = 0; // Break cyclic reference count. +} + + diff --git a/cpp/src/Ice/ConnectRequestHandler.h b/cpp/src/Ice/ConnectRequestHandler.h new file mode 100644 index 00000000000..bdf8d1b3a16 --- /dev/null +++ b/cpp/src/Ice/ConnectRequestHandler.h @@ -0,0 +1,88 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_CONNECT_REQUEST_HANDLER_H +#define ICE_CONNECT_REQUEST_HANDLER_H + +#include <IceUtil/Monitor.h> +#include <IceUtil/Mutex.h> + +#include <Ice/RequestHandler.h> +#include <Ice/Reference.h> +#include <Ice/RouterInfo.h> +#include <Ice/ProxyF.h> +#include <Ice/BasicStream.h> + +namespace IceInternal +{ + +class ConnectRequestHandler : public RequestHandler, + public Reference::GetConnectionCallback, + public RouterInfo::AddProxyCallback, + public IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + ConnectRequestHandler(const ReferencePtr&, const Ice::ObjectPrx&, const Handle< ::IceDelegate::Ice::Object>&); + virtual ~ConnectRequestHandler(); + + RequestHandlerPtr connect(); + + virtual void prepareBatchRequest(BasicStream*); + virtual void finishBatchRequest(BasicStream*); + virtual void abortBatchRequest(); + + virtual Ice::ConnectionI* sendRequest(Outgoing*); + virtual void sendAsyncRequest(const OutgoingAsyncPtr&); + + virtual bool flushBatchRequests(BatchOutgoing*); + virtual void flushAsyncBatchRequests(const BatchOutgoingAsyncPtr&); + + virtual Ice::ConnectionIPtr getConnection(bool); + + virtual void setConnection(const Ice::ConnectionIPtr&, bool); + virtual void setException(const Ice::LocalException&); + + virtual void addedProxy(); + +private: + + bool initialized(); + void flushRequests(); + + struct Request + { + OutgoingAsyncPtr out; + BatchOutgoingAsyncPtr batchOut; + BasicStream* os; + }; + + Ice::ObjectPrx _proxy; + Handle< ::IceDelegate::Ice::Object> _delegate; + + const bool _response; + const bool _batchAutoFlush; + + Ice::ConnectionIPtr _connection; + bool _compress; + std::auto_ptr<Ice::LocalException> _exception; + bool _initialized; + bool _flushing; + + std::vector<Request> _requests; + bool _batchRequestInProgress; + size_t _batchRequestsSize; + BasicStream _batchStream; + bool _updateRequestHandler; +}; +typedef IceUtil::Handle<ConnectRequestHandler> ConnectRequestHandlerPtr; + +} + +#endif diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index af2b506193d..6d69a36cb84 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -38,6 +38,7 @@ IceUtil::Shared* IceInternal::upCast(IncomingConnectionFactory* p) { return p; } namespace { + struct RandomNumberGenerator : public std::unary_function<ptrdiff_t, ptrdiff_t> { ptrdiff_t operator()(ptrdiff_t d) @@ -45,6 +46,22 @@ struct RandomNumberGenerator : public std::unary_function<ptrdiff_t, ptrdiff_t> return IceUtil::random(static_cast<int>(d)); } }; + +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectorInfo::operator<(const ConnectorInfo& other) const +{ + if(!threadPerConnection && other.threadPerConnection) + { + return true; + } + else if(other.threadPerConnection < threadPerConnection) + { + return false; + } + + return connector < other.connector; } void @@ -60,11 +77,11 @@ IceInternal::OutgoingConnectionFactory::destroy() #ifdef _STLP_BEGIN_NAMESPACE // voidbind2nd is an STLport extension for broken compilers in IceUtil/Functional.h for_each(_connections.begin(), _connections.end(), - voidbind2nd(Ice::secondVoidMemFun1<ConnectorPtr, ConnectionI, ConnectionI::DestructionReason> + voidbind2nd(Ice::secondVoidMemFun1<ConnectorInfo, ConnectionI, ConnectionI::DestructionReason> (&ConnectionI::destroy), ConnectionI::CommunicatorDestroyed)); #else for_each(_connections.begin(), _connections.end(), - bind2nd(Ice::secondVoidMemFun1<const ConnectorPtr, ConnectionI, ConnectionI::DestructionReason> + bind2nd(Ice::secondVoidMemFun1<const ConnectorInfo, ConnectionI, ConnectionI::DestructionReason> (&ConnectionI::destroy), ConnectionI::CommunicatorDestroyed)); #endif @@ -75,7 +92,7 @@ IceInternal::OutgoingConnectionFactory::destroy() void IceInternal::OutgoingConnectionFactory::waitUntilFinished() { - multimap<ConnectorPtr, ConnectionIPtr> connections; + multimap<ConnectorInfo, ConnectionIPtr> connections; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); @@ -85,7 +102,7 @@ IceInternal::OutgoingConnectionFactory::waitUntilFinished() // until there are no pending connections anymore. Only then // we can be sure the _connections contains all connections. // - while(!_destroyed || !_pending.empty()) + while(!_destroyed || !_pending.empty() || !_pendingEndpoints.empty()) { wait(); } @@ -94,311 +111,187 @@ IceInternal::OutgoingConnectionFactory::waitUntilFinished() // We want to wait until all connections are finished outside the // thread synchronization. // - connections.swap(_connections); + connections = _connections; } for_each(connections.begin(), connections.end(), - Ice::secondVoidMemFun<const ConnectorPtr, ConnectionI>(&ConnectionI::waitUntilFinished)); + Ice::secondVoidMemFun<const ConnectorInfo, ConnectionI>(&ConnectionI::waitUntilFinished)); + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _connections.clear(); + } } ConnectionIPtr -IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool moreEndpts, +IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool hasMore, bool threadPerConnection, Ice::EndpointSelectionType selType, bool& compress) { assert(!endpts.empty()); - vector<pair<ConnectorPtr, EndpointIPtr> > connectors; + + // + // Apply the overrides. + // + vector<EndpointIPtr> endpoints = applyOverrides(endpts); + // + // Try to find a connection to one of the given endpoints. + // + Ice::ConnectionIPtr connection = findConnection(endpoints, threadPerConnection, compress); + if(connection) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + return connection; + } - if(_destroyed) - { - throw CommunicatorDestroyedException(__FILE__, __LINE__); - } + auto_ptr<Ice::LocalException> exception; + // + // If we didn't find a connection with the endpoints, we create the connectors + // for the endpoints. + // + vector<ConnectorInfo> connectors; + for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { // - // Reap connections for which destruction has completed. + // Create connectors for the endpoint. // - std::multimap<ConnectorPtr, ConnectionIPtr>::iterator p = _connections.begin(); - while(p != _connections.end()) - { - if(p->second->isFinished()) - { - _connections.erase(p++); - } - else - { - ++p; - } - } - - vector<EndpointIPtr> endpoints = endpts; - vector<EndpointIPtr>::iterator q; - for(q = endpoints.begin(); q != endpoints.end(); ++q) + try { - // - // Modify endpoints with overrides. - // - if(_instance->defaultsAndOverrides()->overrideTimeout) - { - *q = (*q)->timeout(_instance->defaultsAndOverrides()->overrideTimeoutValue); - } - - // - // Create connectors for the endpoints. - // - vector<ConnectorPtr> cons = (*q)->connectors(); - assert(cons.size() > 0); - - // - // Shuffle connectors is endpoint selection type is Random. - // + vector<ConnectorPtr> cons = (*p)->connectors(); + assert(!cons.empty()); + if(selType == Random) { RandomNumberGenerator rng; random_shuffle(cons.begin(), cons.end(), rng); } - - vector<ConnectorPtr>::const_iterator r; - for(r = cons.begin(); r != cons.end(); ++r) - { - connectors.push_back(make_pair(*r, *q)); - } - } - - // - // Search for existing connections. - // - vector<pair<ConnectorPtr, EndpointIPtr> >::const_iterator r; - for(r = connectors.begin(); r != connectors.end(); ++r) - { - pair<multimap<ConnectorPtr, ConnectionIPtr>::iterator, - multimap<ConnectorPtr, ConnectionIPtr>::iterator> pr = _connections.equal_range((*r).first); - while(pr.first != pr.second) + for(vector<ConnectorPtr>::const_iterator r = cons.begin(); r != cons.end(); ++r) { - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!pr.first->second->isDestroyed() && - pr.first->second->threadPerConnection() == threadPerConnection) - { - if(_instance->defaultsAndOverrides()->overrideCompress) - { - compress = _instance->defaultsAndOverrides()->overrideCompressValue; - } - else - { - compress = (*r).second->compress(); - } - - return pr.first->second; - } - - ++pr.first; + assert(*r); + connectors.push_back(ConnectorInfo(*r, *p, threadPerConnection)); } } - - // - // If some other thread is currently trying to establish a - // connection to any of our endpoints, we wait until this - // thread is finished. - // - bool searchAgain = false; - while(!_destroyed) + catch(const Ice::LocalException& ex) { - for(r = connectors.begin(); r != connectors.end(); ++r) - { - if(_pending.find((*r).first) != _pending.end()) - { - break; - } - } - - if(r == connectors.end()) - { - break; - } - - searchAgain = true; - - wait(); - } - - if(_destroyed) - { - throw CommunicatorDestroyedException(__FILE__, __LINE__); - } - - // - // Search for existing connections again if we waited above, - // as new connections might have been added in the meantime. - // - if(searchAgain) - { - for(r = connectors.begin(); r != connectors.end(); ++r) - { - pair<multimap<ConnectorPtr, ConnectionIPtr>::iterator, - multimap<ConnectorPtr, ConnectionIPtr>::iterator> pr = _connections.equal_range((*r).first); - - while(pr.first != pr.second) - { - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!pr.first->second->isDestroyed() && - pr.first->second->threadPerConnection() == threadPerConnection) - { - if(_instance->defaultsAndOverrides()->overrideCompress) - { - compress = _instance->defaultsAndOverrides()->overrideCompressValue; - } - else - { - compress = (*r).second->compress(); - } - - return pr.first->second; - } - - ++pr.first; - } - } - } - - // - // No connection to any of our endpoints exists yet, so we - // will try to create one. To avoid that other threads try to - // create connections to the same endpoints, we add our - // endpoints to _pending. - // - for(r = connectors.begin(); r != connectors.end(); ++r) - { - _pending.insert((*r).first); + exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + handleException(ex, hasMore || p != endpoints.end() - 1); } } - ConnectorPtr connector; - ConnectionIPtr connection; - auto_ptr<LocalException> exception; + if(connectors.empty()) + { + assert(exception.get()); + exception->ice_throw(); + } - vector<pair<ConnectorPtr, EndpointIPtr> >::const_iterator q; - for(q = connectors.begin(); q != connectors.end(); ++q) + // + // Try to get a connection to one of the connectors. A null result indicates that no + // connection was found and that we should try to establish the connection (and that + // the connectors were added to _pending to prevent other threads from establishing + // the connection). + // + connection = getConnection(connectors, 0, compress); + if(connection) + { + return connection; + } + + // + // Try to establish the connection to the connectors. + // + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) { - connector = (*q).first; - EndpointIPtr endpoint = (*q).second; - try { - int timeout; - if(_instance->defaultsAndOverrides()->overrideConnectTimeout) + if(defaultsAndOverrides->overrideConnectTimeout) { - timeout = _instance->defaultsAndOverrides()->overrideConnectTimeoutValue; + timeout = defaultsAndOverrides->overrideConnectTimeoutValue; } - // It is not necessary to check for overrideTimeout, - // the endpoint has already been modified with this - // override, if set. else { - timeout = endpoint->timeout(); + // + // It is not necessary to check for overrideTimeout, the endpoint has already + // been modified with this override, if set. + // + timeout = p->endpoint->timeout(); } - TransceiverPtr transceiver = connector->connect(timeout); - assert(transceiver); - - connection = new ConnectionI(_instance, transceiver, endpoint->compress(false), 0, threadPerConnection, - _instance->threadPerConnectionStackSize()); - connection->start(); - connection->validate(); + connection = createConnection(p->connector->connect(timeout), *p); + connection->start(0); - if(_instance->defaultsAndOverrides()->overrideCompress) + if(defaultsAndOverrides->overrideCompress) { - compress = _instance->defaultsAndOverrides()->overrideCompressValue; + compress = defaultsAndOverrides->overrideCompressValue; } else { - compress = endpoint->compress(); + compress = p->endpoint->compress(); } + break; } - catch(const LocalException& ex) + catch(const Ice::CommunicatorDestroyedException& ex) { - exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); - - // - // If a connection object was constructed, then validate() - // must have raised the exception. - // - if(connection) - { - connection->waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - connection = 0; - } + exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + handleException(*exception.get(), *p, connection, hasMore || p != connectors.end() - 1); + connection = 0; + break; // No need to continue } - - TraceLevelsPtr traceLevels = _instance->traceLevels(); - if(traceLevels->retry >= 2) + catch(const Ice::LocalException& ex) { - Trace out(_instance->initializationData().logger, traceLevels->retryCat); - - out << "connection to endpoint failed"; - if(moreEndpts || q + 1 != connectors.end()) - { - out << ", trying next endpoint\n"; - } - else - { - out << " and no more endpoints to try\n"; - } - out << *exception.get(); + exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + handleException(*exception.get(), *p, connection, hasMore || p != connectors.end() - 1); + connection = 0; } } - - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - // - // Signal other threads that we are done with trying to - // establish connections to our endpoints. - // - for(q = connectors.begin(); q != connectors.end(); ++q) - { - _pending.erase((*q).first); - } - notifyAll(); - if(!connection) - { - assert(exception.get()); - exception->ice_throw(); - } - else - { - _connections.insert(_connections.end(), pair<const ConnectorPtr, ConnectionIPtr>(connector, connection)); + // + // Finish creating the connection (this removes the connectors from the _pending + // list and notifies any waiting threads). + // + finishGetConnection(connectors, 0, connection); - if(_destroyed) - { - connection->destroy(ConnectionI::CommunicatorDestroyed); - throw CommunicatorDestroyedException(__FILE__, __LINE__); - } - else - { - connection->activate(); - } - } + if(!connection) + { + assert(exception.get()); + exception->ice_throw(); } - assert(connection); return connection; } void +IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool hasMore, + bool tpc, Ice::EndpointSelectionType selType, + const CreateConnectionCallbackPtr& callback) +{ + assert(!endpts.empty()); + + // + // Apply the overrides. + // + vector<EndpointIPtr> endpoints = applyOverrides(endpts); + + // + // Try to find a connection to one of the given endpoints. + // + bool compress; + Ice::ConnectionIPtr connection = findConnection(endpoints, tpc, compress); + if(connection) + { + callback->setConnection(connection, compress); + return; + } + + ConnectCallbackPtr cb = new ConnectCallback(this, endpoints, hasMore, callback, selType, tpc); + cb->getConnection(); +} + +void IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& routerInfo) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); @@ -442,14 +335,14 @@ IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& route // endpoint = endpoint->compress(false); - multimap<ConnectorPtr, ConnectionIPtr>::const_iterator q; + multimap<ConnectorInfo, ConnectionIPtr>::const_iterator q; for(q = _connections.begin(); q != _connections.end(); ++q) { - if((*q).second->endpoint() == endpoint) + if(q->second->endpoint() == endpoint) { try { - (*q).second->setAdapter(adapter); + q->second->setAdapter(adapter); } catch(const Ice::LocalException&) { @@ -472,7 +365,7 @@ IceInternal::OutgoingConnectionFactory::removeAdapter(const ObjectAdapterPtr& ad return; } - for(multimap<ConnectorPtr, ConnectionIPtr>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) + for(multimap<ConnectorInfo, ConnectionIPtr>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) { if(p->second->getAdapter() == adapter) { @@ -497,9 +390,7 @@ IceInternal::OutgoingConnectionFactory::flushBatchRequests() { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - for(std::multimap<ConnectorPtr, ConnectionIPtr>::const_iterator p = _connections.begin(); - p != _connections.end(); + for(multimap<ConnectorInfo, ConnectionIPtr>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) { c.push_back(p->second); @@ -531,6 +422,668 @@ IceInternal::OutgoingConnectionFactory::~OutgoingConnectionFactory() assert(_connections.empty()); } +vector<EndpointIPtr> +IceInternal::OutgoingConnectionFactory::applyOverrides(const vector<EndpointIPtr>& endpts) +{ + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + vector<EndpointIPtr> endpoints = endpts; + for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + // + // Modify endpoints with overrides. + // + if(defaultsAndOverrides->overrideTimeout) + { + *p = (*p)->timeout(defaultsAndOverrides->overrideTimeoutValue); + } + } + return endpoints; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::findConnection(const vector<EndpointIPtr>& endpoints, bool tpc, bool& compress) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + assert(!endpoints.empty()); + for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + pair<multimap<EndpointIPtr, ConnectionIPtr>::iterator, + multimap<EndpointIPtr, ConnectionIPtr>::iterator> pr = _connectionsByEndpoint.equal_range(*p); + + for(multimap<EndpointIPtr, ConnectionIPtr>::iterator q = pr.first; q != pr.second; ++q) + { + if(q->second->isActiveOrHolding() && + q->second->threadPerConnection() == tpc) // Don't return destroyed or un-validated connections + { + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = (*p)->compress(); + } + return q->second; + } + } + } + return 0; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::findConnection(const vector<ConnectorInfo>& connectors, bool& compress) +{ + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + pair<multimap<ConnectorInfo, ConnectionIPtr>::iterator, + multimap<ConnectorInfo, ConnectionIPtr>::iterator> pr = _connections.equal_range(*p); + + if(pr.first == pr.second) + { + continue; + } + + for(multimap<ConnectorInfo, ConnectionIPtr>::iterator q = pr.first; q != pr.second; ++q) + { + if(q->second->isActiveOrHolding()) // Don't return destroyed or un-validated connections + { + if(q->second->endpoint() != p->endpoint) + { + _connectionsByEndpoint.insert(make_pair(p->endpoint, q->second)); + } + + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = p->endpoint->compress(); + } + return q->second; + } + } + } + + return 0; +} + +void +IceInternal::OutgoingConnectionFactory::addPendingEndpoints(const vector<EndpointIPtr>& endpoints) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + _pendingEndpoints.insert(endpoints.begin(), endpoints.end()); +} + +void +IceInternal::OutgoingConnectionFactory::removePendingEndpoints(const vector<EndpointIPtr>& endpoints) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + assert(_pendingEndpoints.find(*p) != _pendingEndpoints.end()); + _pendingEndpoints.erase(_pendingEndpoints.find(*p)); + } + + if(_destroyed) + { + notifyAll(); + } +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::getConnection(const vector<ConnectorInfo>& connectors, + const ConnectCallbackPtr& cb, bool& compress) +{ + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + // + // Reap connections for which destruction has completed. + // + multimap<ConnectorInfo, ConnectionIPtr>::iterator p = _connections.begin(); + while(p != _connections.end()) + { + if(p->second->isFinished()) + { + _connections.erase(p++); + } + else + { + ++p; + } + } + + multimap<EndpointIPtr, ConnectionIPtr>::iterator q = _connectionsByEndpoint.begin(); + while(q != _connectionsByEndpoint.end()) + { + if(q->second->isFinished()) + { + _connectionsByEndpoint.erase(q++); + } + else + { + ++q; + } + } + + // + // Try to get the connection. We may need to wait for other threads to + // finish if one of them is currently establishing a connection to one + // of our connectors. + // + while(!_destroyed) + { + // + // Search for a matching connection. If we find one, we're done. + // + Ice::ConnectionIPtr connection = findConnection(connectors, compress); + if(connection) + { + if(cb) + { + // + // This might not be the first getConnection call for the callback. We need + // to ensure that the callback isn't registered with any other pending + // connectors since we just found a connection and therefore don't need to + // wait anymore for other pending connectors. + // + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map<ConnectorInfo, set<ConnectCallbackPtr> >::iterator q = _pending.find(*p); + if(q != _pending.end()) + { + q->second.erase(cb); + } + } + } + return connection; + } + + // + // Determine whether another thread is currently attempting to connect to one of our endpoints; + // if so we wait until it's done. + // + bool found = false; + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map<ConnectorInfo, set<ConnectCallbackPtr> >::iterator q = _pending.find(*p); + if(q != _pending.end()) + { + found = true; + if(cb) + { + q->second.insert(cb); // Add the callback to each pending connector. + } + } + } + + if(!found) + { + // + // If no thread is currently establishing a connection to one of our connectors, + // we get out of this loop and start the connection establishment to one of the + // given connectors. + // + break; + } + else + { + // + // If a callback is not specified we wait until another thread notifies us about a + // change to the pending list. Otherwise, if a callback is provided we're done: + // when the pending list changes the callback will be notified and will try to + // get the connection again. + // + if(!cb) + { + wait(); + } + else + { + return 0; + } + } + } + + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + // + // No connection to any of our endpoints exists yet; we add the given connectors to + // the _pending set to indicate that we're attempting connection establishment to + // these connectors. + // + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + assert(_pending.find(*p) == _pending.end()); + _pending.insert(pair<ConnectorInfo, set<ConnectCallbackPtr> >(*p, set<ConnectCallbackPtr>())); + } + } + + // + // At this point, we're responsible for establishing the connection to one of + // the given connectors. If it's a non-blocking connect, calling nextConnector + // will start the connection establishment. Otherwise, we return null to get + // the caller to establish the connection. + // + if(cb) + { + cb->nextConnector(); + } + + return 0; +} + +ConnectionIPtr +IceInternal::OutgoingConnectionFactory::createConnection(const TransceiverPtr& transceiver, const ConnectorInfo& ci) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(_pending.find(ci) != _pending.end() && transceiver); + + // + // Create and add the connection to the connection map. Adding the connection to the map + // is necessary to support the interruption of the connection initialization and validation + // in case the communicator is destroyed. + // + try + { + if(_destroyed) + { + throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); + } + + Ice::ConnectionIPtr connection = new ConnectionI(_instance, transceiver, ci.endpoint->compress(false), + 0, ci.threadPerConnection, + _instance->threadPerConnectionStackSize()); + _connections.insert(make_pair(ci, connection)); + _connectionsByEndpoint.insert(make_pair(ci.endpoint, connection)); + return connection; + } + catch(const Ice::LocalException&) + { + try + { + transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Ignore + } + throw; + } +} + +void +IceInternal::OutgoingConnectionFactory::finishGetConnection(const vector<ConnectorInfo>& connectors, + const ConnectCallbackPtr& cb, + const ConnectionIPtr& connection) +{ + vector<ConnectCallbackPtr> callbacks; + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + // + // We're done trying to connect to the given connectors so we remove the + // connectors from the pending list and notify waiting threads. We also + // notify the pending connect callbacks (outside the synchronization). + // + + for(vector<ConnectorInfo>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + map<ConnectorInfo, set<ConnectCallbackPtr> >::iterator q = _pending.find(*p); + assert(q != _pending.end()); + callbacks.insert(callbacks.end(), q->second.begin(), q->second.end()); + _pending.erase(q); + } + notifyAll(); + + // + // If the connect attempt succeeded and the communicator is not destroyed, + // activate the connection! + // + if(connection && !_destroyed) + { + connection->activate(); + } + } + + // + // Notify any waiting callbacks. + // + for(vector<ConnectCallbackPtr>::const_iterator p = callbacks.begin(); p != callbacks.end(); ++p) + { + (*p)->getConnection(); + } +} + +void +IceInternal::OutgoingConnectionFactory::handleException(const LocalException& ex, const ConnectorInfo& ci, + const ConnectionIPtr& connection, bool hasMore) +{ + TraceLevelsPtr traceLevels = _instance->traceLevels(); + if(traceLevels->retry >= 2) + { + Trace out(_instance->initializationData().logger, traceLevels->retryCat); + + out << "connection to endpoint failed"; + if(dynamic_cast<const CommunicatorDestroyedException*>(&ex)) + { + out << "\n"; + } + else + { + if(hasMore) + { + out << ", trying next endpoint\n"; + } + else + { + out << " and no more endpoints to try\n"; + } + } + out << ex; + } + + if(connection && connection->isFinished()) + { + // + // If the connection is finished, we remove it right away instead of + // waiting for the reaping. + // + // NOTE: it's possible for the connection to not be finished yet. That's + // for instance the case when using thread per connection and if it's the + // thread which is calling back the outgoing connection factory to notify + // it of the failure. + // + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + pair<multimap<ConnectorInfo, ConnectionIPtr>::iterator, + multimap<ConnectorInfo, ConnectionIPtr>::iterator> pr = _connections.equal_range(ci); + + for(multimap<ConnectorInfo, ConnectionIPtr>::iterator p = pr.first; p != pr.second; ++p) + { + if(p->second == connection) + { + _connections.erase(p); + break; + } + } + + pair<multimap<EndpointIPtr, ConnectionIPtr>::iterator, + multimap<EndpointIPtr, ConnectionIPtr>::iterator> qr = _connectionsByEndpoint.equal_range(ci.endpoint); + + for(multimap<EndpointIPtr, ConnectionIPtr>::iterator q = qr.first; q != qr.second; ++q) + { + if(q->second == connection) + { + _connectionsByEndpoint.erase(q); + break; + } + } + } + } +} + +void +IceInternal::OutgoingConnectionFactory::handleException(const LocalException& ex, bool hasMore) +{ + TraceLevelsPtr traceLevels = _instance->traceLevels(); + if(traceLevels->retry >= 2) + { + Trace out(_instance->initializationData().logger, traceLevels->retryCat); + + out << "couldn't resolve endpoint host"; + if(dynamic_cast<const CommunicatorDestroyedException*>(&ex)) + { + out << "\n"; + } + else + { + if(hasMore) + { + out << ", trying next endpoint\n"; + } + else + { + out << " and no more endpoints to try\n"; + } + } + out << ex; + } +} + +IceInternal::OutgoingConnectionFactory::ConnectCallback::ConnectCallback(const OutgoingConnectionFactoryPtr& factory, + const vector<EndpointIPtr>& endpoints, + bool hasMore, + const CreateConnectionCallbackPtr& cb, + Ice::EndpointSelectionType selType, + bool threadPerConnection) : + _factory(factory), + _selectorThread(_factory->_instance->selectorThread()), + _endpoints(endpoints), + _hasMore(hasMore), + _callback(cb), + _selType(selType), + _threadPerConnection(threadPerConnection) +{ + _endpointsIter = _endpoints.begin(); +} + +// +// Methods from ConnectionI.StartCallback +// +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectionStartCompleted(const ConnectionIPtr& connection) +{ + assert(!_exception.get() && connection == _connection); + + bool compress; + DefaultsAndOverridesPtr defaultsAndOverrides = _factory->_instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideCompress) + { + compress = defaultsAndOverrides->overrideCompressValue; + } + else + { + compress = _iter->endpoint->compress(); + } + + _factory->finishGetConnection(_connectors, this, connection); + _factory->removePendingEndpoints(_endpoints); + _callback->setConnection(connection, compress); +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectionStartFailed(const ConnectionIPtr& connection, + const LocalException& ex) +{ + assert(!_exception.get() && connection == _connection); + + _exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); + handleException(); +} + +// +// Methods from EndpointI_connectors +// +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::connectors(const vector<ConnectorPtr>& connectors) +{ + vector<ConnectorPtr> cons = connectors; + if(_selType == Random) + { + RandomNumberGenerator rng; + random_shuffle(cons.begin(), cons.end(), rng); + } + + for(vector<ConnectorPtr>::const_iterator p = cons.begin(); p != cons.end(); ++p) + { + _connectors.push_back(ConnectorInfo(*p, *_endpointsIter, _threadPerConnection)); + } + + if(++_endpointsIter != _endpoints.end()) + { + (*_endpointsIter)->connectors_async(this); + } + else + { + assert(!_connectors.empty()); + + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.begin(); + getConnection(); + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::exception(const Ice::LocalException& ex) +{ + _factory->handleException(ex, _hasMore || _endpointsIter != _endpoints.end() - 1); + if(++_endpointsIter != _endpoints.end()) + { + (*_endpointsIter)->connectors_async(this); + } + else if(!_connectors.empty()) + { + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.begin(); + getConnection(); + } + else + { + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + _factory->_instance->clientThreadPool()->execute(this); + } +} + +// +// Methods from ThreadPoolWorkItem +// +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::execute(const ThreadPoolPtr& threadPool) +{ + threadPool->promoteFollower(); + assert(_exception.get()); + _factory->removePendingEndpoints(_endpoints); + _callback->setException(*_exception.get()); +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::getConnection() +{ + // + // First, get the connectors for all the endpoints. + // + if(_endpointsIter != _endpoints.end()) + { + try + { + _factory->addPendingEndpoints(_endpoints); + (*_endpointsIter)->connectors_async(this); + } + catch(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + return; + } + + try + { + // + // If all the connectors have been created, we ask the factory to get a + // connection. + // + bool compress; + Ice::ConnectionIPtr connection = _factory->getConnection(_connectors, this, compress); + if(!connection) + { + // + // A null return value from getConnection indicates that the connection + // is being established and that everthing has been done to ensure that + // the callback will be notified when the connection establishment is + // done. + // + return; + } + + _factory->removePendingEndpoints(_endpoints); + _callback->setConnection(connection, compress); + } + catch(const Ice::LocalException& ex) + { + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + _factory->_instance->clientThreadPool()->execute(this); + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::nextConnector() +{ + try + { + _exception.reset(0); + _connection = _factory->createConnection(_iter->connector->connect(0), *_iter); + _connection->start(this); + } + catch(const Ice::LocalException& ex) + { + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + handleException(); + } +} + +void +IceInternal::OutgoingConnectionFactory::ConnectCallback::handleException() +{ + assert(_iter != _connectors.end() && _exception.get()); + + _factory->handleException(*_exception.get(), *_iter, _connection, _hasMore || _iter != _connectors.end() - 1); + if(dynamic_cast<Ice::CommunicatorDestroyedException*>(_exception.get())) // No need to continue. + { + _factory->finishGetConnection(_connectors, this, 0); + _factory->removePendingEndpoints(_endpoints); + _callback->setException(*_exception.get()); + } + else if(++_iter != _connectors.end()) // Try the next connector. + { + nextConnector(); + } + else + { + _factory->finishGetConnection(_connectors, this, 0); + _factory->removePendingEndpoints(_endpoints); + _callback->setException(*_exception.get()); + } +} + +bool +IceInternal::OutgoingConnectionFactory::ConnectCallback::operator<(const ConnectCallback& rhs) const +{ + return this < &rhs; +} + void IceInternal::IncomingConnectionFactory::activate() { @@ -612,7 +1165,7 @@ IceInternal::IncomingConnectionFactory::waitUntilFinished() // We want to wait until all connections are finished outside the // thread synchronization. // - connections.swap(_connections); + connections = _connections; } if(threadPerIncomingConnectionFactory) @@ -621,6 +1174,11 @@ IceInternal::IncomingConnectionFactory::waitUntilFinished() } for_each(connections.begin(), connections.end(), Ice::voidMemFun(&ConnectionI::waitUntilFinished)); + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _connections.clear(); + } } EndpointIPtr @@ -641,7 +1199,7 @@ IceInternal::IncomingConnectionFactory::connections() const // Only copy connections which have not been destroyed. // remove_copy_if(_connections.begin(), _connections.end(), back_inserter(result), - Ice::constMemFun(&ConnectionI::isDestroyed)); + not1(Ice::constMemFun(&ConnectionI::isActiveOrHolding))); return result; } @@ -678,11 +1236,12 @@ IceInternal::IncomingConnectionFactory::readable() const return false; } -void +bool IceInternal::IncomingConnectionFactory::read(BasicStream&) { assert(!_threadPerConnection); // Only for use with a thread pool. - assert(false); // Must not be called. + assert(false); // Must not be called, readable() returns false. + return false; } class PromoteFollower @@ -772,10 +1331,23 @@ IceInternal::IncomingConnectionFactory::message(BasicStream&, const ThreadPoolPt { assert(!_threadPerConnection); connection = new ConnectionI(_instance, transceiver, _endpoint, _adapter, false, 0); - connection->start(); } - catch(const LocalException&) + catch(const LocalException& ex) { + try + { + transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Ignore. + } + + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "connection exception:\n" << ex << '\n' << _acceptor->toString(); + } return; } @@ -784,23 +1356,7 @@ IceInternal::IncomingConnectionFactory::message(BasicStream&, const ThreadPoolPt assert(connection); - // - // We validate outside the thread synchronization, to not block - // the factory. - // - try - { - connection->validate(); - } - catch(const LocalException&) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - connection->waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - _connections.remove(connection); - return; - } - - connection->activate(); + connection->start(this); } void @@ -844,6 +1400,48 @@ IceInternal::IncomingConnectionFactory::toString() const return _acceptor->toString(); } +void +IceInternal::IncomingConnectionFactory::connectionStartCompleted(const Ice::ConnectionIPtr& connection) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + // + // Initialy, connections are in the holding state. If the factory is active + // we activate the connection. + // + if(_state == StateActive) + { + connection->activate(); + } +} + +void +IceInternal::IncomingConnectionFactory::connectionStartFailed(const Ice::ConnectionIPtr& connection, + const Ice::LocalException& ex) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_state == StateClosed) + { + return; + } + + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "connection exception:\n" << ex << '\n' << _acceptor->toString(); + } + + // + // If the connection is finished, remove it right away from + // the connection map. Otherwise, we keep it in the map, it + // will eventually be reaped. + // + if(connection->isFinished()) + { + _connections.remove(connection); + } +} + IceInternal::IncomingConnectionFactory::IncomingConnectionFactory(const InstancePtr& instance, const EndpointIPtr& endpoint, const ObjectAdapterPtr& adapter, @@ -881,23 +1479,22 @@ IceInternal::IncomingConnectionFactory::IncomingConnectionFactory(const Instance { connection = new ConnectionI(_instance, _transceiver, _endpoint, _adapter, _threadPerConnection, _threadPerConnectionStackSize); - connection->start(); - connection->validate(); } catch(const LocalException&) { - // - // If a connection object was constructed, then validate() - // must have raised the exception. - // - if(connection) + try { - connection->waitUntilFinished(); // We must call waitUntilFinished() for cleanup. + _transceiver->close(); } - - return; + catch(const Ice::LocalException&) + { + // Ignore + } + throw; } + connection->start(0); + _connections.push_back(connection); } else @@ -1148,33 +1745,44 @@ IceInternal::IncomingConnectionFactory::run() // // Create a connection object for the connection. // - if(transceiver) + if(!transceiver) + { + continue; + } + + try + { + connection = new ConnectionI(_instance, transceiver, _endpoint, _adapter, _threadPerConnection, + _threadPerConnectionStackSize); + } + catch(const LocalException& ex) { try { - connection = new ConnectionI(_instance, transceiver, _endpoint, _adapter, _threadPerConnection, - _threadPerConnectionStackSize); - connection->start(); + transceiver->close(); } - catch(const LocalException&) + catch(const Ice::LocalException&) { - return; } - _connections.push_back(connection); + if(_warn) + { + Warning out(_instance->initializationData().logger); + out << "connection exception:\n" << ex << '\n' << _acceptor->toString(); + } + continue; } + + _connections.push_back(connection); } // - // In thread per connection mode, the connection's thread will - // take care of connection validation and activation (for - // non-datagram connections). We don't want to block this - // thread waiting until validation is complete, because in - // contrast to thread pool mode, it is the only thread that - // can accept connections with this factory's - // acceptor. Therefore we don't call validate() and activate() - // from the connection factory in thread per connection mode. + // In thread-per-connection mode and regardless of the background mode, + // start() doesn't block. The connection thread is started and takes + // care of the connection validation and notifies the factory through + // the callback when it's done. // + connection->start(this); } } diff --git a/cpp/src/Ice/ConnectionFactory.h b/cpp/src/Ice/ConnectionFactory.h index e1351e976a7..1c2c3349a42 100644 --- a/cpp/src/Ice/ConnectionFactory.h +++ b/cpp/src/Ice/ConnectionFactory.h @@ -14,7 +14,7 @@ #include <IceUtil/Monitor.h> #include <IceUtil/Thread.h> // For ThreadPerIncomingConnectionFactory. #include <Ice/ConnectionFactoryF.h> -#include <Ice/ConnectionIF.h> +#include <Ice/ConnectionI.h> #include <Ice/InstanceF.h> #include <Ice/ObjectAdapterF.h> #include <Ice/EndpointIF.h> @@ -24,6 +24,7 @@ #include <Ice/TransceiverF.h> #include <Ice/RouterInfoF.h> #include <Ice/EventHandler.h> +#include <Ice/EndpointI.h> #include <list> #include <set> @@ -38,15 +39,26 @@ class ObjectAdapterI; namespace IceInternal { -class OutgoingConnectionFactory : public IceUtil::Shared, public IceUtil::Monitor<IceUtil::Mutex> +class OutgoingConnectionFactory : virtual public IceUtil::Shared, public IceUtil::Monitor<IceUtil::Mutex> { public: + class CreateConnectionCallback : virtual public IceUtil::Shared + { + public: + + virtual void setConnection(const Ice::ConnectionIPtr&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<CreateConnectionCallback> CreateConnectionCallbackPtr; + void destroy(); void waitUntilFinished(); Ice::ConnectionIPtr create(const std::vector<EndpointIPtr>&, bool, bool, Ice::EndpointSelectionType, bool&); + void create(const std::vector<EndpointIPtr>&, bool, bool, Ice::EndpointSelectionType, + const CreateConnectionCallbackPtr&); void setRouterInfo(const RouterInfoPtr&); void removeAdapter(const Ice::ObjectAdapterPtr&); void flushBatchRequests(); @@ -57,13 +69,87 @@ private: virtual ~OutgoingConnectionFactory(); friend class Instance; + struct ConnectorInfo + { + ConnectorInfo(const ConnectorPtr& c, const EndpointIPtr& e, bool t) : + connector(c), endpoint(e), threadPerConnection(t) + { + } + + bool operator<(const ConnectorInfo& other) const; + + ConnectorPtr connector; + EndpointIPtr endpoint; + bool threadPerConnection; + }; + + class ConnectCallback : public Ice::ConnectionI::StartCallback, public IceInternal::EndpointI_connectors, + public IceInternal::ThreadPoolWorkItem + { + public: + + ConnectCallback(const OutgoingConnectionFactoryPtr&, const std::vector<EndpointIPtr>&, bool, + const CreateConnectionCallbackPtr&, Ice::EndpointSelectionType, bool); + + virtual void connectionStartCompleted(const Ice::ConnectionIPtr&); + virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&); + + virtual void connectors(const std::vector<ConnectorPtr>&); + virtual void exception(const Ice::LocalException&); + + virtual void execute(const ThreadPoolPtr&); + + void getConnection(); + void nextConnector(); + + bool operator<(const ConnectCallback&) const; + + private: + + void handleException(); + + const OutgoingConnectionFactoryPtr _factory; + const SelectorThreadPtr _selectorThread; + const std::vector<EndpointIPtr> _endpoints; + const bool _hasMore; + const CreateConnectionCallbackPtr _callback; + const Ice::EndpointSelectionType _selType; + const bool _threadPerConnection; + std::vector<EndpointIPtr>::const_iterator _endpointsIter; + std::vector<ConnectorInfo> _connectors; + std::vector<ConnectorInfo>::const_iterator _iter; + std::auto_ptr<Ice::LocalException> _exception; + Ice::ConnectionIPtr _connection; + }; + typedef IceUtil::Handle<ConnectCallback> ConnectCallbackPtr; + friend class ConnectCallback; + + std::vector<EndpointIPtr> applyOverrides(const std::vector<EndpointIPtr>&); + Ice::ConnectionIPtr findConnection(const std::vector<EndpointIPtr>&, bool, bool&); + void addPendingEndpoints(const std::vector<EndpointIPtr>&); + void removePendingEndpoints(const std::vector<EndpointIPtr>&); + Ice::ConnectionIPtr getConnection(const std::vector<ConnectorInfo>&, const ConnectCallbackPtr&, bool&); + void finishGetConnection(const std::vector<ConnectorInfo>&, const ConnectCallbackPtr&, const Ice::ConnectionIPtr&); + Ice::ConnectionIPtr findConnection(const std::vector<ConnectorInfo>&, bool&); + Ice::ConnectionIPtr createConnection(const TransceiverPtr&, const ConnectorInfo&); + + void handleException(const Ice::LocalException&, bool); + void handleException(const Ice::LocalException&, const ConnectorInfo&, const Ice::ConnectionIPtr&, bool); + const InstancePtr _instance; bool _destroyed; - std::multimap<ConnectorPtr, Ice::ConnectionIPtr> _connections; - std::set<ConnectorPtr> _pending; // Connectors for which connection establishment is pending. + + std::multimap<ConnectorInfo, Ice::ConnectionIPtr> _connections; + std::map<ConnectorInfo, std::set<ConnectCallbackPtr> > _pending; + + std::multimap<EndpointIPtr, Ice::ConnectionIPtr> _connectionsByEndpoint; + std::multiset<EndpointIPtr> _pendingEndpoints; }; -class IncomingConnectionFactory : public EventHandler, public IceUtil::Monitor<IceUtil::Mutex> +class IncomingConnectionFactory : public EventHandler, + public Ice::ConnectionI::StartCallback, + public IceUtil::Monitor<IceUtil::Mutex> + { public: @@ -83,11 +169,14 @@ public: // virtual bool datagram() const; virtual bool readable() const; - virtual void read(BasicStream&); + virtual bool read(BasicStream&); virtual void message(BasicStream&, const ThreadPoolPtr&); virtual void finished(const ThreadPoolPtr&); virtual void exception(const Ice::LocalException&); virtual std::string toString() const; + + virtual void connectionStartCompleted(const Ice::ConnectionIPtr&); + virtual void connectionStartFailed(const Ice::ConnectionIPtr&, const Ice::LocalException&); private: diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index cdf3dce6b80..ccc6d5236e7 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -34,195 +34,226 @@ using namespace IceInternal; Ice::LocalObject* IceInternal::upCast(ConnectionI* p) { return p; } void -Ice::ConnectionI::validate() +Ice::ConnectionI::OutgoingMessage::adopt(BasicStream* str) { - bool active = false; + if(adopted) + { + if(str) + { + delete stream; + stream = 0; + adopted = false; + } + else + { + return; // Stream is already adopted. + } + } + else if(!str) + { + if(out || outAsync) + { + return; // Adopting request stream is not necessary. + } + else + { + str = stream; // Adopt this stream + stream = 0; + } + } - if(!_endpoint->datagram()) // Datagram connections are always implicitly validated. + assert(str); + stream = new BasicStream(str->instance()); + stream->swap(*str); + adopted = true; +} + +void +Ice::ConnectionI::OutgoingMessage::sent(ConnectionI* connection, bool notify) +{ + if(out) + { + out->sent(notify); // true = notify the waiting thread that the request was sent. + } + else if(outAsync) + { + outAsync->__sent(connection); + } + + if(adopted) + { + delete stream; + stream = 0; + } +} + +void +Ice::ConnectionI::OutgoingMessage::finished(const Ice::LocalException& ex) +{ + if(!response) + { + // + // Only notify oneway requests. The connection keeps track of twoway + // requests in the _requests/_asyncRequests maps and will notify them + // of the connection exceptions. + // + if(out) + { + out->finished(ex); + } + else if(outAsync) + { + outAsync->__finished(ex); + } + } + + if(adopted) + { + delete stream; + stream = 0; + } +} + +void +Ice::ConnectionI::start(const StartCallbackPtr& callback) +{ + try { { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - if(_thread && _thread->getThreadControl() != IceUtil::ThreadControl()) - { - // - // In thread per connection mode, this connection's thread - // will take care of connection validation. Therefore all we - // have to do here is to wait until this thread has completed - // validation. - // - while(_state == StateNotValidated) - { - wait(); - } - - if(_state >= StateClosing) - { - assert(_exception.get()); - _exception->ice_throw(); - } - - return; - } - + _startCallback = callback; + // - // The connection might already be closed (e.g.: the communicator - // was destroyed or object adapter deactivated.) + // The connection might already be closed if the communicator was destroyed. // - assert(_state == StateNotValidated || _state == StateClosed); if(_state == StateClosed) { assert(_exception.get()); _exception->ice_throw(); } - - if(_adapter) - { - active = true; // The server side has the active role for connection validation. - } - else - { - active = false; // The client side has the passive role for connection validation. - } - } - - try - { - Int timeout; - if(_instance->defaultsAndOverrides()->overrideConnectTimeout) - { - timeout = _instance->defaultsAndOverrides()->overrideConnectTimeoutValue; - } - else - { - timeout = _endpoint->timeout(); - } - - if(active) - { - IceUtil::Mutex::Lock sendSync(_sendMutex); - if(!_transceiver) // Has the transceiver already been closed? - { - assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. - } - - BasicStream os(_instance.get()); - os.write(magic[0]); - os.write(magic[1]); - os.write(magic[2]); - os.write(magic[3]); - os.write(protocolMajor); - os.write(protocolMinor); - os.write(encodingMajor); - os.write(encodingMinor); - os.write(validateConnectionMsg); - os.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection). - os.write(headerSize); // Message size. - os.i = os.b.begin(); - traceHeader("sending validate connection", os, _logger, _traceLevels); - try - { - _transceiver->initialize(timeout); - _transceiver->write(os, timeout); - } - catch(const TimeoutException&) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - } - else + // + // In thread per connection mode, we create the thread for the connection. The + // intialization and validation of the connection is taken care of by the thread + // per connection. If a callback is given, no need to wait, the thread will notify + // the callback, otherwise wait until the connection is validated. + // + if(_threadPerConnection) { - BasicStream is(_instance.get()); - is.b.resize(headerSize); - is.i = is.b.begin(); try { - _transceiver->initialize(timeout); - _transceiver->read(is, timeout); + _thread = new ThreadPerConnection(this); + _thread->start(_threadPerConnectionStackSize); } - catch(const TimeoutException&) + catch(const IceUtil::Exception& ex) { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - assert(is.i == is.b.end()); - is.i = is.b.begin(); - Byte m[4]; - is.read(m[0]); - is.read(m[1]); - is.read(m[2]); - is.read(m[3]); - if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3]) - { - BadMagicException ex(__FILE__, __LINE__); - ex.badMagic = Ice::ByteSeq(&m[0], &m[0] + sizeof(magic)); - throw ex; - } - Byte pMajor; - Byte pMinor; - is.read(pMajor); - is.read(pMinor); - if(pMajor != protocolMajor) - { - UnsupportedProtocolException ex(__FILE__, __LINE__); - ex.badMajor = static_cast<unsigned char>(pMajor); - ex.badMinor = static_cast<unsigned char>(pMinor); - ex.major = static_cast<unsigned char>(protocolMajor); - ex.minor = static_cast<unsigned char>(protocolMinor); - throw ex; - } - Byte eMajor; - Byte eMinor; - is.read(eMajor); - is.read(eMinor); - if(eMajor != encodingMajor) - { - UnsupportedEncodingException ex(__FILE__, __LINE__); - ex.badMajor = static_cast<unsigned char>(eMajor); - ex.badMinor = static_cast<unsigned char>(eMinor); - ex.major = static_cast<unsigned char>(encodingMajor); - ex.minor = static_cast<unsigned char>(encodingMinor); - throw ex; - } - Byte messageType; - is.read(messageType); - if(messageType != validateConnectionMsg) - { - throw ConnectionNotValidatedException(__FILE__, __LINE__); + { + Error out(_logger); + out << "cannot create thread for connection:\n" << ex; + } + + // + // Clean up. + // + _thread = 0; + _state = StateClosed; + + ex.ice_throw(); } - Byte compress; - is.read(compress); // Ignore compression status for validate connection. - Int size; - is.read(size); - if(size != headerSize) + + if(!callback) // Wait for the connection to be validated. { - throw IllegalMessageSizeException(__FILE__, __LINE__); + while(_state <= StateNotValidated) + { + wait(); + } + + if(_state >= StateClosing) + { + assert(_exception.get()); + _exception->ice_throw(); + } } - traceHeader("received validate connection", is, _logger, _traceLevels); + return; // We're done. } } - catch(const LocalException& ex) + + SocketStatus status = initialize(); + if(status == Finished) + { + status = validate(); + } + + if(status == Finished) + { + finishStart(); + return; // We're done! + } + + assert(callback); + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_state == StateClosed) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - setState(StateClosed, ex); assert(_exception.get()); _exception->ice_throw(); } - } - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + int timeout; + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideConnectTimeout) + { + timeout = defaultsAndOverrides->overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint->timeout(); + } - if(_acmTimeout > 0) + _sendInProgress = true; + _selectorThread->_register(_transceiver->fd(), this, status, timeout); + return; + } + catch(const Ice::LocalException& ex) + { { - _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + setState(StateClosed, ex); + + // + // If start is called with a callback, the callback is notified either by the + // thread per conncetion or the thread pool. + // + if(callback) + { + if(!_threadPerConnection) + { + registerWithPool(); + unregisterWithPool(); // Let finished do the close. + } + return; + } + + // + // Close the transceiver if there's no thread per connection, otherwise, the + // thread per connection takes care of it. + // + if(!_thread && _transceiver) + { + try + { + _transceiver->close(); + } + catch(const Ice::LocalException&) + { + // Here we ignore any exceptions in close(). + } + _transceiver = 0; + } } - // - // We start out in holding state. - // - setState(StateHolding); + waitUntilFinished(); + throw; } } @@ -230,10 +261,14 @@ void Ice::ConnectionI::activate() { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_state <= StateNotValidated) + { + return; + } - while(_state == StateNotValidated) + if(_acmTimeout > 0) { - wait(); + _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); } setState(StateActive); @@ -243,10 +278,9 @@ void Ice::ConnectionI::hold() { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - while(_state == StateNotValidated) + if(_state <= StateNotValidated) { - wait(); + return; } setState(StateHolding); @@ -255,20 +289,35 @@ Ice::ConnectionI::hold() void Ice::ConnectionI::destroy(DestructionReason reason) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - switch(reason) + bool send = false; + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + switch(reason) + { + case ObjectAdapterDeactivated: + { + send = setState(StateClosing, ObjectAdapterDeactivatedException(__FILE__, __LINE__)); + break; + } + + case CommunicatorDestroyed: + { + send = setState(StateClosing, CommunicatorDestroyedException(__FILE__, __LINE__)); + break; + } + } + } + + if(send) // Send the close connection message { - case ObjectAdapterDeactivated: + try { - setState(StateClosing, ObjectAdapterDeactivatedException(__FILE__, __LINE__)); - break; + finishSendMessage(); } - - case CommunicatorDestroyed: + catch(const Ice::LocalException&) { - setState(StateClosing, CommunicatorDestroyedException(__FILE__, __LINE__)); - break; + // Ignore. } } } @@ -276,32 +325,47 @@ Ice::ConnectionI::destroy(DestructionReason reason) void Ice::ConnectionI::close(bool force) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - if(force) + bool send = false; { - setState(StateClosed, ForcedCloseConnectionException(__FILE__, __LINE__)); + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + if(force) + { + setState(StateClosed, ForcedCloseConnectionException(__FILE__, __LINE__)); + } + else + { + // + // If we do a graceful shutdown, then we wait until all + // outstanding requests have been completed. Otherwise, the + // CloseConnectionException will cause all outstanding + // requests to be retried, regardless of whether the server + // has processed them or not. + // + while(!_requests.empty() || !_asyncRequests.empty()) + { + wait(); + } + + send = setState(StateClosing, CloseConnectionException(__FILE__, __LINE__)); + } } - else + + if(send) // Send the close connection message { - // - // If we do a graceful shutdown, then we wait until all - // outstanding requests have been completed. Otherwise, the - // CloseConnectionException will cause all outstanding - // requests to be retried, regardless of whether the server - // has processed them or not. - // - while(!_requests.empty() || !_asyncRequests.empty()) + try { - wait(); + finishSendMessage(); + } + catch(const Ice::LocalException&) + { + // Ignore. } - - setState(StateClosing, CloseConnectionException(__FILE__, __LINE__)); } } bool -Ice::ConnectionI::isDestroyed() const +Ice::ConnectionI::isActiveOrHolding() const { // // We can not use trylock here, otherwise the outgoing connection @@ -310,7 +374,7 @@ Ice::ConnectionI::isDestroyed() const // IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - return _state >= StateClosing; + return _state > StateNotValidated && _state < StateClosing; } bool @@ -460,56 +524,55 @@ Ice::ConnectionI::waitUntilFinished() void Ice::ConnectionI::monitor() { - IceUtil::Monitor<IceUtil::Mutex>::TryLock sync(*this); - - if(!sync.acquired()) + bool send = false; { - return; - } + IceUtil::Monitor<IceUtil::Mutex>::TryLock sync(*this); + if(!sync.acquired()) + { + return; + } - if(_state != StateActive) - { - return; - } + if(_state != StateActive) + { + return; + } - // - // Check for timed out async requests. - // - for(map<Int, AsyncRequest>::iterator p = _asyncRequests.begin(); p != _asyncRequests.end(); ++p) - { - if(p->second.t > IceUtil::Time() && p->second.t <= IceUtil::Time::now(IceUtil::Time::Monotonic)) + // + // Active connection management for idle connections. + // + if(_acmTimeout <= 0 || + !_requests.empty() || !_asyncRequests.empty() || + _batchStreamInUse || !_batchStream.b.empty() || + _sendInProgress || _dispatchCount > 0) { - setState(StateClosed, TimeoutException(__FILE__, __LINE__)); return; } + + if(IceUtil::Time::now(IceUtil::Time::Monotonic) >= _acmAbsoluteTimeout) + { + send = setState(StateClosing, ConnectionTimeoutException(__FILE__, __LINE__)); + } } - - // - // Active connection management for idle connections. - // - if(_acmTimeout > 0 && - _requests.empty() && _asyncRequests.empty() && - !_batchStreamInUse && _batchStream.b.empty() && - _dispatchCount == 0) + + if(send) { - if(IceUtil::Time::now(IceUtil::Time::Monotonic) >= _acmAbsoluteTimeout) + try + { + finishSendMessage(); + } + catch(const Ice::LocalException&) { - setState(StateClosing, ConnectionTimeoutException(__FILE__, __LINE__)); - return; } } } -void -Ice::ConnectionI::sendRequest(BasicStream* os, Outgoing* out, bool compress) +bool +Ice::ConnectionI::sendRequest(Outgoing* out, bool compress, bool response) { - Int requestId; - + BasicStream* os = out->os(); + bool send = false; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - assert(!(out && _endpoint->datagram())); // Twoway requests cannot be datagrams. - if(_exception.get()) { // @@ -523,10 +586,8 @@ Ice::ConnectionI::sendRequest(BasicStream* os, Outgoing* out, bool compress) assert(_state > StateNotValidated); assert(_state < StateClosing); - // - // Only add to the request map if this is a twoway call. - // - if(out) + Int requestId; + if(response) { // // Create a new unique request ID. @@ -547,134 +608,65 @@ Ice::ConnectionI::sendRequest(BasicStream* os, Outgoing* out, bool compress) #else copy(p, p + sizeof(Int), os->b.begin() + headerSize); #endif - - // - // Add to the requests map. - // - _requestsHint = _requests.insert(_requests.end(), pair<const Int, Outgoing*>(requestId, out)); } - - if(_acmTimeout > 0) + + // + // Send the message. If it can't be sent without blocking the message is added + // to _sendStreams and it will be sent by the selector thread or by this thread + // if flush is true. + // + try { - _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + OutgoingMessage message(out, os, compress, response); + send = sendMessage(message); } - } - - try - { - IceUtil::Mutex::Lock sendSync(_sendMutex); - - if(!_transceiver) // Has the transceiver already been closed? + catch(const LocalException& ex) { - assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. + setState(StateClosed, ex); + assert(_exception.get()); + _exception->ice_throw(); } - - if(compress && os->b.size() >= 100) // Only compress messages larger than 100 bytes. + + if(response) { // - // Message compressed. Request compressed response, if any. - // - os->b[9] = 2; - - // - // Do compression. - // - BasicStream cstream(_instance.get()); - doCompress(*os, cstream); - - // - // Send the request. + // Add to the requests map. // - os->i = os->b.begin(); - traceRequest("sending request", *os, _logger, _traceLevels); - cstream.i = cstream.b.begin(); - _transceiver->write(cstream, _endpoint->timeout()); + _requestsHint = _requests.insert(_requests.end(), pair<const Int, Outgoing*>(requestId, out)); } - else - { - if(compress) - { - // - // Message not compressed. Request compressed response, if any. - // - os->b[9] = 1; - } - // - // No compression, just fill in the message size. - // - Int sz = static_cast<Int>(os->b.size()); - const Byte* p = reinterpret_cast<const Byte*>(&sz); -#ifdef ICE_BIG_ENDIAN - reverse_copy(p, p + sizeof(Int), os->b.begin() + 10); -#else - copy(p, p + sizeof(Int), os->b.begin() + 10); -#endif - - // - // Send the request. - // - os->i = os->b.begin(); - traceRequest("sending request", *os, _logger, _traceLevels); - _transceiver->write(*os, _endpoint->timeout()); + if(!send) + { + return !_sendInProgress && _queuedStreams.empty(); // The request was sent if it's not queued! } } - catch(const LocalException& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - setState(StateClosed, ex); - assert(_exception.get()); - if(out) + if(send) + { + try { - // - // If the request has already been removed from the - // request map, we are out of luck. It would mean that - // finished() has been called already, and therefore the - // exception has been set using the Outgoing::finished() - // callback. In this case, we cannot throw the exception - // here, because we must not both raise an exception and - // have Outgoing::finished() called with an - // exception. This means that in some rare cases, a - // request will not be retried even though it could. But I - // honestly don't know how I could avoid this, without a - // very elaborate and complex design, which would be bad - // for performance. - // - map<Int, Outgoing*>::iterator p = _requests.find(requestId); - if(p != _requests.end()) - { - if(p == _requestsHint) - { - _requests.erase(p++); - _requestsHint = p; - } - else - { - _requests.erase(p); - } - - _exception->ice_throw(); - } + finishSendMessage(); } - else + catch(const Ice::LocalException&) { - _exception->ice_throw(); + assert(_exception.get()); + if(!response) // Twoway calls are notified through finished() + { + throw; + } } } + return true; // The request was sent. } void -Ice::ConnectionI::sendAsyncRequest(BasicStream* os, const OutgoingAsyncPtr& out, bool compress) +Ice::ConnectionI::sendAsyncRequest(const OutgoingAsyncPtr& out, bool compress, bool response) { - Int requestId; + BasicStream* os = out->__getOs(); + bool send = false; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - assert(!_endpoint->datagram()); // Twoway requests cannot be datagrams, and async implies twoway. - if(_exception.get()) { // @@ -687,140 +679,66 @@ Ice::ConnectionI::sendAsyncRequest(BasicStream* os, const OutgoingAsyncPtr& out, assert(_state > StateNotValidated); assert(_state < StateClosing); - - // - // Create a new unique request ID. - // - requestId = _nextRequestId++; - if(requestId <= 0) + + Int requestId; + if(response) { - _nextRequestId = 1; + // + // Create a new unique request ID. + // requestId = _nextRequestId++; - } - - // - // Fill in the request ID. - // - const Byte* p = reinterpret_cast<const Byte*>(&requestId); + if(requestId <= 0) + { + _nextRequestId = 1; + requestId = _nextRequestId++; + } + + // + // Fill in the request ID. + // + const Byte* p = reinterpret_cast<const Byte*>(&requestId); #ifdef ICE_BIG_ENDIAN - reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize); + reverse_copy(p, p + sizeof(Int), os->b.begin() + headerSize); #else - copy(p, p + sizeof(Int), os->b.begin() + headerSize); + copy(p, p + sizeof(Int), os->b.begin() + headerSize); #endif - - // - // Add to the async requests map. - // - struct AsyncRequest asyncRequest; - asyncRequest.p = out; - if(_endpoint->timeout() > 0) - { - asyncRequest.t = - IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::milliSeconds(_endpoint->timeout()); } - _asyncRequestsHint = _asyncRequests.insert(_asyncRequests.end(), - pair<const Int, AsyncRequest>(requestId, asyncRequest)); - - if(_acmTimeout > 0) + + try { - _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + OutgoingMessage message(out, os, compress, response); + send = sendMessage(message); } - } - - try - { - IceUtil::Mutex::Lock sendSync(_sendMutex); - - if(!_transceiver) // Has the transceiver already been closed? + catch(const LocalException& ex) { + setState(StateClosed, ex); assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. + _exception->ice_throw(); } - if(compress && os->b.size() >= 100) // Only compress messages larger than 100 bytes. - { - // - // Message compressed. Request compressed response, if any. - // - os->b[9] = 2; - - // - // Do compression. - // - BasicStream cstream(_instance.get()); - doCompress(*os, cstream); - - // - // Send the request. - // - os->i = os->b.begin(); - traceRequest("sending asynchronous request", *os, _logger, _traceLevels); - cstream.i = cstream.b.begin(); - _transceiver->write(cstream, _endpoint->timeout()); - } - else + if(response) { - if(compress) - { - // - // Message not compressed. Request compressed response, if any. - // - os->b[9] = 1; - } - - // - // No compression, just fill in the message size. - // - Int sz = static_cast<Int>(os->b.size()); - const Byte* p = reinterpret_cast<const Byte*>(&sz); -#ifdef ICE_BIG_ENDIAN - reverse_copy(p, p + sizeof(Int), os->b.begin() + 10); -#else - copy(p, p + sizeof(Int), os->b.begin() + 10); -#endif - // - // Send the request. + // Add to the async requests map. // - os->i = os->b.begin(); - traceRequest("sending asynchronous request", *os, _logger, _traceLevels); - _transceiver->write(*os, _endpoint->timeout()); + _asyncRequestsHint = _asyncRequests.insert(_asyncRequests.end(), + pair<const Int, OutgoingAsyncPtr>(requestId, out)); } } - catch(const LocalException& ex) + + if(send) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - setState(StateClosed, ex); - assert(_exception.get()); - - // - // If the request has already been removed from the async - // request map, we are out of luck. It would mean that - // finished() has been called already, and therefore the - // exception has been set using the - // OutgoingAsync::__finished() callback. In this case, we - // cannot throw the exception here, because we must not both - // raise an exception and have OutgoingAsync::__finished() - // called with an exception. This means that in some rare - // cases, a request will not be retried even though it - // could. But I honestly don't know how I could avoid this, - // without a very elaborate and complex design, which would be - // bad for performance. - // - map<Int, AsyncRequest>::iterator p = _asyncRequests.find(requestId); - if(p != _asyncRequests.end()) + try { - if(p == _asyncRequestsHint) - { - _asyncRequests.erase(p++); - _asyncRequestsHint = p; - } - else + finishSendMessage(); + } + catch(const Ice::LocalException&) + { + assert(_exception.get()); + if(!response) // Twoway calls are notified through finished(). { - _asyncRequests.erase(p); - } - - _exception->ice_throw(); + throw; + } } } } @@ -872,9 +790,8 @@ Ice::ConnectionI::prepareBatchRequest(BasicStream* os) void Ice::ConnectionI::finishBatchRequest(BasicStream* os, bool compress) { - bool autoflush = false; - vector<Ice::Byte> lastRequest; - + bool send = false; + try { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); @@ -882,16 +799,15 @@ Ice::ConnectionI::finishBatchRequest(BasicStream* os, bool compress) // Get the batch stream back. // _batchStream.swap(*os); - + + if(_exception.get()) + { + _exception->ice_throw(); + } + + bool flush = false; if(_batchAutoFlush) { - IceUtil::Mutex::Lock sendSync(_sendMutex); - if(!_transceiver) - { - assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. - } - // // Throw memory limit exception if the first message added causes us to // go over limit. Otherwise put aside the marshalled message that caused @@ -903,122 +819,152 @@ Ice::ConnectionI::finishBatchRequest(BasicStream* os, bool compress) } catch(const Ice::Exception&) { - if(_batchRequestNum == 0) + if(_batchRequestNum > 0) + { + flush = true; + } + else { - resetBatch(true); throw; } - vector<Ice::Byte>(_batchStream.b.begin() + _batchMarker, _batchStream.b.end()).swap(lastRequest); - _batchStream.b.resize(_batchMarker); - autoflush = true; } } - if(!autoflush) + if(flush) { // - // Increment the number of requests in the batch. + // Temporarily save the last request. + // + vector<Ice::Byte> lastRequest(_batchStream.b.begin() + _batchMarker, _batchStream.b.end()); + _batchStream.b.resize(_batchMarker); + + // + // Send the batch stream without the last request. + // + try + { + // + // Fill in the number of requests in the batch. + // + const Byte* p = reinterpret_cast<const Byte*>(&_batchRequestNum); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize); +#else + copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize); +#endif + + OutgoingMessage message(&_batchStream, _batchRequestCompress); + send = sendMessage(message); + if(send) + { + // + // If the request can't be sent immediately and this is a foreground send, + // we adopt the stream to be able to re-use _batchStream immediately. + // + assert(!_sendStreams.empty()); + _sendStreams.back().adopt(0); + } + } + catch(const Ice::LocalException& ex) + { + setState(StateClosed, ex); + assert(_exception.get()); + _exception->ice_throw(); + } + + // + // Reset the batch. // - ++_batchRequestNum; + BasicStream dummy(_instance.get(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; // - // We compress the whole batch if there is at least one compressed - // message. + // Check again if the last request doesn't exceed what we can send with the auto flush // - if(compress) + if(sizeof(requestBatchHdr) + lastRequest.size() > _instance->messageSizeMax()) { - _batchRequestCompress = true; + throw MemoryLimitException(__FILE__, __LINE__); } - + // - // Notify about the batch stream not being in use anymore. + // Start a new batch with the last message that caused us to go over the limit. // - assert(_batchStreamInUse); - _batchStreamInUse = false; - notifyAll(); + _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr)); + _batchStream.writeBlob(&lastRequest[0], lastRequest.size()); } - } - - if(autoflush) - { - // - // We have to keep _batchStreamInUse set until after we insert the - // saved marshalled data into a new stream. - // - flushBatchRequestsInternal(true); - - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); // - // Throw memory limit exception if the message that caused us to go over - // limit causes us to exceed the limit by itself. + // Increment the number of requests in the batch. // - if(sizeof(requestBatchHdr) + lastRequest.size() > _instance->messageSizeMax()) - { - resetBatch(true); - throw MemoryLimitException(__FILE__, __LINE__); - } - + ++_batchRequestNum; + // - // Start a new batch with the last message that caused us to - // go over the limit. + // We compress the whole batch if there is at least one compressed + // message. // - try - { - _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr)); - _batchStream.writeBlob(&lastRequest[0], lastRequest.size()); - } - catch(const LocalException& ex) - { - setState(StateClosed, ex); - ex.ice_throw(); - } - if(compress) { _batchRequestCompress = true; } - + // - // Notify that the batch stream not in use anymore. + // Notify about the batch stream not being in use anymore. // - ++_batchRequestNum; + assert(_batchStreamInUse); _batchStreamInUse = false; notifyAll(); } + catch(const Ice::LocalException&) + { + abortBatchRequest(); + if(send) + { + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. + } + throw; + } + + if(send) + { + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. + } } void Ice::ConnectionI::abortBatchRequest() { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - // - // Reset the batch stream. We cannot save old requests - // in the batch stream, as they might be corrupted due to - // incomplete marshaling. - // - resetBatch(true); + + BasicStream dummy(_instance.get(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + assert(_batchStreamInUse); + _batchStreamInUse = false; + notifyAll(); } void Ice::ConnectionI::flushBatchRequests() { - flushBatchRequestsInternal(false); + BatchOutgoing out(this, _instance.get()); + out.invoke(); } -void -Ice::ConnectionI::flushBatchRequestsInternal(bool ignoreInUse) +bool +Ice::ConnectionI::flushBatchRequests(BatchOutgoing* out) { + bool send = false; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - if(!ignoreInUse) + while(_batchStreamInUse && !_exception.get()) { - while(_batchStreamInUse && !_exception.get()) - { - wait(); - } + wait(); } if(_exception.get()) @@ -1026,36 +972,78 @@ Ice::ConnectionI::flushBatchRequestsInternal(bool ignoreInUse) _exception->ice_throw(); } - if(_batchStream.b.empty()) + if(_batchRequestNum == 0) { - return; // Nothing to do. + return true; } - assert(_state > StateNotValidated); - assert(_state < StateClosing); - - _batchStream.i = _batchStream.b.begin(); + // + // Fill in the number of requests in the batch. + // + const Byte* p = reinterpret_cast<const Byte*>(&_batchRequestNum); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize); +#else + copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize); +#endif + _batchStream.swap(*out->os()); - if(_acmTimeout > 0) + // + // Send the batch stream. + // + try { - _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + OutgoingMessage message(out, out->os(), _batchRequestCompress, false); + send = sendMessage(message); + } + catch(const Ice::LocalException& ex) + { + setState(StateClosed, ex); + assert(_exception.get()); + _exception->ice_throw(); } // - // Prevent that new batch requests are added while we are - // flushing. + // Reset the batch stream. // - _batchStreamInUse = true; + BasicStream dummy(_instance.get(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + if(!send) + { + return !_sendInProgress && _queuedStreams.empty(); // The request was sent if it's not queued! + } } - - try + + if(send) + { + finishSendMessage(); + } + return true; +} + +void +Ice::ConnectionI::flushAsyncBatchRequests(const BatchOutgoingAsyncPtr& outAsync) +{ + bool send = false; { - IceUtil::Mutex::Lock sendSync(_sendMutex); + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + while(_batchStreamInUse && !_exception.get()) + { + wait(); + } + + if(_exception.get()) + { + _exception->ice_throw(); + } - if(!_transceiver) // Has the transceiver already been closed? + if(_batchRequestNum == 0) { - assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. + return; } // @@ -1067,195 +1055,123 @@ Ice::ConnectionI::flushBatchRequestsInternal(bool ignoreInUse) #else copy(p, p + sizeof(Int), _batchStream.b.begin() + headerSize); #endif - - if(_batchRequestCompress && _batchStream.b.size() >= 100) // Only compress messages larger than 100 bytes. + _batchStream.swap(*outAsync->__getOs()); + + // + // Send the batch stream. + // + try { - // - // Message compressed. Request compressed response, if any. - // - _batchStream.b[9] = 2; - - // - // Do compression. - // - BasicStream cstream(_instance.get()); - doCompress(_batchStream, cstream); - - // - // Send the batch request. - // - _batchStream.i = _batchStream.b.begin(); - traceBatchRequest("sending batch request", _batchStream, _logger, _traceLevels); - cstream.i = cstream.b.begin(); - _transceiver->write(cstream, _endpoint->timeout()); + OutgoingMessage message(outAsync, outAsync->__getOs(), _batchRequestCompress, false); + send = sendMessage(message); } - else + catch(const Ice::LocalException& ex) { - if(_batchRequestCompress) - { - // - // Message not compressed. Request compressed response, if any. - // - _batchStream.b[9] = 1; - } - - // - // No compression, just fill in the message size. - // - Int sz = static_cast<Int>(_batchStream.b.size()); - const Byte* q = reinterpret_cast<const Byte*>(&sz); -#ifdef ICE_BIG_ENDIAN - reverse_copy(q, q + sizeof(Int), _batchStream.b.begin() + 10); -#else - copy(q, q + sizeof(Int), _batchStream.b.begin() + 10); -#endif - - // - // Send the batch request. - // - _batchStream.i = _batchStream.b.begin(); - traceBatchRequest("sending batch request", _batchStream, _logger, _traceLevels); - _transceiver->write(_batchStream, _endpoint->timeout()); + setState(StateClosed, ex); + assert(_exception.get()); + _exception->ice_throw(); } - } - catch(const LocalException& ex) - { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - setState(StateClosed, ex); - assert(_exception.get()); // - // Since batch requests are all oneways (or datagrams), we - // must report the exception to the caller. + // Reset the batch stream. // - _exception->ice_throw(); + BasicStream dummy(_instance.get(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; } + if(send) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - // - // Reset the batch stream, and notify that flushing is over. - // - resetBatch(!ignoreInUse); - } -} - -void -Ice::ConnectionI::resetBatch(bool resetInUse) -{ - BasicStream dummy(_instance.get(), _batchAutoFlush); - _batchStream.swap(dummy); - _batchRequestNum = 0; - _batchRequestCompress = false; - _batchMarker = 0; - - // - // Notify about the batch stream not being in use - // anymore. - // - if(resetInUse) - { - assert(_batchStreamInUse); - _batchStreamInUse = false; - notifyAll(); + finishSendMessage(); } } void Ice::ConnectionI::sendResponse(BasicStream* os, Byte compressFlag) { - try + bool send = false; { - IceUtil::Mutex::Lock sendSync(_sendMutex); - - if(!_transceiver) // Has the transceiver already been closed? - { - assert(_exception.get()); - _exception->ice_throw(); // The exception is immutable at this point. - } + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(_state > StateNotValidated); - // - // Only compress if compression was requested by the client, - // and if the message is larger than 100 bytes. - // - if(compressFlag > 0 && os->b.size() >= 100) + try { - // - // Message compressed. Request compressed response, if any. - // - os->b[9] = 2; + if(--_dispatchCount == 0) + { + notifyAll(); + } - // - // Do compression. - // - BasicStream cstream(_instance.get()); - doCompress(*os, cstream); + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } - // - // Send the reply. - // - os->i = os->b.begin(); - traceReply("sending reply", *os, _logger, _traceLevels); - cstream.i = cstream.b.begin(); - _transceiver->write(cstream, _endpoint->timeout()); - } - else - { - if(compressFlag > 0) + OutgoingMessage message(os, compressFlag > 0); + send = sendMessage(message); + + if(_state == StateClosing && _dispatchCount == 0) { - // - // Message not compressed. Request compressed response, if any. - // - os->b[9] = 1; + send = initiateShutdown(send); } - // - // No compression, just fill in the message size. - // - Int sz = static_cast<Int>(os->b.size()); - const Byte* p = reinterpret_cast<const Byte*>(&sz); -#ifdef ICE_BIG_ENDIAN - reverse_copy(p, p + sizeof(Int), os->b.begin() + 10); -#else - copy(p, p + sizeof(Int), os->b.begin() + 10); -#endif - - // - // Send the reply. - // - os->i = os->b.begin(); - traceReply("sending reply", *os, _logger, _traceLevels); - _transceiver->write(*os, _endpoint->timeout()); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + + IceUtil::Time::seconds(_acmTimeout); + } + } + catch(const LocalException& ex) + { + setState(StateClosed, ex); } } - catch(const LocalException& ex) + + if(send) { - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - setState(StateClosed, ex); + try + { + finishSendMessage(); + } + catch(Ice::LocalException&) + { + // Ignore. + } } +} +void +Ice::ConnectionI::sendNoResponse() +{ + bool send = false; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - assert(_state > StateNotValidated); - + try { if(--_dispatchCount == 0) { notifyAll(); } - + + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } + if(_state == StateClosing && _dispatchCount == 0) { - initiateShutdown(); + send = initiateShutdown(false); } - + if(_acmTimeout > 0) { - _acmAbsoluteTimeout = - IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + + IceUtil::Time::seconds(_acmTimeout); } } catch(const LocalException& ex) @@ -1263,31 +1179,18 @@ Ice::ConnectionI::sendResponse(BasicStream* os, Byte compressFlag) setState(StateClosed, ex); } } -} -void -Ice::ConnectionI::sendNoResponse() -{ - IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - assert(_state > StateNotValidated); - - try + if(send) { - if(--_dispatchCount == 0) + try { - notifyAll(); + finishSendMessage(); } - - if(_state == StateClosing && _dispatchCount == 0) + catch(Ice::LocalException&) { - initiateShutdown(); + // Ignore. } } - catch(const LocalException& ex) - { - setState(StateClosed, ex); - } } EndpointIPtr @@ -1307,12 +1210,15 @@ Ice::ConnectionI::setAdapter(const ObjectAdapterPtr& adapter) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - if(_exception.get()) + if(_state == StateClosing || _state == StateClosed) { + assert(_exception.get()); _exception->ice_throw(); } - - assert(_state < StateClosing); + else if(_state <= StateNotValidated) + { + return; + } _adapter = adapter; @@ -1370,12 +1276,12 @@ Ice::ConnectionI::readable() const return true; } -void +bool Ice::ConnectionI::read(BasicStream& stream) { assert(!_threadPerConnection); // Only for use with a thread pool. - _transceiver->read(stream, 0); + return _transceiver->read(stream, 0); // // Updating _acmAbsoluteTimeout is too expensive here, because we @@ -1446,9 +1352,6 @@ Ice::ConnectionI::finished(const ThreadPoolPtr& threadPool) threadPool->promoteFollower(); auto_ptr<LocalException> localEx; - - map<Int, Outgoing*> requests; - map<Int, AsyncRequest> asyncRequests; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); @@ -1456,49 +1359,48 @@ Ice::ConnectionI::finished(const ThreadPoolPtr& threadPool) --_finishedCount; assert(threadPool.get() == _threadPool.get()); - if(_finishedCount == 0 && _state == StateClosed) + if(_finishedCount > 0 || _state != StateClosed || _sendInProgress) { - _threadPool->decFdsInUse(); + return; + } - // - // We must make sure that nobody is sending when we close - // the transceiver. - // - IceUtil::Mutex::Lock sendSync(_sendMutex); + _threadPool->decFdsInUse(); + _selectorThread->decFdsInUse(); - try - { - _transceiver->close(); - } - catch(const LocalException& ex) - { - localEx.reset(dynamic_cast<LocalException*>(ex.ice_clone())); - } - - _transceiver = 0; - notifyAll(); + try + { + _transceiver->close(); } - - if(_state == StateClosed || _state == StateClosing) + catch(const LocalException& ex) { - requests.swap(_requests); - _requestsHint = _requests.end(); - - asyncRequests.swap(_asyncRequests); - _asyncRequestsHint = _asyncRequests.end(); + localEx.reset(dynamic_cast<LocalException*>(ex.ice_clone())); } + + _transceiver = 0; + notifyAll(); } - for(map<Int, Outgoing*>::iterator p = requests.begin(); p != requests.end(); ++p) + finishStart(*_exception.get()); + + // Note: the streams must be cleared first because they expect the Outgoing objects to still be valid. + for(deque<OutgoingMessage>::iterator o = _queuedStreams.begin(); o != _queuedStreams.end(); ++o) { - p->second->finished(*_exception.get()); // The exception is immutable at this point. + o->finished(*_exception.get()); } + _queuedStreams.clear(); - for(map<Int, AsyncRequest>::iterator q = asyncRequests.begin(); q != asyncRequests.end(); ++q) + for(map<Int, Outgoing*>::iterator p = _requests.begin(); p != _requests.end(); ++p) { - q->second.p->__finished(*_exception.get()); // The exception is immutable at this point. + p->second->finished(*_exception.get()); // The exception is immutable at this point. } + _requests.clear(); + for(map<Int, OutgoingAsyncPtr>::iterator q = _asyncRequests.begin(); q != _asyncRequests.end(); ++q) + { + q->second->__finished(*_exception.get()); // The exception is immutable at this point. + } + _asyncRequests.clear(); + if(localEx.get()) { localEx->ice_throw(); @@ -1554,6 +1456,139 @@ Ice::ConnectionI::toString() const } // +// Operations from SocketReadyCallback +// +SocketStatus +Ice::ConnectionI::socketReady(bool finished) +{ + if(!finished) + { + try + { + // + // First, we check if there's something to send. If that's the case, the connection + // must be active and the only thing to do is send the queued streams. + // + if(!_sendStreams.empty()) + { + if(!send(0)) + { + return NeedWrite; + } + assert(_sendStreams.empty()); + } + else + { + // + // If there's nothing to send, we're still validating the connection. + // + int state; + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(_state == StateClosed || _state <= StateNotValidated); + + state = _state; + + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } + } + + if(state == StateNotInitialized) + { + SocketStatus status = initialize(); + if(status != Finished) + { + return status; + } + } + + if(state <= StateNotValidated) + { + SocketStatus status = validate(); + if(status != Finished) + { + return status; + } + } + + finishStart(); + } + } + catch(const Ice::LocalException& ex) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + setState(StateClosed, ex); + } + } + + // + // If there's no more data to send or if connection validation is finished, we checkout + // the connection state to figure out whether or not it's time to unregister with the + // selector thread. + // + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(_sendInProgress); + if(_state == StateClosed) + { + assert(!_startCallback || (!_threadPerConnection && !_registeredWithPool)); + + _queuedStreams.insert(_queuedStreams.begin(), _sendStreams.begin(), _sendStreams.end()); + _sendStreams.clear(); + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver->shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + notifyAll(); + return Finished; + } + else if(_waitingForSend > 0) // If there's synchronous calls waiting to be sent, unregister. + { + _sendInProgress = false; + notifyAll(); + return Finished; + } + else if(_queuedStreams.empty()) + { + _sendInProgress = false; + if(_acmTimeout > 0) + { + _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + } + return Finished; + } + else + { + _sendStreams.swap(_queuedStreams); + return NeedWrite; // We're not finished yet, there's more data to send! + } +} + +void +Ice::ConnectionI::socketTimeout() +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_state <= StateNotValidated) + { + setState(StateClosed, ConnectTimeoutException(__FILE__, __LINE__)); + } + else if(_state <= StateClosing) + { + setState(StateClosed, TimeoutException(__FILE__, __LINE__)); + } +} + +// // Only used by the SSL plug-in. // // The external party has to synchronize the connection, since the @@ -1596,8 +1631,10 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, _batchRequestNum(0), _batchRequestCompress(false), _batchMarker(0), + _sendInProgress(false), + _waitingForSend(0), _dispatchCount(0), - _state(StateNotValidated), + _state(StateNotInitialized), _stateTime(IceUtil::Time::now(IceUtil::Time::Monotonic)) { Int& acmTimeout = const_cast<Int&>(_acmTimeout); @@ -1635,17 +1672,17 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, _servantManager = adapterImpl->getServantManager(); } - if(!threadPerConnection) + __setNoDelete(true); + try { - // - // Only set _threadPool if we really need it, i.e., if we are - // not in thread per connection mode. Thread pools have lazy - // initialization in Instance, and we don't want them to be - // created if they are not needed. - // - __setNoDelete(true); - try + if(!threadPerConnection) { + // + // Only set _threadPool if we really need it, i.e., if we are + // not in thread per connection mode. Thread pools have lazy + // initialization in Instance, and we don't want them to be + // created if they are not needed. + // if(adapterImpl) { const_cast<ThreadPoolPtr&>(_threadPool) = adapterImpl->getThreadPool(); @@ -1656,76 +1693,34 @@ Ice::ConnectionI::ConnectionI(const InstancePtr& instance, } _threadPool->incFdsInUse(); } - catch(const IceUtil::Exception& ex) - { - try - { - _transceiver->close(); - } - catch(const LocalException&) - { - // Here we ignore any exceptions in close(). - } - __setNoDelete(false); - ex.ice_throw(); - } + // + // Only set selector thread if we really need it. + // + const_cast<SelectorThreadPtr&>(_selectorThread) = _instance->selectorThread(); + _selectorThread->incFdsInUse(); + } + catch(const IceUtil::Exception&) + { __setNoDelete(false); + throw; } + __setNoDelete(false); } Ice::ConnectionI::~ConnectionI() { + assert(!_startCallback); assert(_state == StateClosed); assert(!_transceiver); assert(_dispatchCount == 0); assert(!_thread); + assert(_queuedStreams.empty()); + assert(_requests.empty()); + assert(_asyncRequests.empty()); } -void -Ice::ConnectionI::start() -{ - // - // If we are in thread per connection mode, create the thread for this connection. - // We can't start the thread in the constructor because it can cause a race condition - // (see bug 1718). - // - if(_threadPerConnection) - { - try - { - _thread = new ThreadPerConnection(this); - _thread->start(_threadPerConnectionStackSize); - } - catch(const IceUtil::Exception& ex) - { - { - Error out(_logger); - out << "cannot create thread for connection:\n" << ex; - } - - try - { - _transceiver->close(); - } - catch(const LocalException&) - { - // Here we ignore any exceptions in close(). - } - - // - // Clean up. - // - _transceiver = 0; - _thread = 0; - _state = StateClosed; - - ex.ice_throw(); - } - } -} - -void +bool Ice::ConnectionI::setState(State state, const LocalException& ex) { // @@ -1736,7 +1731,7 @@ Ice::ConnectionI::setState(State state, const LocalException& ex) if(_state == state) // Don't switch twice. { - return; + return false; } if(!_exception.get()) @@ -1777,10 +1772,10 @@ Ice::ConnectionI::setState(State state, const LocalException& ex) // exceptions. Otherwise new requests may retry on a connection // that is not yet marked as closed or closing. // - setState(state); + return setState(state); } -void +bool Ice::ConnectionI::setState(State state) { // @@ -1795,135 +1790,122 @@ Ice::ConnectionI::setState(State state) // // Skip graceful shutdown if we are destroyed before validation. // - if(_state == StateNotValidated && state == StateClosing) + if(_state <= StateNotValidated && state == StateClosing) { state = StateClosed; } if(_state == state) // Don't switch twice. { - return; + return false; } switch(state) { - case StateNotValidated: + case StateNotInitialized: + { + assert(false); + break; + } + + case StateNotValidated: + { + if(_state != StateNotInitialized) { - assert(false); - break; + assert(_state == StateClosed); + return false; } + break; + } - case StateActive: + case StateActive: + { + // + // Can only switch from holding or not validated to + // active. + // + if(_state != StateHolding && _state != StateNotValidated) { - // - // Can only switch from holding or not validated to - // active. - // - if(_state != StateHolding && _state != StateNotValidated) - { - return; - } - if(!_threadPerConnection) - { - registerWithPool(); - } - break; + return false; + } + if(!_threadPerConnection) + { + registerWithPool(); + } + break; + } + + case StateHolding: + { + // + // Can only switch from active or not validated to + // holding. + // + if(_state != StateActive && _state != StateNotValidated) + { + return false; + } + if(!_threadPerConnection) + { + unregisterWithPool(); + } + break; + } + + case StateClosing: + { + // + // Can't change back from closed. + // + if(_state == StateClosed) + { + return false; } + if(!_threadPerConnection) + { + registerWithPool(); // We need to continue to read in closing state. + } + break; + } - case StateHolding: + case StateClosed: + { + if(_sendInProgress) { // - // Can only switch from active or not validated to - // holding. + // Unregister with both the pool and the selector thread. We unregister with + // the pool to ensure that it stops reading on the socket (otherwise, if the + // socket is closed the thread pool would spin always reading 0 from the FD). + // The selector thread will register again the FD with the pool once it's + // done. // - if(_state != StateActive && _state != StateNotValidated) - { - return; - } + _selectorThread->unregister(_transceiver->fd()); if(!_threadPerConnection) { unregisterWithPool(); } - break; - } - case StateClosing: + _transceiver->shutdownWrite(); // Prevent further writes. + } + else if(_state <= StateNotValidated || _threadPerConnection) { // - // Can't change back from closed. + // If we are in thread per connection mode or we're initializing + // the connection in blocking mode, we shutdown both for reading + // and writing. This will unblock and read call with an exception. + // The thread per connection then closes the transceiver. // - if(_state == StateClosed) - { - return; - } - if(!_threadPerConnection) - { - registerWithPool(); // We need to continue to read in closing state. - } - break; + _transceiver->shutdownReadWrite(); } - - case StateClosed: + else { - if(_threadPerConnection) - { - // - // If we are in thread per connection mode, we - // shutdown both for reading and writing. This will - // unblock and read call with an exception. The thread - // per connection then closes the transceiver. - // - _transceiver->shutdownReadWrite(); - } - else if(_state == StateNotValidated) - { - // - // If we change from not validated we can close right - // away. - // - assert(!_registeredWithPool); - - _threadPool->decFdsInUse(); - - // - // We must make sure that nobody is sending when we - // close the transceiver. - // - IceUtil::Mutex::Lock sendSync(_sendMutex); - - try - { - _transceiver->close(); - } - catch(const LocalException&) - { - // Here we ignore any exceptions in close(). - } - - _transceiver = 0; - //notifyAll(); // We notify already below. - } - else - { - // - // Otherwise we first must make sure that we are - // registered, then we unregister, and let finished() - // do the close. - // - registerWithPool(); - unregisterWithPool(); + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. - // - // We must prevent any further writes when _state == StateClosed. - // However, functions such as sendResponse cannot acquire the main - // mutex in order to check _state. Therefore we shut down the write - // end of the transceiver, which causes subsequent write attempts - // to fail with an exception. - // - _transceiver->shutdownWrite(); - } - break; + _transceiver->shutdownWrite(); // Prevent further writes. } + break; + } } // @@ -1954,25 +1936,25 @@ Ice::ConnectionI::setState(State state) { try { - initiateShutdown(); + return initiateShutdown(false); } catch(const LocalException& ex) { setState(StateClosed, ex); } } + + return false; } -void -Ice::ConnectionI::initiateShutdown() const +bool +Ice::ConnectionI::initiateShutdown(bool queue) { assert(_state == StateClosing); assert(_dispatchCount == 0); if(!_endpoint->datagram()) { - IceUtil::Mutex::Lock sendSync(_sendMutex); - // // Before we shut down, we send a close connection message. // @@ -1989,12 +1971,9 @@ Ice::ConnectionI::initiateShutdown() const os.write((Byte)1); // Compression status: compression supported but not used. os.write(headerSize); // Message size. - // - // Send the message. - // - os.i = os.b.begin(); - traceHeader("sending close connection", os, _logger, _traceLevels); - _transceiver->write(os, _endpoint->timeout()); + OutgoingMessage message(&os, false); + return sendMessage(message, queue); + // // The CloseConnection message should be sufficient. Closing the write // end of the socket is probably an artifact of how things were done @@ -2005,6 +1984,610 @@ Ice::ConnectionI::initiateShutdown() const // //_transceiver->shutdownWrite(); } + + return false; +} + +SocketStatus +Ice::ConnectionI::initialize() +{ + int timeout = 0; + if(!_startCallback || _threadPerConnection) + { + DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); + if(defaultsAndOverrides->overrideConnectTimeout) + { + timeout = defaultsAndOverrides->overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint->timeout(); + } + } + + try + { + SocketStatus status = _transceiver->initialize(timeout); + if(status != Finished) + { + if(!_startCallback || _threadPerConnection) + { + throw TimeoutException(__FILE__, __LINE__); + } + return status; + } + } + catch(const TimeoutException&) + { + throw ConnectTimeoutException(__FILE__, __LINE__); + } + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } + + // + // Update the connection description once the transceiver is initialized. + // + const_cast<string&>(_desc) = _transceiver->toString(); + + setState(StateNotValidated); + } + + return Finished; +} + +SocketStatus +Ice::ConnectionI::validate() +{ + if(!_endpoint->datagram()) // Datagram connections are always implicitly validated. + { + Int timeout = 0; + if(!_startCallback || _threadPerConnection) + { + if(_instance->defaultsAndOverrides()->overrideConnectTimeout) + { + timeout = _instance->defaultsAndOverrides()->overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint->timeout(); + } + } + + if(_adapter) // The server side has the active role for connection validation. + { + BasicStream& os = _stream; + if(os.b.empty()) + { + os.write(magic[0]); + os.write(magic[1]); + os.write(magic[2]); + os.write(magic[3]); + os.write(protocolMajor); + os.write(protocolMinor); + os.write(encodingMajor); + os.write(encodingMinor); + os.write(validateConnectionMsg); + os.write(static_cast<Byte>(0)); // Compression status (always zero for validate connection). + os.write(headerSize); // Message size. + os.i = os.b.begin(); + traceSend(os, _logger, _traceLevels); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + assert(_startCallback && !_threadPerConnection); + } + + try + { + if(!_transceiver->write(os, timeout)) + { + if(!_startCallback || _threadPerConnection) + { + throw TimeoutException(__FILE__, __LINE__); + } + return NeedWrite; + } + } + catch(const TimeoutException&) + { + throw ConnectTimeoutException(__FILE__, __LINE__); + } + } + else // The client side has the passive role for connection validation. + { + BasicStream& is = _stream; + if(is.b.empty()) + { + is.b.resize(headerSize); + is.i = is.b.begin(); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + assert(_startCallback && !_threadPerConnection); + } + + try + { + if(!_transceiver->read(is, timeout)) + { + if(!_startCallback || _threadPerConnection) + { + throw TimeoutException(__FILE__, __LINE__); + } + return NeedRead; + } + } + catch(const TimeoutException&) + { + throw ConnectTimeoutException(__FILE__, __LINE__); + } + + assert(is.i == is.b.end()); + is.i = is.b.begin(); + Byte m[4]; + is.read(m[0]); + is.read(m[1]); + is.read(m[2]); + is.read(m[3]); + if(m[0] != magic[0] || m[1] != magic[1] || m[2] != magic[2] || m[3] != magic[3]) + { + BadMagicException ex(__FILE__, __LINE__); + ex.badMagic = Ice::ByteSeq(&m[0], &m[0] + sizeof(magic)); + throw ex; + } + Byte pMajor; + Byte pMinor; + is.read(pMajor); + is.read(pMinor); + if(pMajor != protocolMajor) + { + UnsupportedProtocolException ex(__FILE__, __LINE__); + ex.badMajor = static_cast<unsigned char>(pMajor); + ex.badMinor = static_cast<unsigned char>(pMinor); + ex.major = static_cast<unsigned char>(protocolMajor); + ex.minor = static_cast<unsigned char>(protocolMinor); + throw ex; + } + Byte eMajor; + Byte eMinor; + is.read(eMajor); + is.read(eMinor); + if(eMajor != encodingMajor) + { + UnsupportedEncodingException ex(__FILE__, __LINE__); + ex.badMajor = static_cast<unsigned char>(eMajor); + ex.badMinor = static_cast<unsigned char>(eMinor); + ex.major = static_cast<unsigned char>(encodingMajor); + ex.minor = static_cast<unsigned char>(encodingMinor); + throw ex; + } + Byte messageType; + is.read(messageType); + if(messageType != validateConnectionMsg) + { + throw ConnectionNotValidatedException(__FILE__, __LINE__); + } + Byte compress; + is.read(compress); // Ignore compression status for validate connection. + Int size; + is.read(size); + if(size != headerSize) + { + throw IllegalMessageSizeException(__FILE__, __LINE__); + } + traceRecv(is, _logger, _traceLevels); + } + } + + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + _stream.resize(0); + _stream.i = _stream.b.begin(); + + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } + + // + // We start out in holding state. + // + setState(StateHolding); + } + + return Finished; +} + +bool +Ice::ConnectionI::send(int timeout) +{ + assert(_transceiver); + assert(!_sendStreams.empty()); + + while(!_sendStreams.empty()) + { + OutgoingMessage* message = &_sendStreams.front(); + + // + // Prepare the message stream for writing if necessary. + // + if(!message->stream->i) + { + message->stream->i = message->stream->b.begin(); + if(message->compress && message->stream->b.size() >= 100) // Only compress messages larger than 100 bytes. + { + // + // Message compressed. Request compressed response, if any. + // + message->stream->b[9] = 2; + + // + // Do compression. + // + BasicStream stream(_instance.get()); + doCompress(*message->stream, stream); + + if(message->outAsync) + { + trace("sending asynchronous request", *message->stream, _logger, _traceLevels); + } + else + { + traceSend(*message->stream, _logger, _traceLevels); + } + + message->adopt(&stream); // Adopt the compressed stream. + message->stream->i = message->stream->b.begin(); + } + else + { + if(message->compress) + { + // + // Message not compressed. Request compressed response, if any. + // + message->stream->b[9] = 1; + } + + // + // No compression, just fill in the message size. + // + Int sz = static_cast<Int>(message->stream->b.size()); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), message->stream->b.begin() + 10); +#else + copy(p, p + sizeof(Int), message->stream->b.begin() + 10); +#endif + message->stream->i = message->stream->b.begin(); + + if(message->outAsync) + { + trace("sending asynchronous request", *message->stream, _logger, _traceLevels); + } + else + { + traceSend(*message->stream, _logger, _traceLevels); + } + } + } + + // + // Send the first message. + // + assert(message->stream->i); + if(!_transceiver->write(*message->stream, timeout)) + { + assert(timeout == 0); + return false; + } + + // + // Notify the message that it was sent. + // + message->sent(this, timeout == 0); // timeout == 0 indicates that this is called by the selector thread. + _sendStreams.pop_front(); + } + + return true; +} + +bool +Ice::ConnectionI::sendMessage(OutgoingMessage& message, bool queue) +{ + assert(_state != StateClosed); + + // + // TODO: Remove support for foreground send? If set to true, messages are sent + // by the calling thread. Foreground send might still be useful for transports + // that don't support non-blocking send. + // + bool foreground = false; + + message.stream->i = 0; // Reset the message stream iterator before starting sending the message. + + // + // If another thread is currently sending messages, we queue the message in _queuedStreams + // if we're not required to send the message in the foreground. If we're required to send + // the request in the foreground we wait until no more threads send messages. + // + if(_sendInProgress) + { + if(!foreground) + { + _queuedStreams.push_back(message); + _queuedStreams.back().adopt(0); + return false; + } + else if(queue) + { + // + // Add the message to _sendStreams if requested, this is useful for sendResponse() to + // send the close connection message after sending the response. + // + _sendStreams.push_back(message); + return true; // The calling thread must send the messages by calling finishSendMessage() + } + else + { + ++_waitingForSend; + while(_sendInProgress) + { + wait(); + } + --_waitingForSend; + + if(_state == StateClosed) + { + assert(_exception.get()); + _exception->ice_throw(); + } + } + } + + assert(!_sendInProgress); + + // + // Attempt to send the message without blocking. If the send blocks, we register + // the connection with the selector thread or we request the caller to call + // finishSendMessage() outside the synchronization. + // + + message.stream->i = message.stream->b.begin(); + + if(message.compress && message.stream->b.size() >= 100) // Only compress messages larger than 100 bytes. + { + // + // Message compressed. Request compressed response, if any. + // + message.stream->b[9] = 2; + + // + // Do compression. + // + BasicStream stream(_instance.get()); + doCompress(*message.stream, stream); + stream.i = stream.b.begin(); + + if(message.outAsync) + { + trace("sending asynchronous request", *message.stream, _logger, _traceLevels); + } + else + { + traceSend(*message.stream, _logger, _traceLevels); + } + + // + // Send the message without blocking. + // + if(!foreground && _transceiver->write(stream, 0)) + { + message.sent(this, false); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeout = + IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + } + return false; + } + + _sendStreams.push_back(message); + _sendStreams.back().adopt(&stream); + } + else + { + if(message.compress) + { + // + // Message not compressed. Request compressed response, if any. + // + message.stream->b[9] = 1; + } + + // + // No compression, just fill in the message size. + // + Int sz = static_cast<Int>(message.stream->b.size()); + const Byte* p = reinterpret_cast<const Byte*>(&sz); +#ifdef ICE_BIG_ENDIAN + reverse_copy(p, p + sizeof(Int), message.stream->b.begin() + 10); +#else + copy(p, p + sizeof(Int), message.stream->b.begin() + 10); +#endif + message.stream->i = message.stream->b.begin(); + + if(message.outAsync) + { + trace("sending asynchronous request", *message.stream, _logger, _traceLevels); + } + else + { + traceSend(*message.stream, _logger, _traceLevels); + } + + // + // Send the message without blocking. + // + if(!foreground && _transceiver->write(*message.stream, 0)) + { + message.sent(this, false); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeout = + IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + } + return false; + } + + _sendStreams.push_back(message); + if(!foreground) + { + _sendStreams.back().adopt(0); + } + } + + _sendInProgress = true; + if(!foreground) + { + _selectorThread->_register(_transceiver->fd(), this, NeedWrite, _endpoint->timeout()); + return false; // The selector thread will send the message. + } + else + { + return true; // The calling thread must send the message by calling finishSendMessage() + } +} + +void +Ice::ConnectionI::finishSendMessage() +{ + try + { + // + // Send the send messages with a blocking write(). + // + send(_endpoint->timeout()); + } + catch(const Ice::LocalException& ex) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + setState(StateClosed, ex); + + for(deque<OutgoingMessage>::const_iterator p = _sendStreams.begin(); p != _sendStreams.end(); ++p) + { + if(p->adopted) + { + delete p->stream; + } + } + _sendStreams.clear(); + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver->shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + notifyAll(); + + assert(_exception.get()); + _exception->ice_throw(); + } + + + // + // Clear the _sendInProgress flag and notify waiting threads that we're not + // sending anymore data. + // + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(_sendStreams.empty()); + + if(_state == StateClosed) + { + _sendInProgress = false; + if(_threadPerConnection) + { + _transceiver->shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + notifyAll(); + } + else if(_waitingForSend > 0) + { + _sendInProgress = false; + notifyAll(); + } + else if(_queuedStreams.empty()) + { + if(_acmTimeout > 0) + { + _acmAbsoluteTimeout = IceUtil::Time::now(IceUtil::Time::Monotonic) + IceUtil::Time::seconds(_acmTimeout); + } + _sendInProgress = false; + } + else + { + _selectorThread->_register(_transceiver->fd(), this, NeedWrite, _endpoint->timeout()); + } +} + +void +Ice::ConnectionI::finishStart() +{ + // + // We set _startCallback to null to break potential cyclic reference count + // and because the destructor checks for it to ensure that we always invoke + // on the callback. + // + + StartCallbackPtr callback; + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + swap(callback, _startCallback); + } + if(callback) + { + callback->connectionStartCompleted(this); + } +} + +void +Ice::ConnectionI::finishStart(const Ice::LocalException& ex) +{ + // + // We set _startCallback to null to break potential cyclic reference count + // and because the destructor checks for it to ensure that we always invoke + // on the callback. + // + + StartCallbackPtr callback; + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + swap(callback, _startCallback); + } + if(callback) + { + callback->connectionStartFailed(this, ex); + } } void @@ -2213,7 +2796,7 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request { case closeConnectionMsg: { - traceHeader("received close connection", stream, _logger, _traceLevels); + traceRecv(stream, _logger, _traceLevels); if(_endpoint->datagram()) { if(_warn) @@ -2233,13 +2816,12 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request { if(_state == StateClosing) { - traceRequest("received request during closing\n" - "(ignored by server, client will retry)", - stream, _logger, _traceLevels); + trace("received request during closing\n(ignored by server, client will retry)", stream, _logger, + _traceLevels); } else { - traceRequest("received request", stream, _logger, _traceLevels); + traceRecv(stream, _logger, _traceLevels); stream.read(requestId); invokeNum = 1; servantManager = _servantManager; @@ -2253,13 +2835,12 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request { if(_state == StateClosing) { - traceBatchRequest("received batch request during closing\n" - "(ignored by server, client will retry)", - stream, _logger, _traceLevels); + trace("received batch request during closing\n(ignored by server, client will retry)", stream, + _logger, _traceLevels); } else { - traceBatchRequest("received batch request", stream, _logger, _traceLevels); + traceRecv(stream, _logger, _traceLevels); stream.read(invokeNum); if(invokeNum < 0) { @@ -2275,12 +2856,12 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request case replyMsg: { - traceReply("received reply", stream, _logger, _traceLevels); + traceRecv(stream, _logger, _traceLevels); stream.read(requestId); map<Int, Outgoing*>::iterator p = _requests.end(); - map<Int, AsyncRequest>::iterator q = _asyncRequests.end(); + map<Int, OutgoingAsyncPtr>::iterator q = _asyncRequests.end(); if(_requestsHint != _requests.end()) { @@ -2334,7 +2915,7 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request { assert(q != _asyncRequests.end()); - outAsync = q->second.p; + outAsync = q->second; if(q == _asyncRequestsHint) { @@ -2352,7 +2933,7 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request case validateConnectionMsg: { - traceHeader("received validate connection", stream, _logger, _traceLevels); + traceRecv(stream, _logger, _traceLevels); if(_warn) { Warning out(_logger); @@ -2363,9 +2944,7 @@ Ice::ConnectionI::parseMessage(BasicStream& stream, Int& invokeNum, Int& request default: { - traceHeader("received unknown message\n" - "(invalid, closing connection)", - stream, _logger, _traceLevels); + trace("received unknown message\n(invalid, closing connection)", stream, _logger, _traceLevels); throw UnknownMessageException(__FILE__, __LINE__); break; } @@ -2448,30 +3027,26 @@ Ice::ConnectionI::invokeAll(BasicStream& stream, Int invokeNum, Int requestId, B void Ice::ConnectionI::run() { - // - // For non-datagram connections, the thread-per-connection must - // validate and activate this connection, and not in the - // connection factory. Please see the comments in the connection - // factory for details. - // - if(!_endpoint->datagram()) + try + { + // + // Initialize the connection transceiver and validate the connection using + // blocking operations. + // + SocketStatus status; + + status = initialize(); + assert(status == Finished); + + status = validate(); + assert(status == Finished); + } + catch(const LocalException& ex) { - try - { - validate(); - } - catch(const LocalException&) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - - assert(_state == StateClosed); - - // - // We must make sure that nobody is sending when we close - // the transceiver. - // - IceUtil::Mutex::Lock sendSync(_sendMutex); - + setState(StateClosed, ex); + if(_transceiver) { try @@ -2482,15 +3057,17 @@ Ice::ConnectionI::run() { // Here we ignore any exceptions in close(). } - + _transceiver = 0; } notifyAll(); - return; } - - activate(); + + finishStart(ex); + return; } + + finishStart(); const bool warnUdp = _instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Datagrams") > 0; @@ -2615,9 +3192,6 @@ Ice::ConnectionI::run() OutgoingAsyncPtr outAsync; auto_ptr<LocalException> localEx; - - map<Int, Outgoing*> requests; - map<Int, AsyncRequest> asyncRequests; { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); @@ -2638,12 +3212,24 @@ Ice::ConnectionI::run() // if(_state == StateClosed) { + if(_sendInProgress) + { + _selectorThread->unregister(_transceiver->fd()); + } + // - // We must make sure that nobody is sending when we close - // the transceiver. + // Prevent further writes. // - IceUtil::Mutex::Lock sendSync(_sendMutex); - + _transceiver->shutdownWrite(); + + // + // We must make sure that nobody is sending before closing the transceiver. + // + while(_sendInProgress) + { + wait(); + } + try { _transceiver->close(); @@ -2652,26 +3238,15 @@ Ice::ConnectionI::run() { localEx.reset(dynamic_cast<LocalException*>(ex.ice_clone())); } - _transceiver = 0; notifyAll(); // - // We cannot simply return here. We have to make sure - // that all requests (regular and async) are notified - // about the closed connection below. + // We cannot simply return here. We have to make sure that all requests (regular and + // async) are notified about the closed connection below. // closed = true; } - - if(_state == StateClosed || _state == StateClosing) - { - requests.swap(_requests); - _requestsHint = _requests.end(); - - asyncRequests.swap(_asyncRequests); - _asyncRequestsHint = _asyncRequests.end(); - } } // @@ -2690,21 +3265,33 @@ Ice::ConnectionI::run() // invokeAll(stream, invokeNum, requestId, compress, servantManager, adapter); - for(map<Int, Outgoing*>::iterator p = requests.begin(); p != requests.end(); ++p) - { - p->second->finished(*_exception.get()); // The exception is immutable at this point. - } - - for(map<Int, AsyncRequest>::iterator q = asyncRequests.begin(); q != asyncRequests.end(); ++q) + if(closed) { - q->second.p->__finished(*_exception.get()); // The exception is immutable at this point. - } + // Note: the streams must be cleared first because they expect the Outgoing objects to still be valid. + for(deque<OutgoingMessage>::iterator o = _queuedStreams.begin(); o != _queuedStreams.end(); ++o) + { + o->finished(*_exception.get()); + } + _queuedStreams.clear(); + + for(map<Int, Outgoing*>::iterator p = _requests.begin(); p != _requests.end(); ++p) + { + p->second->finished(*_exception.get()); // The exception is immutable at this point. + } + _requests.clear(); + for(map<Int, OutgoingAsyncPtr>::iterator q = _asyncRequests.begin(); q != _asyncRequests.end(); ++q) + { + q->second->__finished(*_exception.get()); // The exception is immutable at this point. + } + _asyncRequests.clear(); + } + if(localEx.get()) { assert(closed); localEx->ice_throw(); - } + } } } diff --git a/cpp/src/Ice/ConnectionI.h b/cpp/src/Ice/ConnectionI.h index 8e712cb3b42..9d7b9cc15af 100644 --- a/cpp/src/Ice/ConnectionI.h +++ b/cpp/src/Ice/ConnectionI.h @@ -26,11 +26,16 @@ #include <Ice/TraceLevelsF.h> #include <Ice/OutgoingAsyncF.h> #include <Ice/EventHandler.h> +#include <Ice/SelectorThread.h> + +#include <deque> namespace IceInternal { class Outgoing; +class BatchOutgoing; +class OutgoingMessageCallback; } @@ -39,23 +44,35 @@ namespace Ice class LocalException; -class ICE_API ConnectionI : public Connection, public IceInternal::EventHandler, +class ICE_API ConnectionI : public Connection, + public IceInternal::EventHandler, + public IceInternal::SocketReadyCallback, public IceUtil::Monitor<IceUtil::Mutex> { public: - void validate(); + class StartCallback : virtual public IceUtil::Shared + { + public: + + virtual void connectionStartCompleted(const ConnectionIPtr&) = 0; + virtual void connectionStartFailed(const ConnectionIPtr&, const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<StartCallback> StartCallbackPtr; + enum DestructionReason { ObjectAdapterDeactivated, CommunicatorDestroyed }; + + void start(const StartCallbackPtr&); void activate(); void hold(); void destroy(DestructionReason); virtual void close(bool); // From Connection. - bool isDestroyed() const; + bool isActiveOrHolding() const; bool isFinished() const; void throwException() const; // Throws the connection exception if destroyed. @@ -65,14 +82,18 @@ public: void monitor(); - void sendRequest(IceInternal::BasicStream*, IceInternal::Outgoing*, bool); - void sendAsyncRequest(IceInternal::BasicStream*, const IceInternal::OutgoingAsyncPtr&, bool); + bool sendRequest(IceInternal::Outgoing*, bool, bool); + void sendAsyncRequest(const IceInternal::OutgoingAsyncPtr&, bool, bool); void prepareBatchRequest(IceInternal::BasicStream*); void finishBatchRequest(IceInternal::BasicStream*, bool); void abortBatchRequest(); + virtual void flushBatchRequests(); // From Connection. + bool flushBatchRequests(IceInternal::BatchOutgoing*); + void flushAsyncBatchRequests(const IceInternal::BatchOutgoingAsyncPtr&); + void sendResponse(IceInternal::BasicStream*, Byte); void sendNoResponse(); @@ -88,7 +109,7 @@ public: // virtual bool datagram() const; virtual bool readable() const; - virtual void read(IceInternal::BasicStream&); + virtual bool read(IceInternal::BasicStream&); virtual void message(IceInternal::BasicStream&, const IceInternal::ThreadPoolPtr&); virtual void finished(const IceInternal::ThreadPoolPtr&); virtual void exception(const LocalException&); @@ -97,6 +118,12 @@ public: virtual Ice::Int timeout() const; // From Connection. virtual std::string toString() const; // From Connection and EvantHandler. + // + // Operations from SocketReadyCallback + // + virtual IceInternal::SocketStatus socketReady(bool); + virtual void socketTimeout(); + // SSL plug-in needs to be able to get the transceiver. IceInternal::TransceiverPtr getTransceiver() const; @@ -105,12 +132,13 @@ private: ConnectionI(const IceInternal::InstancePtr&, const IceInternal::TransceiverPtr&, const IceInternal::EndpointIPtr&, const ObjectAdapterPtr&, bool, size_t); virtual ~ConnectionI(); - void start(); + friend class IceInternal::IncomingConnectionFactory; friend class IceInternal::OutgoingConnectionFactory; enum State { + StateNotInitialized, StateNotValidated, StateActive, StateHolding, @@ -118,13 +146,53 @@ private: StateClosed }; - void resetBatch(bool); - void flushBatchRequestsInternal(bool); + bool setState(State, const LocalException&); + bool setState(State); + + bool initiateShutdown(bool); + + struct OutgoingMessage + { + OutgoingMessage() + { + } + + OutgoingMessage(IceInternal::BasicStream* str, bool comp) : + stream(str), out(0), compress(comp), response(false), adopted(false) + { + } + + OutgoingMessage(IceInternal::OutgoingMessageCallback* o, IceInternal::BasicStream* str, bool comp, bool resp) : + stream(str), out(o), compress(comp), response(resp), adopted(false) + { + } + + OutgoingMessage(const IceInternal::OutgoingAsyncMessageCallbackPtr& o, IceInternal::BasicStream* str, + bool comp, bool resp) : + stream(str), out(0), outAsync(o), compress(comp), response(resp), adopted(false) + { + } + + void adopt(IceInternal::BasicStream*); + void sent(ConnectionI*, bool); + void finished(const Ice::LocalException&); + + IceInternal::BasicStream* stream; + IceInternal::OutgoingMessageCallback* out; + IceInternal::OutgoingAsyncMessageCallbackPtr outAsync; + bool compress; + bool response; + bool adopted; + }; - void setState(State, const LocalException&); - void setState(State); + IceInternal::SocketStatus initialize(); + IceInternal::SocketStatus validate(); + bool send(int); + bool sendMessage(OutgoingMessage&, bool = false); + void finishSendMessage(); - void initiateShutdown() const; + void finishStart(); + void finishStart(const Ice::LocalException&); void registerWithPool(); void unregisterWithPool(); @@ -171,6 +239,10 @@ private: int _finishedCount; const IceInternal::ThreadPoolPtr _threadPool; + const IceInternal::SelectorThreadPtr _selectorThread; + + StartCallbackPtr _startCallback; + const bool _warn; const int _acmTimeout; @@ -183,13 +255,8 @@ private: std::map<Int, IceInternal::Outgoing*> _requests; std::map<Int, IceInternal::Outgoing*>::iterator _requestsHint; - struct AsyncRequest - { - IceInternal::OutgoingAsyncPtr p; - IceUtil::Time t; - }; - std::map<Int, AsyncRequest> _asyncRequests; - std::map<Int, AsyncRequest>::iterator _asyncRequestsHint; + std::map<Int, IceInternal::OutgoingAsyncPtr> _asyncRequests; + std::map<Int, IceInternal::OutgoingAsyncPtr>::iterator _asyncRequestsHint; std::auto_ptr<LocalException> _exception; @@ -200,16 +267,15 @@ private: bool _batchRequestCompress; size_t _batchMarker; + std::deque<OutgoingMessage> _queuedStreams; + std::deque<OutgoingMessage> _sendStreams; + bool _sendInProgress; + int _waitingForSend; + int _dispatchCount; State _state; // The current state. IceUtil::Time _stateTime; // The last time when the state was changed. - - // - // We have a separate mutex for sending, so that we don't block - // the whole connection when we do a blocking send. - // - IceUtil::Mutex _sendMutex; }; } diff --git a/cpp/src/Ice/ConnectionMonitor.cpp b/cpp/src/Ice/ConnectionMonitor.cpp index cf4104e805d..a462251679b 100644 --- a/cpp/src/Ice/ConnectionMonitor.cpp +++ b/cpp/src/Ice/ConnectionMonitor.cpp @@ -69,7 +69,7 @@ IceInternal::ConnectionMonitor::~ConnectionMonitor() } void -IceInternal::ConnectionMonitor::run() +IceInternal::ConnectionMonitor::runTimerTask() { set<ConnectionIPtr> connections; diff --git a/cpp/src/Ice/ConnectionMonitor.h b/cpp/src/Ice/ConnectionMonitor.h index bfd7954dc4c..63f4be8457e 100644 --- a/cpp/src/Ice/ConnectionMonitor.h +++ b/cpp/src/Ice/ConnectionMonitor.h @@ -36,7 +36,7 @@ private: virtual ~ConnectionMonitor(); friend class Instance; - virtual void run(); + virtual void runTimerTask(); InstancePtr _instance; std::set<Ice::ConnectionIPtr> _connections; diff --git a/cpp/src/Ice/ConnectionRequestHandler.cpp b/cpp/src/Ice/ConnectionRequestHandler.cpp new file mode 100644 index 00000000000..dffab29e69b --- /dev/null +++ b/cpp/src/Ice/ConnectionRequestHandler.cpp @@ -0,0 +1,107 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/ConnectionRequestHandler.h> +#include <Ice/Proxy.h> +#include <Ice/Reference.h> +#include <Ice/ConnectionI.h> +#include <Ice/RouterInfo.h> +#include <Ice/Outgoing.h> +#include <Ice/OutgoingAsync.h> + +using namespace std; +using namespace IceInternal; + +ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference, const Ice::ObjectPrx& proxy) : + RequestHandler(reference), + _response(reference->getMode() == Reference::ModeTwoway) +{ + _connection = _reference->getConnection(_compress); + RouterInfoPtr ri = reference->getRouterInfo(); + if(ri) + { + ri->addProxy(proxy); + } +} + +ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference, + const Ice::ConnectionIPtr& connection, + bool compress) : + RequestHandler(reference), + _response(reference->getMode() == Reference::ModeTwoway), + _connection(connection), + _compress(compress) +{ +} + +void +ConnectionRequestHandler::prepareBatchRequest(BasicStream* out) +{ + _connection->prepareBatchRequest(out); +} + +void +ConnectionRequestHandler::finishBatchRequest(BasicStream* out) +{ + _connection->finishBatchRequest(out, _compress); +} + +void +ConnectionRequestHandler::abortBatchRequest() +{ + _connection->abortBatchRequest(); +} + +Ice::ConnectionI* +ConnectionRequestHandler::sendRequest(Outgoing* out) +{ + return (!_connection->sendRequest(out, _compress, _response) || _response) ? _connection.get() : 0; +} + +void +ConnectionRequestHandler::sendAsyncRequest(const OutgoingAsyncPtr& out) +{ + try + { + _connection->sendAsyncRequest(out, _compress, _response); + } + catch(const LocalExceptionWrapper& ex) + { + out->__finished(ex); + } + catch(const Ice::LocalException& ex) + { + out->__finished(ex); + } +} + +bool +ConnectionRequestHandler::flushBatchRequests(BatchOutgoing* out) +{ + return _connection->flushBatchRequests(out); +} + +void +ConnectionRequestHandler::flushAsyncBatchRequests(const BatchOutgoingAsyncPtr& out) +{ + try + { + _connection->flushAsyncBatchRequests(out); + } + catch(const Ice::LocalException& ex) + { + out->__finished(ex); + } +} + +Ice::ConnectionIPtr +ConnectionRequestHandler::getConnection(bool wait) +{ + return _connection; +} diff --git a/cpp/src/Ice/ConnectionRequestHandler.h b/cpp/src/Ice/ConnectionRequestHandler.h new file mode 100644 index 00000000000..785cda3b5b6 --- /dev/null +++ b/cpp/src/Ice/ConnectionRequestHandler.h @@ -0,0 +1,48 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_CONNECTION_REQUEST_HANDLER_H +#define ICE_CONNECTION_REQUEST_HANDLER_H + +#include <Ice/RequestHandler.h> +#include <Ice/ReferenceF.h> +#include <Ice/ProxyF.h> + +namespace IceInternal +{ + +class ConnectionRequestHandler : public RequestHandler +{ +public: + + ConnectionRequestHandler(const ReferencePtr&, const Ice::ObjectPrx&); + ConnectionRequestHandler(const ReferencePtr&, const Ice::ConnectionIPtr&, bool); + + virtual void prepareBatchRequest(BasicStream*); + virtual void finishBatchRequest(BasicStream*); + virtual void abortBatchRequest(); + + virtual Ice::ConnectionI* sendRequest(Outgoing*); + virtual void sendAsyncRequest(const OutgoingAsyncPtr&); + + virtual bool flushBatchRequests(BatchOutgoing*); + virtual void flushAsyncBatchRequests(const BatchOutgoingAsyncPtr&); + + virtual Ice::ConnectionIPtr getConnection(bool); + +private: + + const bool _response; + Ice::ConnectionIPtr _connection; + bool _compress; +}; + +} + +#endif diff --git a/cpp/src/Ice/Connector.h b/cpp/src/Ice/Connector.h index 347997afbce..825afa86383 100644 --- a/cpp/src/Ice/Connector.h +++ b/cpp/src/Ice/Connector.h @@ -14,6 +14,12 @@ #include <Ice/ConnectorF.h> #include <Ice/TransceiverF.h> +#ifdef _WIN32 +# include <winsock2.h> +#else +# define SOCKET int +#endif + namespace IceInternal { @@ -22,6 +28,7 @@ class ICE_API Connector : public ::IceUtil::Shared public: virtual TransceiverPtr connect(int) = 0; + virtual Ice::Short type() const = 0; virtual std::string toString() const = 0; diff --git a/cpp/src/Ice/EndpointFactoryManager.cpp b/cpp/src/Ice/EndpointFactoryManager.cpp index a2a7900c26d..9b1a126a1d6 100644 --- a/cpp/src/Ice/EndpointFactoryManager.cpp +++ b/cpp/src/Ice/EndpointFactoryManager.cpp @@ -66,8 +66,6 @@ IceInternal::EndpointFactoryManager::get(Short type) const EndpointIPtr IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint) const { - IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? - const string delim = " \t\n\r"; string::size_type beg = str.find_first_not_of(delim); @@ -91,30 +89,40 @@ IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint) protocol = _instance->defaultsAndOverrides()->defaultProtocol; } - // - // TODO: Optimize with a map? - // - for(vector<EndpointFactoryPtr>::size_type i = 0; i < _factories.size(); i++) + EndpointFactoryPtr factory; { - if(_factories[i]->protocol() == protocol) + IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? + + // + // TODO: Optimize with a map? + // + for(vector<EndpointFactoryPtr>::size_type i = 0; i < _factories.size(); i++) { + if(_factories[i]->protocol() == protocol) + { + factory = _factories[i]; + } + } + } + + if(factory) + { #if 1 - return _factories[i]->create(str.substr(end), oaEndpoint); + return factory->create(str.substr(end), oaEndpoint); #else - // Code below left in place for debugging. - - EndpointIPtr e = _factories[i]->create(str.substr(end), oaEndpoint); - BasicStream bs(_instance.get()); - e->streamWrite(&bs); - bs.i = bs.b.begin(); - short type; - bs.read(type); - EndpointIPtr ue = new IceInternal::UnknownEndpointI(type, &bs); - cerr << "Normal: " << e->toString() << endl; - cerr << "Opaque: " << ue->toString() << endl; - return e; + // Code below left in place for debugging. + + EndpointIPtr e = factory->create(str.substr(end), oaEndpoint); + BasicStream bs(_instance.get()); + e->streamWrite(&bs); + bs.i = bs.b.begin(); + short type; + bs.read(type); + EndpointIPtr ue = new IceInternal::UnknownEndpointI(type, &bs); + cerr << "Normal: " << e->toString() << endl; + cerr << "Opaque: " << ue->toString() << endl; + return e; #endif - } } // @@ -124,22 +132,20 @@ IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint) if(protocol == "opaque") { EndpointIPtr ue = new UnknownEndpointI(str.substr(end)); - for(vector<EndpointFactoryPtr>::size_type i = 0; i < _factories.size(); i++) + factory = get(ue->type()); + if(factory) { - if(_factories[i]->type() == ue->type()) - { - // - // Make a temporary stream, write the opaque endpoint data into the stream, - // and ask the factory to read the endpoint data from that stream to create - // the actual endpoint. - // - BasicStream bs(_instance.get()); - ue->streamWrite(&bs); - bs.i = bs.b.begin(); - short type; - bs.read(type); - return _factories[i]->read(&bs); - } + // + // Make a temporary stream, write the opaque endpoint data into the stream, + // and ask the factory to read the endpoint data from that stream to create + // the actual endpoint. + // + BasicStream bs(_instance.get()); + ue->streamWrite(&bs); + bs.i = bs.b.begin(); + short type; + bs.read(type); + return factory->read(&bs); } return ue; // Endpoint is opaque, but we don't have a factory for its type. } @@ -150,20 +156,13 @@ IceInternal::EndpointFactoryManager::create(const string& str, bool oaEndpoint) EndpointIPtr IceInternal::EndpointFactoryManager::read(BasicStream* s) const { - IceUtil::Mutex::Lock sync(*this); // TODO: Necessary? - Short type; s->read(type); - // - // TODO: Optimize with a map? - // - for(vector<EndpointFactoryPtr>::size_type i = 0; i < _factories.size(); i++) + EndpointFactoryPtr factory = get(type); + if(factory) { - if(_factories[i]->type() == type) - { - return _factories[i]->read(s); - } + return factory->read(s); } return new UnknownEndpointI(type, s); diff --git a/cpp/src/Ice/EndpointI.cpp b/cpp/src/Ice/EndpointI.cpp index 45f88a6cde8..f3505005f28 100644 --- a/cpp/src/Ice/EndpointI.cpp +++ b/cpp/src/Ice/EndpointI.cpp @@ -8,7 +8,110 @@ // ********************************************************************** #include <Ice/EndpointI.h> +#include <Ice/Instance.h> +#include <Ice/LocalException.h> +#include <Ice/Network.h> -using namespace Ice; +using namespace std; +using namespace IceInternal; Ice::LocalObject* IceInternal::upCast(EndpointI* p) { return p; } +IceUtil::Shared* IceInternal::upCast(EndpointHostResolver* p) { return p; } + +vector<ConnectorPtr> +IceInternal::EndpointI::connectors(const vector<struct sockaddr_in>& addrs) const +{ + // + // This method must be extended by endpoints which use the EndpointHostResolver to create + // connectors from IP addresses. + // + assert(false); + return vector<ConnectorPtr>(); +} + +IceInternal::EndpointHostResolver::EndpointHostResolver(const InstancePtr& instance) : + _instance(instance), + _destroyed(false) +{ + start(); +} + +void +IceInternal::EndpointHostResolver::resolve(const string& host, int port, const EndpointIPtr& endpoint, + const EndpointI_connectorsPtr& callback) +{ + // + // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve + // entry and the thread will take care of getting the endpoint addresses. + // + vector<struct sockaddr_in> addrs = getAddresses(host, port, false); + if(!addrs.empty()) + { + callback->connectors(endpoint->connectors(addrs)); + return; + } + + Lock sync(*this); + assert(!_destroyed); + + ResolveEntry entry; + entry.host = host; + entry.port = port; + entry.endpoint = endpoint; + entry.callback = callback; + _queue.push_back(entry); + notify(); +} + +void +IceInternal::EndpointHostResolver::destroy() +{ + Lock sync(*this); + assert(!_destroyed); + _destroyed = true; + notify(); +} + +void +IceInternal::EndpointHostResolver::run() +{ + if(_instance->initializationData().threadHook) + { + _instance->initializationData().threadHook->start(); + } + + while(true) + { + ResolveEntry resolve; + + { + Lock sync(*this); + + while(!_destroyed && _queue.empty()) + { + wait(); + } + + if(_destroyed) + { + break; + } + + resolve = _queue.front(); + _queue.pop_front(); + } + + resolve.callback->connectors(resolve.endpoint->connectors(getAddresses(resolve.host, resolve.port))); + } + + for(deque<ResolveEntry>::const_iterator p = _queue.begin(); p != _queue.end(); ++p) + { + p->callback->exception(Ice::CommunicatorDestroyedException(__FILE__, __LINE__)); + } + _queue.clear(); + + if(_instance->initializationData().threadHook) + { + _instance->initializationData().threadHook->stop(); + } +} diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h index 9470d0e4468..1d5eff2df76 100644 --- a/cpp/src/Ice/EndpointI.h +++ b/cpp/src/Ice/EndpointI.h @@ -11,6 +11,8 @@ #define ICE_ENDPOINT_I_H #include <IceUtil/Shared.h> +#include <IceUtil/Thread.h> +#include <IceUtil/Monitor.h> #include <Ice/Endpoint.h> #include <Ice/EndpointIF.h> #include <Ice/InstanceF.h> @@ -18,11 +20,30 @@ #include <Ice/ConnectorF.h> #include <Ice/AcceptorF.h> +#ifdef _WIN32 +# include <winsock2.h> +#else +# include <netinet/in.h> // For struct sockaddr_in +#endif + +#include <deque> + namespace IceInternal { class BasicStream; +class ICE_API EndpointI_connectors : public virtual IceUtil::Shared +{ +public: + + virtual ~EndpointI_connectors() { } + + virtual void connectors(const std::vector<ConnectorPtr>&) = 0; + virtual void exception(const Ice::LocalException&) = 0; +}; +typedef IceUtil::Handle<EndpointI_connectors> EndpointI_connectorsPtr; + class ICE_API EndpointI : public Ice::Endpoint { public: @@ -97,6 +118,7 @@ public: // connector is available. // virtual std::vector<ConnectorPtr> connectors() const = 0; + virtual void connectors_async(const EndpointI_connectorsPtr&) const = 0; // // Return an acceptor for this endpoint, or null if no acceptors @@ -114,9 +136,9 @@ public: virtual std::vector<EndpointIPtr> expand() const = 0; // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - virtual bool equivalent(const ConnectorPtr&) const = 0; + virtual bool equivalent(const EndpointIPtr&) const = 0; // // Compare endpoints for sorting purposes. @@ -127,6 +149,9 @@ public: private: + virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const; + friend class EndpointHostResolver; + #if defined(__SUNPRO_CC) || defined(__HP_aCC) // // COMPILERFIX: prevent the compiler from emitting a warning about @@ -137,6 +162,32 @@ private: #endif }; +class ICE_API EndpointHostResolver : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + EndpointHostResolver(const InstancePtr&); + + void resolve(const std::string&, int, const EndpointIPtr&, const EndpointI_connectorsPtr&); + void destroy(); + + virtual void run(); + +private: + + struct ResolveEntry + { + std::string host; + int port; + EndpointIPtr endpoint; + EndpointI_connectorsPtr callback; + }; + + const InstancePtr _instance; + bool _destroyed; + std::deque<ResolveEntry> _queue; +}; + } #endif diff --git a/cpp/src/Ice/EventHandler.cpp b/cpp/src/Ice/EventHandler.cpp index 6a92e51788d..c14576855b8 100644 --- a/cpp/src/Ice/EventHandler.cpp +++ b/cpp/src/Ice/EventHandler.cpp @@ -15,6 +15,7 @@ using namespace Ice; using namespace IceInternal; IceUtil::Shared* IceInternal::upCast(EventHandler* p) { return p; } +IceUtil::Shared* IceInternal::upCast(ThreadPoolWorkItem* p) { return p; } InstancePtr IceInternal::EventHandler::instance() const diff --git a/cpp/src/Ice/EventHandler.h b/cpp/src/Ice/EventHandler.h index 03c34bc3fe0..88111ce545b 100644 --- a/cpp/src/Ice/EventHandler.h +++ b/cpp/src/Ice/EventHandler.h @@ -46,7 +46,7 @@ public: // Read data via the event handler. May only be called if // readable() returns true. // - virtual void read(BasicStream&) = 0; + virtual bool read(BasicStream&) = 0; // // A complete message has been received. @@ -77,15 +77,21 @@ protected: const InstancePtr _instance; -private: - // - // The _stream data member is for use by ThreadPool only + // The _stream data member is for use by ThreadPool or by the + // connection for connection validation only. // BasicStream _stream; friend class ThreadPool; }; +class ThreadPoolWorkItem : virtual public IceUtil::Shared +{ +public: + + virtual void execute(const ThreadPoolPtr&) = 0; +}; + } #endif diff --git a/cpp/src/Ice/EventHandlerF.h b/cpp/src/Ice/EventHandlerF.h index 576fbaac575..d15b1ff96da 100644 --- a/cpp/src/Ice/EventHandlerF.h +++ b/cpp/src/Ice/EventHandlerF.h @@ -21,6 +21,10 @@ class EventHandler; IceUtil::Shared* upCast(EventHandler*); typedef Handle<EventHandler> EventHandlerPtr; +class ThreadPoolWorkItem; +IceUtil::Shared* upCast(ThreadPoolWorkItem*); +typedef Handle<ThreadPoolWorkItem> ThreadPoolWorkItemPtr; + } #endif diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index ef5a4b2f167..9349990bb63 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -18,6 +18,7 @@ #include <Ice/ReferenceFactory.h> #include <Ice/ProxyFactory.h> #include <Ice/ThreadPool.h> +#include <Ice/SelectorThread.h> #include <Ice/ConnectionFactory.h> #include <Ice/ConnectionMonitor.h> #include <Ice/ObjectFactoryManager.h> @@ -235,6 +236,42 @@ IceInternal::Instance::serverThreadPool() return _serverThreadPool; } +SelectorThreadPtr +IceInternal::Instance::selectorThread() +{ + IceUtil::RecMutex::Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(!_selectorThread) // Lazy initialization. + { + _selectorThread = new SelectorThread(this); + } + + return _selectorThread; +} + +EndpointHostResolverPtr +IceInternal::Instance::endpointHostResolver() +{ + IceUtil::RecMutex::Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + if(!_endpointHostResolver) // Lazy initialization. + { + _endpointHostResolver = new EndpointHostResolver(this); + } + + return _endpointHostResolver; +} + IceUtil::TimerPtr IceInternal::Instance::timer() { @@ -914,6 +951,8 @@ IceInternal::Instance::~Instance() assert(!_objectAdapterFactory); assert(!_clientThreadPool); assert(!_serverThreadPool); + assert(!_selectorThread); + assert(!_endpointHostResolver); assert(!_timer); assert(!_routerManager); assert(!_locatorManager); @@ -1077,6 +1116,8 @@ IceInternal::Instance::destroy() ThreadPoolPtr serverThreadPool; ThreadPoolPtr clientThreadPool; + SelectorThreadPtr selectorThread; + EndpointHostResolverPtr endpointHostResolver; { IceUtil::RecMutex::Lock sync(*this); @@ -1102,6 +1143,18 @@ IceInternal::Instance::destroy() std::swap(_clientThreadPool, clientThreadPool); } + if(_selectorThread) + { + _selectorThread->destroy(); + std::swap(selectorThread, _selectorThread); + } + + if(_endpointHostResolver) + { + _endpointHostResolver->destroy(); + std::swap(endpointHostResolver, _endpointHostResolver); + } + if(_timer) { _timer->destroy(); @@ -1169,6 +1222,14 @@ IceInternal::Instance::destroy() { serverThreadPool->joinWithAllThreads(); } + if(selectorThread) + { + selectorThread->joinWithThread(); + } + if(endpointHostResolver) + { + endpointHostResolver->getThreadControl().join(); + } if(_initData.properties->getPropertyAsInt("Ice.Warn.UnusedProperties") > 0) { diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h index f3aa41fb58e..cbf6ad36ecf 100644 --- a/cpp/src/Ice/Instance.h +++ b/cpp/src/Ice/Instance.h @@ -24,6 +24,7 @@ #include <Ice/ReferenceFactoryF.h> #include <Ice/ProxyFactoryF.h> #include <Ice/ThreadPoolF.h> +#include <Ice/SelectorThreadF.h> #include <Ice/ConnectionFactoryF.h> #include <Ice/ConnectionMonitorF.h> #include <Ice/ObjectFactoryManagerF.h> @@ -67,6 +68,8 @@ public: ObjectAdapterFactoryPtr objectAdapterFactory() const; ThreadPoolPtr clientThreadPool(); ThreadPoolPtr serverThreadPool(); + SelectorThreadPtr selectorThread(); + EndpointHostResolverPtr endpointHostResolver(); IceUtil::TimerPtr timer(); bool threadPerConnection() const; size_t threadPerConnectionStackSize() const; @@ -122,6 +125,8 @@ private: ObjectAdapterFactoryPtr _objectAdapterFactory; ThreadPoolPtr _clientThreadPool; ThreadPoolPtr _serverThreadPool; + SelectorThreadPtr _selectorThread; + EndpointHostResolverPtr _endpointHostResolver; IceUtil::TimerPtr _timer; const bool _threadPerConnection; const size_t _threadPerConnectionStackSize; diff --git a/cpp/src/Ice/LocatorInfo.cpp b/cpp/src/Ice/LocatorInfo.cpp index 606d7557fdd..f14561fef20 100644 --- a/cpp/src/Ice/LocatorInfo.cpp +++ b/cpp/src/Ice/LocatorInfo.cpp @@ -375,92 +375,149 @@ IceInternal::LocatorInfo::getEndpoints(const IndirectReferencePtr& ref, int ttl, cached = objectCached || endpointsCached; } } - catch(const AdapterNotFoundException&) + catch(const Ice::Exception& ex) { - if(ref->getInstance()->traceLevels()->location >= 1) - { - Trace out(ref->getInstance()->initializationData().logger, - ref->getInstance()->traceLevels()->locationCat); - out << "adapter not found" << "\n"; - out << "adapter = " << ref->getAdapterId(); - } - - NotRegisteredException ex(__FILE__, __LINE__); - ex.kindOfObject = "object adapter"; - ex.id = ref->getAdapterId(); - throw ex; + getEndpointsException(ref, ex); } - catch(const ObjectNotFoundException&) - { - if(ref->getInstance()->traceLevels()->location >= 1) - { - Trace out(ref->getInstance()->initializationData().logger, - ref->getInstance()->traceLevels()->locationCat); - out << "object not found" << "\n"; - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); - } - NotRegisteredException ex(__FILE__, __LINE__); - ex.kindOfObject = "object"; - ex.id = ref->getInstance()->identityToString(ref->getIdentity()); - throw ex; - } - catch(const NotRegisteredException&) + if(ref->getInstance()->traceLevels()->location >= 1) { - throw; + getEndpointsTrace(ref, endpoints, cached); } - catch(const LocalException& ex) + + return endpoints; +} + +void +IceInternal::LocatorInfo::getEndpoints(const IndirectReferencePtr& ref, int ttl, + const GetEndpointsCallbackPtr& callback) +{ + string adapterId = ref->getAdapterId(); + Ice::Identity identity = ref->getIdentity(); + InstancePtr instance = ref->getInstance(); + if(!adapterId.empty()) { - if(ref->getInstance()->traceLevels()->location >= 1) + vector<EndpointIPtr> endpoints; + if(!_table->getAdapterEndpoints(adapterId, ttl, endpoints)) { - Trace out(ref->getInstance()->initializationData().logger, - ref->getInstance()->traceLevels()->locationCat); - out << "couldn't contact the locator to retrieve adapter endpoints\n"; - if(ref->getAdapterId().empty()) + if(instance->traceLevels()->location >= 1) { - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()) << "\n"; + Trace out(instance->initializationData().logger, instance->traceLevels()->locationCat); + out << "searching for adapter by id" << "\nadapter = " << adapterId; } - else + + class Callback : public AMI_Locator_findAdapterById { - out << "adapter = " << ref->getAdapterId() << "\n"; + public: + + virtual void + ice_response(const Ice::ObjectPrx& object) + { + vector<EndpointIPtr> endpoints; + if(object) + { + endpoints = object->__reference()->getEndpoints(); + if(!endpoints.empty()) + { + _table->addAdapterEndpoints(_reference->getAdapterId(), endpoints); + } + } + + if(_reference->getInstance()->traceLevels()->location >= 1) + { + _locatorInfo->getEndpointsTrace(_reference, endpoints, false); + } + + _callback->setEndpoints(endpoints, false); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + _locatorInfo->getEndpointsException(_reference, ex, _callback); + } + + Callback(const LocatorInfoPtr& locatorInfo, const LocatorTablePtr& table, + const IndirectReferencePtr& reference, const GetEndpointsCallbackPtr& callback) : + _locatorInfo(locatorInfo), _table(table), _reference(reference), _callback(callback) + { + } + + private: + + const LocatorInfoPtr _locatorInfo; + const LocatorTablePtr _table; + const IndirectReferencePtr _reference; + const GetEndpointsCallbackPtr _callback; + }; + + // + // Search the adapter in the location service if we didn't + // find it in the cache. + // + _locator->findAdapterById_async(new Callback(this, _table, ref, callback), adapterId); + return; + } + else + { + if(instance->traceLevels()->location >= 1) + { + getEndpointsTrace(ref, endpoints, true); } - out << "reason = " << ex; + callback->setEndpoints(endpoints, true); + return; } - throw; } - - - if(ref->getInstance()->traceLevels()->location >= 1) + else { - if(!endpoints.empty()) + Ice::ObjectPrx object; + if(!_table->getProxy(identity, ttl, object)) { - if(cached) + if(instance->traceLevels()->location >= 1) { - trace("found endpoints in locator table", ref, endpoints); + Trace out(instance->initializationData().logger, instance->traceLevels()->locationCat); + out << "searching for object by id" << "\nobject = " << instance->identityToString(ref->getIdentity()); } - else + + class Callback : public Ice::AMI_Locator_findObjectById { - trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); - } + public: + + virtual void + ice_response(const Ice::ObjectPrx& object) + { + _locatorInfo->getWellKnownObjectEndpoints(_reference, object, _ttl, false, _callback); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + _locatorInfo->getEndpointsException(_reference, ex, _callback); + } + + Callback(const LocatorInfoPtr& locatorInfo, const IndirectReferencePtr& reference, int ttl, + const GetEndpointsCallbackPtr& callback) : + _locatorInfo(locatorInfo), _reference(reference), _ttl(ttl), _callback(callback) + { + } + + private: + + const LocatorInfoPtr _locatorInfo; + const IndirectReferencePtr _reference; + int _ttl; + const GetEndpointsCallbackPtr _callback; + }; + + _locator->findObjectById_async(new Callback(this, ref, ttl, callback), identity); + return; } else { - Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); - out << "no endpoints configured for "; - if(ref->getAdapterId().empty()) - { - out << "object\n"; - out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); - } - else - { - out << "adapter\n"; - out << "adapter = " << ref->getAdapterId(); - } + getWellKnownObjectEndpoints(ref, object, ttl, true, callback); + return; } } - - return endpoints; } void @@ -548,3 +605,195 @@ IceInternal::LocatorInfo::trace(const string& msg, Ice::constMemFun(&Endpoint::toString)); out << "endpoints = " << o.str(); } + +void +IceInternal::LocatorInfo::getEndpointsException(const IndirectReferencePtr& ref, const Ice::Exception& exc) +{ + try + { + exc.ice_throw(); + } + catch(const AdapterNotFoundException&) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, + ref->getInstance()->traceLevels()->locationCat); + out << "adapter not found" << "\n"; + out << "adapter = " << ref->getAdapterId(); + } + + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object adapter"; + ex.id = ref->getAdapterId(); + throw ex; + } + catch(const ObjectNotFoundException&) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, + ref->getInstance()->traceLevels()->locationCat); + out << "object not found" << "\n"; + out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); + } + + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object"; + ex.id = ref->getInstance()->identityToString(ref->getIdentity()); + throw ex; + } + catch(const NotRegisteredException&) + { + throw; + } + catch(const LocalException& ex) + { + if(ref->getInstance()->traceLevels()->location >= 1) + { + Trace out(ref->getInstance()->initializationData().logger, + ref->getInstance()->traceLevels()->locationCat); + out << "couldn't contact the locator to retrieve adapter endpoints\n"; + if(ref->getAdapterId().empty()) + { + out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()) << "\n"; + } + else + { + out << "adapter = " << ref->getAdapterId() << "\n"; + } + out << "reason = " << ex; + } + throw; + } +} + +void +IceInternal::LocatorInfo::getEndpointsException(const IndirectReferencePtr& ref, const Ice::Exception& exc, + const GetEndpointsCallbackPtr& callback) +{ + try + { + getEndpointsException(ref, exc); + } + catch(const Ice::LocalException& ex) + { + callback->setException(ex); + } +} + +void +IceInternal::LocatorInfo::getWellKnownObjectEndpoints(const IndirectReferencePtr& ref, + const Ice::ObjectPrx& object, + int ttl, + bool objectCached, + const GetEndpointsCallbackPtr& callback) +{ + class Callback : public GetEndpointsCallback + { + public: + + virtual void + setEndpoints(const vector<EndpointIPtr>& endpoints, bool endpointsCached) + { + if(!_objectCached && !endpoints.empty()) + { + _table->addProxy(_reference->getIdentity(), _object); + } + + if(_reference->getInstance()->traceLevels()->location >= 1) + { + _locatorInfo->getEndpointsTrace(_reference, endpoints, _objectCached || endpointsCached); + } + + _callback->setEndpoints(endpoints, _objectCached || endpointsCached); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + Callback(const LocatorInfoPtr& locatorInfo, const LocatorTablePtr& table, + const IndirectReferencePtr& reference, const Ice::ObjectPrx& object, + bool objectCached, const GetEndpointsCallbackPtr& callback) : + _locatorInfo(locatorInfo), _table(table), _reference(reference), _object(object), + _objectCached(objectCached), _callback(callback) + { + } + + private: + + const LocatorInfoPtr _locatorInfo; + const LocatorTablePtr _table; + const IndirectReferencePtr _reference; + const Ice::ObjectPrx _object; + const bool _objectCached; + const GetEndpointsCallbackPtr _callback; + }; + + vector<EndpointIPtr> endpoints; + if(object) + { + DirectReferencePtr odr = DirectReferencePtr::dynamicCast(object->__reference()); + if(odr) + { + endpoints = odr->getEndpoints(); + } + else + { + IndirectReferencePtr oir = IndirectReferencePtr::dynamicCast(object->__reference()); + assert(oir); + if(!oir->getAdapterId().empty()) + { + getEndpoints(oir, ttl, new Callback(this, _table, ref, object, objectCached, callback)); + return; + } + } + } + + if(!objectCached && !endpoints.empty()) + { + _table->addProxy(ref->getIdentity(), object); + } + + if(ref->getInstance()->traceLevels()->location >= 1) + { + getEndpointsTrace(ref, endpoints, objectCached); + } + + callback->setEndpoints(endpoints, objectCached); +} + +void +IceInternal::LocatorInfo::getEndpointsTrace(const IndirectReferencePtr& ref, const vector<EndpointIPtr>& endpoints, + bool cached) +{ + if(!endpoints.empty()) + { + if(cached) + { + trace("found endpoints in locator table", ref, endpoints); + } + else + { + trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + } + } + else + { + Trace out(ref->getInstance()->initializationData().logger, ref->getInstance()->traceLevels()->locationCat); + out << "no endpoints configured for "; + if(ref->getAdapterId().empty()) + { + out << "object\n"; + out << "object = " << ref->getInstance()->identityToString(ref->getIdentity()); + } + else + { + out << "adapter\n"; + out << "adapter = " << ref->getAdapterId(); + } + } +} diff --git a/cpp/src/Ice/LocatorInfo.h b/cpp/src/Ice/LocatorInfo.h index 4811030d97c..f0a1032fa05 100644 --- a/cpp/src/Ice/LocatorInfo.h +++ b/cpp/src/Ice/LocatorInfo.h @@ -71,6 +71,15 @@ class LocatorInfo : public IceUtil::Shared, public IceUtil::Mutex { public: + class GetEndpointsCallback : virtual public IceUtil::Shared + { + public: + + virtual void setEndpoints(const std::vector<EndpointIPtr>&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<GetEndpointsCallback> GetEndpointsCallbackPtr; + LocatorInfo(const Ice::LocatorPrx&, const LocatorTablePtr&); void destroy(); @@ -83,6 +92,7 @@ public: Ice::LocatorRegistryPrx getLocatorRegistry(); std::vector<EndpointIPtr> getEndpoints(const IndirectReferencePtr&, int, bool&); + void getEndpoints(const IndirectReferencePtr&, int, const GetEndpointsCallbackPtr&); void clearCache(const IndirectReferencePtr&); void clearObjectCache(const IndirectReferencePtr&); @@ -90,6 +100,12 @@ private: void trace(const std::string&, const IndirectReferencePtr&, const std::vector<EndpointIPtr>&); + void getEndpointsException(const IndirectReferencePtr&, const Ice::Exception&); + void getWellKnownObjectEndpoints(const IndirectReferencePtr&, const Ice::ObjectPrx&, int, bool, + const GetEndpointsCallbackPtr&); + void getEndpointsException(const IndirectReferencePtr&, const Ice::Exception&, const GetEndpointsCallbackPtr&); + void getEndpointsTrace(const IndirectReferencePtr&, const std::vector<EndpointIPtr>&, bool); + const Ice::LocatorPrx _locator; Ice::LocatorRegistryPrx _locatorRegistry; const LocatorTablePtr _table; diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile index ebecec755eb..2c7c06d5238 100644 --- a/cpp/src/Ice/Makefile +++ b/cpp/src/Ice/Makefile @@ -22,10 +22,12 @@ OBJS = Acceptor.o \ BuiltinSequences.o \ CommunicatorI.o \ Communicator.o \ + ConnectRequestHandler.o \ ConnectionFactory.o \ ConnectionI.o \ ConnectionMonitor.o \ Connection.o \ + ConnectionRequestHandler.o \ Connector.o \ Current.o \ DefaultsAndOverrides.o \ @@ -78,8 +80,11 @@ OBJS = Acceptor.o \ Proxy.o \ ReferenceFactory.o \ Reference.o \ + RequestHandler.o \ RouterInfo.o \ Router.o \ + Selector.o \ + SelectorThread.o \ ServantLocator.o \ ServantManager.o \ Service.o \ diff --git a/cpp/src/Ice/Makefile.mak b/cpp/src/Ice/Makefile.mak index 80c69167223..6b4d6ee0318 100644 --- a/cpp/src/Ice/Makefile.mak +++ b/cpp/src/Ice/Makefile.mak @@ -21,11 +21,13 @@ OBJS = Acceptor.obj \ BuiltinSequences.obj \ CommunicatorI.obj \ Communicator.obj \ + ConnectRequestHandler.obj \ ConnectionFactory.obj \ ConnectionI.obj \ ConnectionMonitor.obj \ Connection.obj \ Connector.obj \ + ConnectionRequestHandler.obj \ Current.obj \ DefaultsAndOverrides.obj \ Direct.obj \ @@ -79,8 +81,11 @@ OBJS = Acceptor.obj \ Proxy.obj \ ReferenceFactory.obj \ Reference.obj \ + RequestHandler.obj \ RouterInfo.obj \ Router.obj \ + Selector.obj \ + SelectorThread.obj \ ServantLocator.obj \ ServantManager.obj \ Service.obj \ diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 0ee86c6472d..1fb9491e479 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -190,6 +190,8 @@ IceInternal::notConnected() { #ifdef _WIN32 return WSAGetLastError() == WSAENOTCONN; +#elif defined(__APPLE__) || defined(__FreeBSD__) + return errno == ENOTCONN || errno == EINVAL; #else return errno == ENOTCONN; #endif @@ -293,7 +295,7 @@ IceInternal::shutdownSocketWrite(SOCKET fd) { return; } -#elif defined(__APPLE__) +#elif defined(__APPLE__) || defined(__FreeBSD__) if(errno == ENOTCONN || errno == EINVAL) { return; @@ -329,7 +331,7 @@ IceInternal::shutdownSocketReadWrite(SOCKET fd) { return; } -#elif defined(__APPLE__) +#elif defined(__APPLE__) || defined(__FreeBSD__) if(errno == ENOTCONN || errno == EINVAL) { return; @@ -568,44 +570,9 @@ repeatListen: } } -void +bool IceInternal::doConnect(SOCKET fd, struct sockaddr_in& addr, int timeout) { -#ifdef _WIN32 - // - // Set larger send buffer size to avoid performance problems on - // WIN32. - // - setSendBufferSize(fd, 64 * 1024); - - // - // Under WinCE its not possible to find out the connection failure - // reason with SO_ERROR, so its necessary to use the WSAEVENT - // mechanism. We use the same mechanism for any Winsock platform. - // - WSAEVENT event = WSACreateEvent(); - if(event == 0) - { - closeSocketNoThrow(fd); - - SocketException ex(__FILE__, __LINE__); - ex.error = WSAGetLastError(); - throw ex; - } - - if(WSAEventSelect(fd, event, FD_CONNECT) == SOCKET_ERROR) - { - int error = WSAGetLastError(); - - WSACloseEvent(event); - closeSocketNoThrow(fd); - - SocketException ex(__FILE__, __LINE__); - ex.error = error; - throw ex; - } -#endif - repeatConnect: if(::connect(fd, reinterpret_cast<struct sockaddr*>(&addr), int(sizeof(addr))) == SOCKET_ERROR) { @@ -616,125 +583,141 @@ repeatConnect: if(connectInProgress()) { - int val; -#ifdef _WIN32 - WSAEVENT events[1]; - events[0] = event; - long tout = (timeout >= 0) ? timeout : WSA_INFINITE; - DWORD rc = WSAWaitForMultipleEvents(1, events, FALSE, tout, FALSE); - if(rc == WSA_WAIT_FAILED) + if(timeout == 0) { - int error = WSAGetLastError(); - - WSACloseEvent(event); - closeSocketNoThrow(fd); - - SocketException ex(__FILE__, __LINE__); - ex.error = error; - throw ex; + return false; } - if(rc == WSA_WAIT_TIMEOUT) + try { - WSACloseEvent(event); - closeSocketNoThrow(fd); - - assert(timeout >= 0); - throw ConnectTimeoutException(__FILE__, __LINE__); + doFinishConnect(fd, timeout); } - assert(rc == WSA_WAIT_EVENT_0); - - WSANETWORKEVENTS nevents; - if(WSAEnumNetworkEvents(fd, event, &nevents) == SOCKET_ERROR) + catch(const Ice::LocalException&) { - int error = WSAGetLastError(); - WSACloseEvent(event); closeSocketNoThrow(fd); - - SocketException ex(__FILE__, __LINE__); - ex.error = error; - throw ex; + throw; } + return true; + } + + closeSocketNoThrow(fd); + if(connectionRefused()) + { + ConnectionRefusedException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + else if(connectFailed()) + { + ConnectFailedException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + else + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + } - // - // Now we close the event, because we're finished and - // this code be repeated. - // - WSACloseEvent(event); +#if defined(__linux) + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // + struct sockaddr_in localAddr; + fdToLocalAddress(fd, localAddr); + if(compareAddress(addr, localAddr) == 0) + { + ConnectionRefusedException ex(__FILE__, __LINE__); + ex.error = 0; // No appropriate errno + throw ex; + } +#endif + return true; +} - assert(nevents.lNetworkEvents & FD_CONNECT); - val = nevents.iErrorCode[FD_CONNECT_BIT]; +void +IceInternal::doFinishConnect(SOCKET fd, int timeout) +{ + // + // Note: we don't close the socket if there's an exception. It's the responsability + // of the caller to do so. + // + + if(timeout != 0) + { + repeatSelect: +#ifdef _WIN32 + fd_set wFdSet; + fd_set eFdSet; + FD_ZERO(&wFdSet); + FD_ZERO(&eFdSet); + FD_SET(fd, &wFdSet); + FD_SET(fd, &eFdSet); + + int ret; + if(timeout >= 0) + { + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; + ret = ::select(static_cast<int>(fd + 1), 0, &wFdSet, &eFdSet, &tv); + } + else + { + ret = ::select(static_cast<int>(fd + 1), 0, &wFdSet, &eFdSet, 0); + } #else - repeatPoll: - struct pollfd pollFd[1]; - pollFd[0].fd = fd; - pollFd[0].events = POLLOUT; - int ret = ::poll(pollFd, 1, timeout); - if(ret == 0) + struct pollfd pollFd[1]; + pollFd[0].fd = fd; + pollFd[0].events = POLLOUT; + int ret = ::poll(pollFd, 1, timeout); +#endif + if(ret == 0) + { + throw ConnectTimeoutException(__FILE__, __LINE__); + } + else if(ret == SOCKET_ERROR) + { + if(interrupted()) { - closeSocketNoThrow(fd); - throw ConnectTimeoutException(__FILE__, __LINE__); + goto repeatSelect; } - else if(ret == SOCKET_ERROR) - { - if(interrupted()) - { - goto repeatPoll; - } - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - - // - // Strange windows bug: The following call to Sleep() is - // necessary, otherwise no error is reported through - // getsockopt. - // - //Sleep(0); - socklen_t len = static_cast<socklen_t>(sizeof(int)); - if(getsockopt(fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&val), &len) == SOCKET_ERROR) - { - closeSocketNoThrow(fd); - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + } + + int val; + + // + // Strange windows bug: The following call to Sleep() is + // necessary, otherwise no error is reported through + // getsockopt. + // +#ifdef _WIN32 + Sleep(0); #endif + socklen_t len = static_cast<socklen_t>(sizeof(int)); + if(getsockopt(fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&val), &len) == SOCKET_ERROR) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } - if(val > 0) - { - closeSocketNoThrow(fd); + if(val > 0) + { #ifdef _WIN32 - WSASetLastError(val); + WSASetLastError(val); #else - errno = val; + errno = val; #endif - if(connectionRefused()) - { - ConnectionRefusedException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else if(connectFailed()) - { - ConnectFailedException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - } - - return; - } - - closeSocketNoThrow(fd); if(connectionRefused()) { ConnectionRefusedException ex(__FILE__, __LINE__); @@ -754,6 +737,23 @@ repeatConnect: throw ex; } } + +#if defined(__linux) + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // + struct sockaddr_in localAddr; + fdToLocalAddress(fd, localAddr); + struct sockaddr_in remoteAddr; + if(fdToRemoteAddress(fd, remoteAddr) && compareAddress(remoteAddr, localAddr) == 0) + { + ConnectionRefusedException ex(__FILE__, __LINE__); + ex.error = 0; // No appropriate errno + throw ex; + } +#endif } SOCKET @@ -826,15 +826,6 @@ repeatAccept: setTcpNoDelay(ret); setKeepAlive(ret); - -#ifdef _WIN32 - // - // Set larger send buffer size to avoid performance problems on - // WIN32. - // - setSendBufferSize(ret, 64 * 1024); -#endif - return ret; } @@ -848,41 +839,44 @@ IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr) if(addr.sin_addr.s_addr == INADDR_NONE) { -#ifdef _WIN32 - // - // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. + // We now use getaddrinfo() on Windows. // +// #ifdef _WIN32 + +// // +// // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. +// // - // - // gethostbyname() is thread safe on Windows, with a separate hostent per thread - // - struct hostent* entry; - int retry = 5; - do - { - entry = gethostbyname(host.c_str()); - } - while(entry == 0 && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0); +// // +// // gethostbyname() is thread safe on Windows, with a separate hostent per thread +// // +// struct hostent* entry; +// int retry = 5; +// do +// { +// entry = gethostbyname(host.c_str()); +// } +// while(entry == 0 && WSAGetLastError() == WSATRY_AGAIN && --retry >= 0); - if(entry == 0) - { - DNSException ex(__FILE__, __LINE__); +// if(entry == 0) +// { +// DNSException ex(__FILE__, __LINE__); - ex.error = WSAGetLastError(); - ex.host = host; - throw ex; - } - memcpy(&addr.sin_addr, entry->h_addr, entry->h_length); +// ex.error = WSAGetLastError(); +// ex.host = host; +// throw ex; +// } +// memcpy(&addr.sin_addr, entry->h_addr, entry->h_length); -#else +// #else struct addrinfo* info = 0; int retry = 5; struct addrinfo hints = { 0 }; hints.ai_family = PF_INET; - + int rs = 0; do { @@ -903,8 +897,6 @@ IceInternal::getAddress(const string& host, int port, struct sockaddr_in& addr) addr.sin_addr.s_addr = sin->sin_addr.s_addr; freeaddrinfo(info); - -#endif } } @@ -1346,7 +1338,7 @@ IceInternal::addrToString(const struct sockaddr_in& addr) } vector<struct sockaddr_in> -IceInternal::getAddresses(const string& host, int port) +IceInternal::getAddresses(const string& host, int port, bool blocking) { vector<struct sockaddr_in> result; @@ -1367,47 +1359,54 @@ IceInternal::getAddresses(const string& host, int port) addr.sin_family = AF_INET; addr.sin_port = htons(port); -#ifdef _WIN32 - - // - // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. - // - // - // gethostbyname() is thread safe on Windows, with a separate hostent per thread + // We now use getaddrinfo() on Windows. // - struct hostent* entry = 0; - int retry = 5; +// #ifdef _WIN32 - do - { - entry = gethostbyname(host.c_str()); - } - while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0); +// // +// // Windows XP has getaddrinfo(), but we don't want to require XP to run Ice. +// // + +// // +// // gethostbyname() is thread safe on Windows, with a separate hostent per thread +// // +// struct hostent* entry = 0; +// int retry = 5; + +// do +// { +// entry = gethostbyname(host.c_str()); +// } +// while(entry == 0 && h_errno == TRY_AGAIN && --retry >= 0); - if(entry == 0) - { - DNSException ex(__FILE__, __LINE__); - ex.error = h_errno; - ex.host = host; - throw ex; - } - - char** p = entry->h_addr_list; - while(*p) - { - memcpy(&addr.sin_addr, *p, entry->h_length); - result.push_back(addr); - p++; - } - -#else +// if(entry == 0) +// { +// DNSException ex(__FILE__, __LINE__); +// ex.error = h_errno; +// ex.host = host; +// throw ex; +// } + +// char** p = entry->h_addr_list; +// while(*p) +// { +// memcpy(&addr.sin_addr, *p, entry->h_length); +// result.push_back(addr); +// p++; +// } + +// #else struct addrinfo* info = 0; int retry = 5; struct addrinfo hints = { 0 }; hints.ai_family = PF_INET; + if(!blocking) + { + hints.ai_flags = AI_NUMERICHOST; + } int rs = 0; do @@ -1451,7 +1450,7 @@ IceInternal::getAddresses(const string& host, int port) freeaddrinfo(info); -#endif +//#endif } return result; diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h index 178e08a6e1a..5936a2cd2c0 100644 --- a/cpp/src/Ice/Network.h +++ b/cpp/src/Ice/Network.h @@ -96,7 +96,8 @@ ICE_API void setReuseAddress(SOCKET, bool); ICE_API void doBind(SOCKET, struct sockaddr_in&); ICE_API void doListen(SOCKET, int); -ICE_API void doConnect(SOCKET, struct sockaddr_in&, int); +ICE_API bool doConnect(SOCKET, struct sockaddr_in&, int); +ICE_API void doFinishConnect(SOCKET, int); ICE_API SOCKET doAccept(SOCKET, int); ICE_API void getAddress(const std::string&, int, struct sockaddr_in&); @@ -114,7 +115,7 @@ ICE_API void fdToLocalAddress(SOCKET, struct sockaddr_in&); ICE_API bool fdToRemoteAddress(SOCKET, struct sockaddr_in&); ICE_API std::string addrToString(const struct sockaddr_in&); -ICE_API std::vector<struct sockaddr_in> getAddresses(const std::string&, int); +ICE_API std::vector<struct sockaddr_in> getAddresses(const std::string&, int, bool = true); ICE_API std::vector<std::string> getLocalHosts(); ICE_API void setTcpBufSize(SOCKET, const Ice::PropertiesPtr&, const Ice::LoggerPtr&); ICE_API int getSocketErrno(); diff --git a/cpp/src/Ice/ObjectAdapterFactory.cpp b/cpp/src/Ice/ObjectAdapterFactory.cpp index a6009d658e3..5d7f1d131f9 100644 --- a/cpp/src/Ice/ObjectAdapterFactory.cpp +++ b/cpp/src/Ice/ObjectAdapterFactory.cpp @@ -79,7 +79,7 @@ IceInternal::ObjectAdapterFactory::waitForShutdown() _waitForShutdown = true; adapters = _adapters; } - + // // Now we wait for deactivation of each object adapter. // diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index 9d7cf4c7d5c..ccd571147ec 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -256,7 +256,6 @@ Ice::ObjectAdapterI::waitForDeactivate() { IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); - if(_destroyed) { return; @@ -365,7 +364,6 @@ Ice::ObjectAdapterI::destroy() _routerInfo = 0; _publishedEndpoints.clear(); _locatorInfo = 0; - _connectors.clear(); objectAdapterFactory = _objectAdapterFactory; _objectAdapterFactory = 0; @@ -583,14 +581,6 @@ Ice::ObjectAdapterI::refreshPublishedEndpoints() oldPublishedEndpoints = _publishedEndpoints; _publishedEndpoints = parsePublishedEndpoints(); - _connectors.clear(); - vector<IncomingConnectionFactoryPtr>::const_iterator p; - for(p = _incomingConnectionFactories.begin(); p != _incomingConnectionFactories.end(); ++p) - { - vector<ConnectorPtr> cons = (*p)->endpoint()->connectors(); - _connectors.insert(_connectors.end(), cons.begin(), cons.end()); - } - locatorInfo = _locatorInfo; if(!_noConfig) { @@ -671,10 +661,18 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrx& proxy) const // for(p = endpoints.begin(); p != endpoints.end(); ++p) { - vector<ConnectorPtr>::const_iterator q; - for(q = _connectors.begin(); q != _connectors.end(); ++q) + vector<IncomingConnectionFactoryPtr>::const_iterator q; + for(q = _incomingConnectionFactories.begin(); q != _incomingConnectionFactories.end(); ++q) + { + if((*p)->equivalent((*q)->endpoint())) + { + return true; + } + } + vector<EndpointIPtr>::const_iterator r; + for(r = _publishedEndpoints.begin(); r != _publishedEndpoints.end(); ++r) { - if((*p)->equivalent(*q)) + if((*p)->equivalent(*r)) { return true; } @@ -944,9 +942,6 @@ Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const Communica { IncomingConnectionFactoryPtr factory = new IncomingConnectionFactory(instance, *p, this, _name); _incomingConnectionFactories.push_back(factory); - - vector<ConnectorPtr> cons = factory->endpoint()->connectors(); - _connectors.insert(_connectors.end(), cons.begin(), cons.end()); } if(endpoints.empty()) { diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp index 8eedeffe6a1..14fb41c7afd 100644 --- a/cpp/src/Ice/Outgoing.cpp +++ b/cpp/src/Ice/Outgoing.cpp @@ -9,6 +9,7 @@ #include <Ice/Outgoing.h> #include <Ice/Object.h> +#include <Ice/RequestHandler.h> #include <Ice/ConnectionI.h> #include <Ice/Reference.h> #include <Ice/Endpoint.h> @@ -78,16 +79,15 @@ IceInternal::LocalExceptionWrapper::retry() const return _retry; } -IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const string& operation, - OperationMode mode, const Context* context, bool compress) : - _connection(connection), - _reference(ref), +IceInternal::Outgoing::Outgoing(RequestHandler* handler, const string& operation, OperationMode mode, + const Context* context) : + _handler(handler), _state(StateUnsent), - _is(ref->getInstance().get()), - _os(ref->getInstance().get()), - _compress(compress) + _is(handler->getReference()->getInstance().get()), + _os(handler->getReference()->getInstance().get()), + _sent(false) { - switch(_reference->getMode()) + switch(_handler->getReference()->getMode()) { case Reference::ModeTwoway: case Reference::ModeOneway: @@ -100,25 +100,25 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s case Reference::ModeBatchOneway: case Reference::ModeBatchDatagram: { - _connection->prepareBatchRequest(&_os); + _handler->prepareBatchRequest(&_os); break; } } try { - _reference->getIdentity().__write(&_os); + _handler->getReference()->getIdentity().__write(&_os); // // For compatibility with the old FacetPath. // - if(_reference->getFacet().empty()) + if(_handler->getReference()->getFacet().empty()) { _os.write(static_cast<string*>(0), static_cast<string*>(0)); } else { - string facet = _reference->getFacet(); + string facet = _handler->getReference()->getFacet(); _os.write(&facet, &facet + 1); } @@ -138,11 +138,8 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s // // Implicit context // - const ImplicitContextIPtr& implicitContext = - _reference->getInstance()->getImplicitContext(); - - const Context& prxContext = _reference->getContext()->getValue(); - + const ImplicitContextIPtr& implicitContext = _handler->getReference()->getInstance()->getImplicitContext(); + const Context& prxContext = _handler->getReference()->getContext()->getValue(); if(implicitContext == 0) { __writeContext(&_os, prxContext); @@ -173,42 +170,33 @@ IceInternal::Outgoing::invoke() _os.endWriteEncaps(); - switch(_reference->getMode()) + switch(_handler->getReference()->getMode()) { case Reference::ModeTwoway: { - // - // We let all exceptions raised by sending directly - // propagate to the caller, because they can be retried - // without violating "at-most-once". In case of such - // exceptions, the connection object does not call back on - // this object, so we don't need to lock the mutex, keep - // track of state, or save exceptions. - // - _connection->sendRequest(&_os, this, _compress); - - // - // Wait until the request has completed, or until the - // request times out. - // + _state = StateInProgress; - bool timedOut = false; + Ice::ConnectionI* connection = _handler->sendRequest(this); + bool timedOut = false; + { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); // - // It's possible that the request has already - // completed, due to a regular response, or because of - // an exception. So we only change the state to "in - // progress" if it is still "unsent". + // If the request is being sent in the background we first wait for the + // sent notification. // - if(_state == StateUnsent) + while(_state != StateFailed && !_sent) { - _state = StateInProgress; + _monitor.wait(); } - - Int timeout = _connection->timeout(); + + // + // Wait until the request has completed, or until the request times out. + // + + Int timeout = connection->timeout(); while(_state == StateInProgress && !timedOut) { if(timeout >= 0) @@ -233,7 +221,7 @@ IceInternal::Outgoing::invoke() // Must be called outside the synchronization of this // object. // - _connection->exception(TimeoutException(__FILE__, __LINE__)); + connection->exception(TimeoutException(__FILE__, __LINE__)); // // We must wait until the exception set above has @@ -241,7 +229,6 @@ IceInternal::Outgoing::invoke() // { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); - while(_state == StateInProgress) { _monitor.wait(); @@ -262,7 +249,8 @@ IceInternal::Outgoing::invoke() // An ObjectNotExistException can always be retried as // well without violating "at-most-once". // - if(dynamic_cast<CloseConnectionException*>(_exception.get()) || + if(!_sent || + dynamic_cast<CloseConnectionException*>(_exception.get()) || dynamic_cast<ObjectNotExistException*>(_exception.get())) { _exception->ice_throw(); @@ -281,25 +269,35 @@ IceInternal::Outgoing::invoke() { return false; } - - assert(_state == StateOK); - break; + else + { + assert(_state == StateOK); + return true; + } } - + case Reference::ModeOneway: case Reference::ModeDatagram: { - // - // For oneway and datagram requests, the connection object - // never calls back on this object. Therefore we don't - // need to lock the mutex or save exceptions. We simply - // let all exceptions from sending propagate to the - // caller, because such exceptions can be retried without - // violating "at-most-once". - // _state = StateInProgress; - _connection->sendRequest(&_os, 0, _compress); - break; + if(_handler->sendRequest(this)) + { + // + // If the handler returns the connection, we must wait for the sent callback. + // + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + while(_state != StateFailed && !_sent) + { + _monitor.wait(); + } + + if(_exception.get()) + { + assert(!_sent); + _exception->ice_throw(); + } + } + return true; } case Reference::ModeBatchOneway: @@ -311,12 +309,13 @@ IceInternal::Outgoing::invoke() // apply. // _state = StateInProgress; - _connection->finishBatchRequest(&_os, _compress); - break; + _handler->finishBatchRequest(&_os); + return true; } } - return true; + assert(false); + return false; } void @@ -329,9 +328,10 @@ IceInternal::Outgoing::abort(const LocalException& ex) // notify the connection about that we give up ownership of the // batch stream. // - if(_reference->getMode() == Reference::ModeBatchOneway || _reference->getMode() == Reference::ModeBatchDatagram) + if(_handler->getReference()->getMode() == Reference::ModeBatchOneway || + _handler->getReference()->getMode() == Reference::ModeBatchDatagram) { - _connection->abortBatchRequest(); + _handler->abortBatchRequest(); // // If we abort a batch requests, we cannot retry, because not @@ -345,11 +345,30 @@ IceInternal::Outgoing::abort(const LocalException& ex) } void +IceInternal::Outgoing::sent(bool notify) +{ + if(notify) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _sent = true; + _monitor.notify(); + } + else + { + // + // No synchronization is necessary if called from sendRequest() because the connection + // send mutex is locked and no other threads can call on Outgoing until it's released. + // + _sent = true; + } +} + +void IceInternal::Outgoing::finished(BasicStream& is) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); - assert(_reference->getMode() == Reference::ModeTwoway); // Can only be called for twoways. + assert(_handler->getReference()->getMode() == Reference::ModeTwoway); // Can only be called for twoways. assert(_state <= StateInProgress); @@ -514,12 +533,68 @@ void IceInternal::Outgoing::finished(const LocalException& ex) { IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); - - assert(_reference->getMode() == Reference::ModeTwoway); // Can only be called for twoways. - assert(_state <= StateInProgress); - _state = StateLocalException; + _state = StateFailed; + _exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); + _monitor.notify(); +} + +IceInternal::BatchOutgoing::BatchOutgoing(RequestHandler* handler) : + _handler(handler), + _connection(0), + _sent(false), + _os(handler->getReference()->getInstance().get()) +{ +} + +IceInternal::BatchOutgoing::BatchOutgoing(ConnectionI* connection, Instance* instance) : + _handler(0), + _connection(connection), + _sent(false), + _os(instance) +{ +} + +void +IceInternal::BatchOutgoing::invoke() +{ + assert(_handler || _connection); + if(_handler && !_handler->flushBatchRequests(this) || _connection && !_connection->flushBatchRequests(this)) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + while(!_exception.get() && !_sent) + { + _monitor.wait(); + } + + if(_exception.get()) + { + assert(!_sent); + _exception->ice_throw(); + } + } +} + +void +IceInternal::BatchOutgoing::sent(bool notify) +{ + if(notify) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _sent = true; + _monitor.notify(); + } + else + { + _sent = true; + } +} + +void +IceInternal::BatchOutgoing::finished(const Ice::LocalException& ex) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); _exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); _monitor.notify(); } diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp index 40cb5336c23..4286cc1949c 100644 --- a/cpp/src/Ice/OutgoingAsync.cpp +++ b/cpp/src/Ice/OutgoingAsync.cpp @@ -10,6 +10,7 @@ #include <Ice/OutgoingAsync.h> #include <Ice/Object.h> #include <Ice/ConnectionI.h> +#include <Ice/RequestHandler.h> #include <Ice/Reference.h> #include <Ice/Instance.h> #include <Ice/LocalException.h> @@ -27,9 +28,12 @@ using namespace std; using namespace Ice; using namespace IceInternal; +IceUtil::Shared* IceInternal::upCast(OutgoingAsyncMessageCallback* p) { return p; } IceUtil::Shared* IceInternal::upCast(OutgoingAsync* p) { return p; } +IceUtil::Shared* IceInternal::upCast(BatchOutgoingAsync* p) { return p; } IceUtil::Shared* IceInternal::upCast(AMI_Object_ice_invoke* p) { return p; } IceUtil::Shared* IceInternal::upCast(AMI_Array_Object_ice_invoke* p) { return p; } +IceUtil::Shared* IceInternal::upCast(AMI_Object_ice_flushBatchRequests* p) { return p; } IceInternal::OutgoingAsync::OutgoingAsync() : __is(0), @@ -44,17 +48,52 @@ IceInternal::OutgoingAsync::~OutgoingAsync() } void +IceInternal::OutgoingAsync::__sent(Ice::ConnectionI* connection) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _sent = true; + + if(!_proxy->ice_isTwoway()) + { + cleanup(); // No response expected, we're done with the OutgoingAsync. + } + else if(_response) + { + _monitor.notifyAll(); // If the response was already received notify finished() which is waiting. + } + else if(connection->timeout() > 0) + { + assert(!_timerTaskConnection); + _timerTaskConnection = connection; + IceUtil::Time timeout = IceUtil::Time::milliSeconds(connection->timeout()); + _proxy->__reference()->getInstance()->timer()->schedule(this, timeout); + } +} + +void IceInternal::OutgoingAsync::__finished(BasicStream& is) { - IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(_monitor); + assert(_proxy->ice_isTwoway()); // Can only be called for twoways. Ice::Byte replyStatus; - try { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + assert(__os); + _response = true; + + if(_timerTaskConnection && _proxy->__reference()->getInstance()->timer()->cancel(this)) + { + _timerTaskConnection = 0; // Timer cancelled. + } + + while(!_sent || _timerTaskConnection) + { + _monitor.wait(); + } + __is->swap(is); __is->read(replyStatus); - switch(replyStatus) { @@ -190,43 +229,65 @@ IceInternal::OutgoingAsync::__finished(BasicStream& is) warning(); } + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); cleanup(); } void IceInternal::OutgoingAsync::__finished(const LocalException& exc) { - IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(_monitor); - - if(__os) // Don't retry if cleanup() was already called. + bool retry = false; { - // - // A CloseConnectionException indicates graceful server - // shutdown, and is therefore always repeatable without - // violating "at-most-once". That's because by sending a close - // connection message, the server guarantees that all - // outstanding requests can safely be repeated. Otherwise, we - // can also retry if the operation mode is Nonmutating or - // Idempotent. - // - // An ObjectNotExistException can always be retried as - // well without violating "at-most-once". - // - if(_mode == Nonmutating || _mode == Idempotent || dynamic_cast<const CloseConnectionException*>(&exc) || - dynamic_cast<const ObjectNotExistException*>(&exc)) + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + + if(__os) // Might be called from __prepare or before __prepare { - try + if(_timerTaskConnection && _proxy->__reference()->getInstance()->timer()->cancel(this)) { - _proxy->__handleException(_delegate, exc, _cnt); - __send(); - return; + _timerTaskConnection = 0; // Timer cancelled. } - catch(const LocalException&) + + while(_timerTaskConnection) + { + _monitor.wait(); + } + + // + // A CloseConnectionException indicates graceful server + // shutdown, and is therefore always repeatable without + // violating "at-most-once". That's because by sending a close + // connection message, the server guarantees that all + // outstanding requests can safely be repeated. Otherwise, we + // can also retry if the operation mode is Nonmutating or + // Idempotent. + // + // An ObjectNotExistException can always be retried as + // well without violating "at-most-once". + // + if(!_sent || + _mode == Nonmutating || _mode == Idempotent || + dynamic_cast<const CloseConnectionException*>(&exc) || + dynamic_cast<const ObjectNotExistException*>(&exc)) { + retry = true; } } } + if(retry) + { + try + { + _proxy->__handleException(_delegate, exc, _cnt); + __send(); + return; + } + catch(const LocalException&) + { + } + } + try { ice_exception(exc); @@ -240,14 +301,58 @@ IceInternal::OutgoingAsync::__finished(const LocalException& exc) warning(); } + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); cleanup(); } void +IceInternal::OutgoingAsync::__finished(const LocalExceptionWrapper& ex) +{ + // + // NOTE: This is called if sendRequest/sendAsyncRequest fails with + // a LocalExceptionWrapper exception. It's not possible for the + // timer to be set at this point because the request couldn't be + // sent. + // + assert(!_sent && !_timerTaskConnection); + + try + { + if(_mode == Nonmutating || _mode == Idempotent) + { + _proxy->__handleExceptionWrapperRelaxed(_delegate, ex, _cnt); + } + else + { + _proxy->__handleExceptionWrapper(_delegate, ex); + } + __send(); + } + catch(const Ice::LocalException& exc) + { + try + { + ice_exception(exc); + } + catch(const std::exception& ex) + { + warning(ex); + } + catch(...) + { + warning(); + } + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + cleanup(); + } +} + +void IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operation, OperationMode mode, const Context* context) { - IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(_monitor); + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); try { @@ -258,16 +363,20 @@ IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operat { _monitor.wait(); } - + // - // Can't call async via a oneway proxy. + // Can't call async via a batch proxy. // - prx->__checkTwowayOnly(operation); - _proxy = prx; + if(_proxy->ice_isBatchOneway() || _proxy->ice_isBatchDatagram()) + { + throw Ice::FeatureNotSupportedException(__FILE__, __LINE__, "can't send batch requests with AMI"); + } _delegate = 0; _cnt = 0; _mode = mode; + _sent = false; + _response = false; ReferencePtr ref = _proxy->__reference(); assert(!__is); @@ -308,11 +417,8 @@ IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operat // // Implicit context // - const ImplicitContextIPtr& implicitContext = - ref->getInstance()->getImplicitContext(); - + const ImplicitContextIPtr& implicitContext = ref->getInstance()->getImplicitContext(); const Context& prxContext = ref->getContext()->getValue(); - if(implicitContext == 0) { __writeContext(__os, prxContext); @@ -335,41 +441,45 @@ IceInternal::OutgoingAsync::__prepare(const ObjectPrx& prx, const string& operat void IceInternal::OutgoingAsync::__send() { - IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(_monitor); - + // + // NOTE: no synchronization needed. At this point, no other threads can be calling on this object. + // + RequestHandler* handler; try { - while(true) + _delegate = _proxy->__getDelegate(true); + handler = _delegate->__getRequestHandler().get(); + } + catch(const Ice::LocalException& ex) + { + __finished(ex); + return; + } + + _sent = false; + _response = false; + handler->sendAsyncRequest(this); +} + +void +IceInternal::OutgoingAsync::runTimerTask() // Implementation of TimerTask::runTimerTask() +{ + Ice::ConnectionIPtr connection; + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + assert(_timerTaskConnection && _sent); // Can only be set once the request is sent. + + if(!_response) // If the response was just received, don't close the connection. { - bool compress; - _delegate = _proxy->__getDelegate(); - Ice::ConnectionIPtr connection = _delegate->__getConnection(compress); - try - { - connection->sendAsyncRequest(__os, this, compress); - - // - // Don't do anything after sendAsyncRequest() returned - // without an exception. I such case, there will be - // callbacks, i.e., calls to the __finished() - // functions. Since there is no mutex protection, we - // cannot modify state here and in such callbacks. - // - return; - } - catch(const LocalExceptionWrapper& ex) - { - _proxy->__handleExceptionWrapper(_delegate, ex); - } - catch(const LocalException& ex) - { - _proxy->__handleException(_delegate, ex, _cnt); - } + connection = _timerTaskConnection; } + _timerTaskConnection = 0; + _monitor.notifyAll(); } - catch(const LocalException& ex) + + if(connection) { - __finished(ex); + connection->exception(Ice::TimeoutException(__FILE__, __LINE__)); } } @@ -414,6 +524,8 @@ IceInternal::OutgoingAsync::warning() const void IceInternal::OutgoingAsync::cleanup() { + assert(!_timerTaskConnection); + delete __is; __is = 0; delete __os; @@ -422,6 +534,91 @@ IceInternal::OutgoingAsync::cleanup() _monitor.notify(); } +IceInternal::BatchOutgoingAsync::BatchOutgoingAsync() : _os(0) +{ +} + +void +IceInternal::BatchOutgoingAsync::__prepare(const InstancePtr& instance) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + while(_os) + { + _monitor.wait(); + } + _os = new BasicStream(instance.get()); +} + +void +IceInternal::BatchOutgoingAsync::__sent(Ice::ConnectionI* connection) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + cleanup(); +} + +void +IceInternal::BatchOutgoingAsync::__finished(const Ice::LocalException& exc) +{ + try + { + ice_exception(exc); + } + catch(const std::exception& ex) + { + warning(ex); + } + catch(...) + { + warning(); + } + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + cleanup(); +} + +void +IceInternal::BatchOutgoingAsync::warning(const std::exception& exc) const +{ + if(_os) // Don't print anything if cleanup() was already called. + { + if(_os->instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + { + Warning out(_os->instance()->initializationData().logger); + const Exception* ex = dynamic_cast<const ObjectNotExistException*>(&exc); + if(ex) + { + out << "Ice::Exception raised by AMI callback:\n" << ex; + } + else + { + out << "std::exception raised by AMI callback:\n" << exc.what(); + } + } + } +} + +void +IceInternal::BatchOutgoingAsync::warning() const +{ + if(_os) // Don't print anything if cleanup() was already called. + { + if(_os->instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.AMICallback", 1) > 0) + { + Warning out(_os->instance()->initializationData().logger); + out << "unknown exception raised by AMI callback"; + } + } +} + +void +IceInternal::BatchOutgoingAsync::cleanup() +{ + delete _os; + _os = 0; + + _monitor.notify(); +} + void Ice::AMI_Object_ice_invoke::__invoke(const ObjectPrx& prx, const string& operation, OperationMode mode, const vector<Byte>& inParams, const Context* context) @@ -492,3 +689,24 @@ Ice::AMI_Array_Object_ice_invoke::__response(bool ok) // ok == true means no use } ice_response(ok, outParams); } + +void +Ice::AMI_Object_ice_flushBatchRequests::__invoke(const ObjectPrx& prx) +{ + Handle< ::IceDelegate::Ice::Object> delegate; + RequestHandler* handler; + try + { + __prepare(prx->__reference()->getInstance()); + delegate = prx->__getDelegate(true); + handler = delegate->__getRequestHandler().get(); + } + catch(const Ice::LocalException& ex) + { + __finished(ex); + return; + } + + handler->flushAsyncBatchRequests(this); +} + diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp index 82b47e23ac6..f72db807b30 100644 --- a/cpp/src/Ice/PropertyNames.cpp +++ b/cpp/src/Ice/PropertyNames.cpp @@ -7,7 +7,7 @@ // // ********************************************************************** // -// Generated by makeprops.py from file ../config/PropertyNames.xml, Thu Nov 22 20:40:28 2007 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Nov 26 11:29:02 2007 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h index e326b32c07f..eeb33e1fb30 100644 --- a/cpp/src/Ice/PropertyNames.h +++ b/cpp/src/Ice/PropertyNames.h @@ -7,7 +7,7 @@ // // ********************************************************************** // -// Generated by makeprops.py from file ../config/PropertyNames.xml, Thu Nov 22 20:40:28 2007 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Nov 26 11:29:02 2007 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/Ice/ProtocolPluginFacade.cpp b/cpp/src/Ice/ProtocolPluginFacade.cpp index f8ff17e63e9..2134bdd6ec1 100644 --- a/cpp/src/Ice/ProtocolPluginFacade.cpp +++ b/cpp/src/Ice/ProtocolPluginFacade.cpp @@ -50,12 +50,24 @@ IceInternal::ProtocolPluginFacade::getNetworkTraceCategory() const return _instance->traceLevels()->networkCat; } +EndpointHostResolverPtr +IceInternal::ProtocolPluginFacade::getEndpointHostResolver() const +{ + return _instance->endpointHostResolver(); +} + void IceInternal::ProtocolPluginFacade::addEndpointFactory(const EndpointFactoryPtr& factory) const { _instance->endpointFactoryManager()->add(factory); } +EndpointFactoryPtr +IceInternal::ProtocolPluginFacade::getEndpointFactory(Ice::Short type) const +{ + return _instance->endpointFactoryManager()->get(type); +} + IceInternal::ProtocolPluginFacade::ProtocolPluginFacade(const CommunicatorPtr& communicator) : _instance(getInstance(communicator)), _communicator(communicator) diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index 4d986ef0abc..845d40ffee5 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -14,6 +14,8 @@ #include <Ice/ObjectAdapterFactory.h> #include <Ice/Outgoing.h> #include <Ice/OutgoingAsync.h> +#include <Ice/ConnectRequestHandler.h> +#include <Ice/ConnectionRequestHandler.h> #include <Ice/Direct.h> #include <Ice/Reference.h> #include <Ice/EndpointI.h> @@ -123,7 +125,7 @@ IceProxy::Ice::Object::ice_isA(const string& typeId, const Context* context) try { __checkTwowayOnly("ice_isA"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del->ice_isA(typeId, context); } catch(const LocalExceptionWrapper& __ex) @@ -146,7 +148,7 @@ IceProxy::Ice::Object::ice_ping(const Context* context) Handle< ::IceDelegate::Ice::Object> __del; try { - __del = __getDelegate(); + __del = __getDelegate(false); __del->ice_ping(context); return; } @@ -171,7 +173,7 @@ IceProxy::Ice::Object::ice_ids(const Context* context) try { __checkTwowayOnly("ice_ids"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del->ice_ids(context); } catch(const LocalExceptionWrapper& __ex) @@ -195,7 +197,7 @@ IceProxy::Ice::Object::ice_id(const Context* context) try { __checkTwowayOnly("ice_id"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del->ice_id(context); } catch(const LocalExceptionWrapper& __ex) @@ -244,7 +246,7 @@ IceProxy::Ice::Object::ice_invoke(const string& operation, Handle< ::IceDelegate::Ice::Object> __del; try { - __del = __getDelegate(); + __del = __getDelegate(false); return __del->ice_invoke(operation, mode, inParams, outParams, context); } catch(const LocalExceptionWrapper& __ex) @@ -824,9 +826,8 @@ IceProxy::Ice::Object::ice_getConnection() Handle< ::IceDelegate::Ice::Object> __del; try { - __del = __getDelegate(); - bool compress; - return __del->__getConnection(compress); + __del = __getDelegate(false); + return __del->__getRequestHandler()->getConnection(true); } catch(const LocalException& __ex) { @@ -848,8 +849,7 @@ IceProxy::Ice::Object::ice_getCachedConnection() const { try { - bool compress; - return __del->__getConnection(compress); + return __del->__getRequestHandler()->getConnection(false); } catch(const CollocationOptimizationException&) { @@ -858,6 +858,36 @@ IceProxy::Ice::Object::ice_getCachedConnection() const return 0; } +void +IceProxy::Ice::Object::ice_flushBatchRequests() +{ + int __cnt; + while(true) + { + Handle< ::IceDelegate::Ice::Object> __del; + try + { + __del = __getDelegate(false); + __del->ice_flushBatchRequests(); + return; + } + catch(const LocalExceptionWrapper& __ex) + { + __handleExceptionWrapper(__del, __ex); + } + catch(const LocalException& __ex) + { + __handleException(__del, __ex, __cnt); + } + } +} + +void +IceProxy::Ice::Object::ice_flushBatchRequests_async(const AMI_Object_ice_flushBatchRequestsPtr& cb) +{ + cb->__invoke(this); +} + ReferencePtr IceProxy::Ice::Object::__reference() const { @@ -1024,7 +1054,7 @@ operator<<(ostream& os, const ::IceProxy::Ice::Object& p) } Handle< ::IceDelegate::Ice::Object> -IceProxy::Ice::Object::__getDelegate() +IceProxy::Ice::Object::__getDelegate(bool async) { IceUtil::Mutex::Lock sync(*this); @@ -1048,19 +1078,8 @@ IceProxy::Ice::Object::__getDelegate() if(!delegate) { Handle< ::IceDelegateM::Ice::Object> d = __createDelegateM(); - d->setup(_reference); + d->setup(_reference, this, async); delegate = d; - - // - // If this proxy is for a non-local object, and we are - // using a router, then add this proxy to the router info - // object. - // - RouterInfoPtr ri = _reference->getRouterInfo(); - if(ri) - { - ri->addProxy(this); - } } if(_reference->getCacheConnection()) @@ -1076,6 +1095,26 @@ IceProxy::Ice::Object::__getDelegate() return delegate; } +void +IceProxy::Ice::Object::__setRequestHandler(const Handle< ::IceDelegate::Ice::Object>& delegate, + const ::IceInternal::RequestHandlerPtr& handler) +{ + IceUtil::Mutex::Lock sync(*this); + if(_delegate.get() == delegate.get()) + { + if(dynamic_cast< ::IceDelegateM::Ice::Object*>(_delegate.get())) + { + _delegate = __createDelegateM(); + _delegate->__setRequestHandler(handler); + } + else if(dynamic_cast< ::IceDelegateD::Ice::Object*>(_delegate.get())) + { + _delegate = __createDelegateD(); + _delegate->__setRequestHandler(handler); + } + } +} + Handle< ::IceDelegateM::Ice::Object> IceProxy::Ice::Object::__createDelegateM() { @@ -1116,7 +1155,7 @@ bool IceDelegateM::Ice::Object::ice_isA(const string& __id, const Context* context) { static const string __operation("ice_isA"); - Outgoing __og(__connection.get(), __reference.get(), __operation, ::Ice::Nonmutating, context, __compress); + Outgoing __og(__handler.get(), __operation, ::Ice::Nonmutating, context); try { BasicStream* __os = __og.os(); @@ -1155,7 +1194,7 @@ void IceDelegateM::Ice::Object::ice_ping(const Context* context) { static const string __operation("ice_ping"); - Outgoing __og(__connection.get(), __reference.get(), __operation, ::Ice::Nonmutating, context, __compress); + Outgoing __og(__handler.get(), __operation, ::Ice::Nonmutating, context); bool __ok = __og.invoke(); try { @@ -1182,7 +1221,7 @@ vector<string> IceDelegateM::Ice::Object::ice_ids(const Context* context) { static const string __operation("ice_ids"); - Outgoing __og(__connection.get(), __reference.get(), __operation, ::Ice::Nonmutating, context, __compress); + Outgoing __og(__handler.get(), __operation, ::Ice::Nonmutating, context); vector<string> __ret; bool __ok = __og.invoke(); try @@ -1212,7 +1251,7 @@ string IceDelegateM::Ice::Object::ice_id(const Context* context) { static const string __operation("ice_id"); - Outgoing __og(__connection.get(), __reference.get(), __operation, ::Ice::Nonmutating, context, __compress); + Outgoing __og(__handler.get(), __operation, ::Ice::Nonmutating, context); string __ret; bool __ok = __og.invoke(); try @@ -1245,7 +1284,7 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation, vector<Byte>& outParams, const Context* context) { - Outgoing __og(__connection.get(), __reference.get(), operation, mode, context, __compress); + Outgoing __og(__handler.get(), operation, mode, context); try { BasicStream* __os = __og.os(); @@ -1256,7 +1295,7 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation, __og.abort(__ex); } bool ok = __og.invoke(); - if(__reference->getMode() == Reference::ModeTwoway) + if(__handler->getReference()->getMode() == Reference::ModeTwoway) { try { @@ -1272,11 +1311,35 @@ IceDelegateM::Ice::Object::ice_invoke(const string& operation, return ok; } -ConnectionIPtr -IceDelegateM::Ice::Object::__getConnection(bool& compress) const +void +IceDelegateM::Ice::Object::ice_flushBatchRequests() { - compress = __compress; - return __connection; + BatchOutgoing __og(__handler.get()); + try + { + __og.invoke(); + } + catch(const ::Ice::LocalException& __ex) + { + // + // We never retry flusing the batch requests as the connection batched + // requests were discarded and the caller needs to be notified of the + // failure. + // + throw ::IceInternal::LocalExceptionWrapper(__ex, false); + } +} + +RequestHandlerPtr +IceDelegateM::Ice::Object::__getRequestHandler() const +{ + return __handler; +} + +void +IceDelegateM::Ice::Object::__setRequestHandler(const RequestHandlerPtr& handler) +{ + __handler = handler; } void @@ -1291,28 +1354,36 @@ IceDelegateM::Ice::Object::__copyFrom(const ::IceInternal::Handle< ::IceDelegate // No need to synchronize "*this", as this operation is only // called upon initialization. // - - assert(!__reference); - assert(!__connection); - - __reference = from->__reference; - __connection = from->__connection; - __compress = from->__compress; + + assert(!__handler); + + __handler = from->__handler; } void -IceDelegateM::Ice::Object::setup(const ReferencePtr& ref) +IceDelegateM::Ice::Object::setup(const ReferencePtr& ref, const ::Ice::ObjectPrx& proxy, bool async) { // // No need to synchronize "*this", as this operation is only // called upon initialization. // - assert(!__reference); - assert(!__connection); + assert(!__handler); - __reference = ref; - __connection = __reference->getConnection(__compress); + // + // If the delegate is created as a result of an AMI call or if the proxy is + // a batch proxy we use the connect request handler to connect the in the + // background. + // + if(async || ref->getMode() == Reference::ModeBatchOneway || ref->getMode() == Reference::ModeBatchDatagram) + { + IceInternal::ConnectRequestHandlerPtr handler = new ::IceInternal::ConnectRequestHandler(ref, proxy, this); + __handler = handler->connect(); + } + else + { + __handler = new ::IceInternal::ConnectionRequestHandler(ref, proxy); + } } bool @@ -1577,14 +1648,26 @@ IceDelegateD::Ice::Object::ice_invoke(const string&, return false; } -ConnectionIPtr -IceDelegateD::Ice::Object::__getConnection(bool&) const +void +IceDelegateD::Ice::Object::ice_flushBatchRequests() +{ + throw CollocationOptimizationException(__FILE__, __LINE__); +} + +RequestHandlerPtr +IceDelegateD::Ice::Object::__getRequestHandler() const { throw CollocationOptimizationException(__FILE__, __LINE__); return 0; } void +IceDelegateD::Ice::Object::__setRequestHandler(const RequestHandlerPtr&) +{ + throw CollocationOptimizationException(__FILE__, __LINE__); +} + +void IceDelegateD::Ice::Object::__copyFrom(const ::IceInternal::Handle< ::IceDelegateD::Ice::Object>& from) { // diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index b9e1d534836..3fe7eee422d 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -625,6 +625,20 @@ IceInternal::FixedReference::getConnection(bool& compress) const return connection; } +void +IceInternal::FixedReference::getConnection(const GetConnectionCallbackPtr& callback) const +{ + try + { + bool compress; + callback->setConnection(getConnection(compress), compress); + } + catch(const Ice::LocalException& ex) + { + callback->setException(ex); + } +} + bool IceInternal::FixedReference::operator==(const Reference& r) const { @@ -743,20 +757,6 @@ IceInternal::FixedReference::filterConnections(const vector<ConnectionIPtr>& all IceUtil::Shared* IceInternal::upCast(IceInternal::RoutableReference* p) { return p; } -vector<EndpointIPtr> -IceInternal::RoutableReference::getRoutedEndpoints() const -{ - if(_routerInfo) - { - // - // If we route, we send everything to the router's client - // proxy endpoints. - // - return _routerInfo->getClientEndpoints(); - } - return vector<EndpointIPtr>(); -} - bool IceInternal::RoutableReference::getSecure() const { @@ -1093,6 +1093,232 @@ IceInternal::RoutableReference::operator<(const Reference& r) const return false; } +ConnectionIPtr +IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& allEndpoints, bool& comp) const +{ + vector<EndpointIPtr> endpoints = filterEndpoints(allEndpoints); + if(endpoints.empty()) + { + throw Ice::NoEndpointException(__FILE__, __LINE__, toString()); + } + + OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); + Ice::ConnectionIPtr connection; + if(getCacheConnection() || endpoints.size() == 1) + { + // + // Get an existing connection or create one if there's no + // existing connection to one of the given endpoints. + // + connection = factory->create(endpoints, false, _threadPerConnection, getEndpointSelection(), comp); + } + else + { + // + // Go through the list of endpoints and try to create the + // connection until it succeeds. This is different from just + // calling create() with the given endpoints since this might + // create a new connection even if there's an existing + // connection for one of the endpoints. + // + + auto_ptr<LocalException> exception; + vector<EndpointIPtr> endpoint; + endpoint.push_back(0); + + for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + try + { + endpoint.back() = *p; + connection = factory->create(endpoint, p + 1 == endpoints.end(), _threadPerConnection, + getEndpointSelection(), comp); + break; + } + catch(const LocalException& ex) + { + exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); + } + } + + if(!connection) + { + assert(exception.get()); + exception->ice_throw(); + } + } + + assert(connection); + + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo) + { + connection->setAdapter(_routerInfo->getAdapter()); + } + + return connection; +} + +void +IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& allEndpoints, + const GetConnectionCallbackPtr& callback) const +{ + vector<EndpointIPtr> endpoints = filterEndpoints(allEndpoints); + if(endpoints.empty()) + { + callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, toString())); + return; + } + + // + // Finally, create the connection. + // + OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); + if(getCacheConnection() || endpoints.size() == 1) + { + class CB1 : public OutgoingConnectionFactory::CreateConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo) + { + connection->setAdapter(_routerInfo->getAdapter()); + } + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + CB1(const RouterInfoPtr& routerInfo, const GetConnectionCallbackPtr& callback) : + _routerInfo(routerInfo), _callback(callback) + { + } + + private: + + const RouterInfoPtr _routerInfo; + const GetConnectionCallbackPtr _callback; + }; + + // + // Get an existing connection or create one if there's no + // existing connection to one of the given endpoints. + // + factory->create(endpoints, false, _threadPerConnection, getEndpointSelection(), new CB1(_routerInfo, callback)); + return; + } + else + { + class CB2 : public OutgoingConnectionFactory::CreateConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_reference->getRouterInfo()) + { + connection->setAdapter(_reference->getRouterInfo()->getAdapter()); + } + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& ex) + { + if(!_exception.get()) + { + _exception.reset(dynamic_cast<Ice::LocalException*>(ex.ice_clone())); + } + + if(++_i == _endpoints.size()) + { + _callback->setException(*_exception.get()); + return; + } + + bool more = _i != _endpoints.size() - 1; + vector<EndpointIPtr> endpoint; + endpoint.push_back(_endpoints[_i]); + + OutgoingConnectionFactoryPtr factory = _reference->getInstance()->outgoingConnectionFactory(); + bool threadPerConnection = _reference->getThreadPerConnection(); + EndpointSelectionType sel = _reference->getEndpointSelection(); + factory->create(endpoint, more, threadPerConnection, sel, this); + } + + CB2(const RoutableReferencePtr& reference, const vector<EndpointIPtr>& endpoints, + const GetConnectionCallbackPtr& callback) : + _reference(reference), + _endpoints(endpoints), + _callback(callback), + _i(0) + { + } + + private: + + const RoutableReferencePtr _reference; + const vector<EndpointIPtr> _endpoints; + const GetConnectionCallbackPtr _callback; + size_t _i; + std::auto_ptr<Ice::LocalException> _exception; + }; + + // + // Go through the list of endpoints and try to create the + // connection until it succeeds. This is different from just + // calling create() with the given endpoints since this might + // create a new connection even if there's an existing + // connection for one of the endpoints. + // + + vector<EndpointIPtr> endpt; + endpt.push_back(endpoints[0]); + RoutableReference* self = const_cast<RoutableReference*>(this); + factory->create(endpt, true, _threadPerConnection, getEndpointSelection(), new CB2(self, endpoints, callback)); + return; + } +} + +void +IceInternal::RoutableReference::applyOverrides(vector<EndpointIPtr>& endpoints) const +{ + for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p) + { + *p = (*p)->connectionId(_connectionId); + if(_overrideCompress) + { + *p = (*p)->compress(_compress); + } + if(_overrideTimeout) + { + *p = (*p)->timeout(_timeout); + } + } +} + IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const SharedContextPtr& ctx, const string& fs, Mode md, bool sec, bool prefSec, const RouterInfoPtr& rtrInfo, @@ -1130,8 +1356,8 @@ IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) : { } -ConnectionIPtr -IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& allEndpoints, bool& comp) const +vector<EndpointIPtr> +IceInternal::RoutableReference::filterEndpoints(const vector<EndpointIPtr>& allEndpoints) const { vector<EndpointIPtr> endpoints = allEndpoints; @@ -1224,75 +1450,8 @@ IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& all // stable_partition(endpoints.begin(), endpoints.end(), not1(Ice::constMemFun(&EndpointI::secure))); } - - if(endpoints.empty()) - { - NoEndpointException ex(__FILE__, __LINE__); - ex.proxy = toString(); - throw ex; - } - - // - // Finally, create the connection. - // - OutgoingConnectionFactoryPtr factory = getInstance()->outgoingConnectionFactory(); - if(getCacheConnection() || endpoints.size() == 1) - { - // - // Get an existing connection or create one if there's no - // existing connection to one of the given endpoints. - // - return factory->create(endpoints, false, _threadPerConnection, getEndpointSelection(), comp); - } - else - { - // - // Go through the list of endpoints and try to create the - // connection until it succeeds. This is different from just - // calling create() with the given endpoints since this might - // create a new connection even if there's an existing - // connection for one of the endpoints. - // - - auto_ptr<LocalException> exception; - vector<EndpointIPtr> endpoint; - endpoint.push_back(0); - - for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p) - { - try - { - endpoint.back() = *p; - return factory->create(endpoint, p + 1 == endpoints.end(), _threadPerConnection, - getEndpointSelection(), comp); - } - catch(const LocalException& ex) - { - exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); - } - } - - assert(exception.get()); - exception->ice_throw(); - return 0; // Keeps the compiler happy. - } -} - -void -IceInternal::RoutableReference::applyOverrides(vector<EndpointIPtr>& endpoints) const -{ - for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p) - { - *p = (*p)->connectionId(_connectionId); - if(_overrideCompress) - { - *p = (*p)->compress(_compress); - } - if(_overrideTimeout) - { - *p = (*p)->timeout(_timeout); - } - } + + return endpoints; } IceUtil::Shared* IceInternal::upCast(IceInternal::DirectReference* p) { return p; } @@ -1403,7 +1562,8 @@ IceInternal::DirectReference::changeAdapterId(const string& newAdapterId) const getSecure(), getPreferSecure(), newAdapterId, getRouterInfo(), locatorInfo, getCollocationOptimization(), getCacheConnection(), getEndpointSelection(), - getThreadPerConnection(), getLocatorCacheTimeout()); + getThreadPerConnection(), + getLocatorCacheTimeout()); } else { @@ -1472,28 +1632,68 @@ IceInternal::DirectReference::toString() const ConnectionIPtr IceInternal::DirectReference::getConnection(bool& comp) const { - vector<EndpointIPtr> endpts = RoutableReference::getRoutedEndpoints(); - applyOverrides(endpts); - - if(endpts.empty()) + if(getRouterInfo()) { - endpts = _endpoints; // Endpoint overrides are already applied on these endpoints. + vector<EndpointIPtr> endpts = getRouterInfo()->getClientEndpoints(); + if(!endpts.empty()) + { + applyOverrides(endpts); + return createConnection(endpts, comp); + } } - ConnectionIPtr connection = createConnection(endpts, comp); + return createConnection(_endpoints, comp); +} + +void +IceInternal::DirectReference::getConnection(const GetConnectionCallbackPtr& callback) const +{ + class Callback : public RouterInfo::GetClientEndpointsCallback + { + public: + + virtual void + setEndpoints(const vector<EndpointIPtr>& endpoints) + { + vector<EndpointIPtr> endpts = endpoints; + if(!endpts.empty()) + { + _reference->applyOverrides(endpts); + _reference->createConnection(endpts, _callback); + return; + } + + _reference->createConnection(_reference->getEndpoints(), _callback); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + Callback(const DirectReferencePtr& reference, const GetConnectionCallbackPtr& callback) : + _reference(reference), _callback(callback) + { + } + + private: + + const DirectReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + }; - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // if(getRouterInfo()) { - connection->setAdapter(getRouterInfo()->getAdapter()); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo()->getClientEndpoints(new Callback(const_cast<DirectReference*>(this), callback)); + return; } - assert(connection); - return connection; + createConnection(_endpoints, callback); } bool @@ -1699,77 +1899,223 @@ IceInternal::IndirectReference::toString() const ConnectionIPtr IceInternal::IndirectReference::getConnection(bool& comp) const { - ConnectionIPtr connection; + if(getRouterInfo()) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + vector<EndpointIPtr> endpts = getRouterInfo()->getClientEndpoints(); + if(!endpts.empty()) + { + applyOverrides(endpts); + return createConnection(endpts, comp); + } + } while(true) { - vector<EndpointIPtr> endpts = RoutableReference::getRoutedEndpoints(); bool cached = false; - if(endpts.empty() && _locatorInfo) + vector<EndpointIPtr> endpts; + if(_locatorInfo) { - const IndirectReferencePtr self = const_cast<IndirectReference*>(this); - endpts = _locatorInfo->getEndpoints(self, _locatorCacheTimeout, cached); + endpts = _locatorInfo->getEndpoints(const_cast<IndirectReference*>(this), _locatorCacheTimeout, cached); + applyOverrides(endpts); } - applyOverrides(endpts); + if(endpts.empty()) + { + throw Ice::NoEndpointException(__FILE__, __LINE__, toString()); + } try { - connection = createConnection(endpts, comp); - assert(connection); + return createConnection(endpts, comp); } - catch(const NoEndpointException& ex) + catch(const NoEndpointException&) { - throw ex; // No need to retry if there's no endpoints. + throw; // No need to retry if there's no endpoints. } catch(const LocalException& ex) { - if(!getRouterInfo()) + assert(_locatorInfo); + _locatorInfo->clearCache(const_cast<IndirectReference*>(this)); + + if(cached) { - assert(_locatorInfo); - - // COMPILERFIX: Braces needed to prevent BCB from causing Reference refCount from + // COMPILERFIX: Braces needed to prevent BCB from causing TraceLevels refCount from // being decremented twice when loop continues. { - const IndirectReferencePtr self = const_cast<IndirectReference*>(this); - _locatorInfo->clearCache(self); + TraceLevelsPtr traceLevels = getInstance()->traceLevels(); + if(traceLevels->retry >= 2) + { + Trace out(getInstance()->initializationData().logger, traceLevels->retryCat); + out << "connection to cached endpoints failed\n" + << "removing endpoints from cache and trying one more time\n" << ex; + } } + continue; + } + throw; + } + } + + assert(false); + return 0; +} + +void +IceInternal::IndirectReference::getConnection(const GetConnectionCallbackPtr& callback) const +{ + class Callback : public RouterInfo::GetClientEndpointsCallback + { + public: + + virtual void + setEndpoints(const vector<EndpointIPtr>& endpoints) + { + vector<EndpointIPtr> endpts = endpoints; + if(!endpts.empty()) + { + _reference->applyOverrides(endpts); + _reference->createConnection(endpts, _callback); + return; + } + + _reference->getConnectionNoRouterInfo(_callback); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } + + Callback(const IndirectReferencePtr& reference, const GetConnectionCallbackPtr& callback) : + _reference(reference), _callback(callback) + { + } + + private: + + const IndirectReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + }; - if(cached) + if(getRouterInfo()) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo()->getClientEndpoints(new Callback(const_cast<IndirectReference*>(this), callback)); + return; + } + + getConnectionNoRouterInfo(callback); +} + +void +IceInternal::IndirectReference::getConnectionNoRouterInfo(const GetConnectionCallbackPtr& callback) const +{ + class Callback2 : public Reference::GetConnectionCallback + { + public: + + virtual void + setConnection(const Ice::ConnectionIPtr& connection, bool compress) + { + _callback->setConnection(connection, compress); + } + + virtual void + setException(const Ice::LocalException& exc) + { + try + { + exc.ice_throw(); + } + catch(const Ice::NoEndpointException& ex) + { + _callback->setException(ex); // No need to retry if there's no endpoints. + } + catch(const Ice::LocalException& ex) + { + LocatorInfoPtr locatorInfo = _reference->getLocatorInfo(); + assert(locatorInfo); + locatorInfo->clearCache(_reference); + if(_cached) { - // COMPILERFIX: Braces needed to prevent BCB from causing TraceLevels refCount from - // being decremented twice when loop continues. + TraceLevelsPtr traceLvls = _reference->getInstance()->traceLevels(); + if(traceLvls->retry >= 2) { - TraceLevelsPtr traceLevels = getInstance()->traceLevels(); - if(traceLevels->retry >= 2) - { - Trace out(getInstance()->initializationData().logger, traceLevels->retryCat); - out << "connection to cached endpoints failed\n" - << "removing endpoints from cache and trying one more time\n" << ex; - } + Trace out(_reference->getInstance()->initializationData().logger, traceLvls->retryCat); + out << "connection to cached endpoints failed\n" + << "removing endpoints from cache and trying one more time\n" << ex; } - continue; + _reference->getConnectionNoRouterInfo(_callback); // Retry. + return; } + _callback->setException(ex); } + } - throw; + Callback2(const IndirectReferencePtr& reference, const GetConnectionCallbackPtr& callback, bool cached): + _reference(reference), _callback(callback), _cached(cached) + { } + + private: + + const IndirectReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + const bool _cached; + }; + + class Callback : public LocatorInfo::GetEndpointsCallback + { + public: - break; - } + virtual void + setEndpoints(const vector<EndpointIPtr>& endpoints, bool cached) + { + if(endpoints.empty()) + { + _callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, _reference->toString())); + return; + } + + vector<EndpointIPtr> endpts = endpoints; + _reference->applyOverrides(endpts); + _reference->createConnection(endpts, new Callback2(_reference, _callback, cached)); + } + + virtual void + setException(const Ice::LocalException& ex) + { + _callback->setException(ex); + } - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // - if(getRouterInfo()) + Callback(const IndirectReferencePtr& reference, const GetConnectionCallbackPtr& callback) : + _reference(reference), _callback(callback) + { + } + + private: + + const IndirectReferencePtr _reference; + const GetConnectionCallbackPtr _callback; + }; + + if(_locatorInfo) { - connection->setAdapter(getRouterInfo()->getAdapter()); + IndirectReference* self = const_cast<IndirectReference*>(this); + _locatorInfo->getEndpoints(self, _locatorCacheTimeout, new Callback(self, callback)); + } + else + { + callback->setException(Ice::NoEndpointException(__FILE__, __LINE__, toString())); } - - assert(connection); - return connection; } int diff --git a/cpp/src/Ice/Reference.h b/cpp/src/Ice/Reference.h index 1430ebf7278..95715300787 100644 --- a/cpp/src/Ice/Reference.h +++ b/cpp/src/Ice/Reference.h @@ -33,6 +33,15 @@ class Reference : public IceUtil::Shared { public: + class GetConnectionCallback : virtual public IceUtil::Shared + { + public: + + virtual void setConnection(const Ice::ConnectionIPtr&, bool) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<GetConnectionCallback> GetConnectionCallbackPtr; + enum Type { TypeDirect, @@ -115,6 +124,7 @@ public: // Get a suitable connection for this reference. // virtual Ice::ConnectionIPtr getConnection(bool&) const = 0; + virtual void getConnection(const GetConnectionCallbackPtr&) const = 0; virtual bool operator==(const Reference&) const = 0; virtual bool operator!=(const Reference&) const = 0; @@ -180,6 +190,7 @@ public: virtual std::string toString() const; virtual Ice::ConnectionIPtr getConnection(bool&) const; + virtual void getConnection(const GetConnectionCallbackPtr&) const; virtual bool operator==(const Reference&) const; virtual bool operator!=(const Reference&) const; @@ -203,7 +214,6 @@ class RoutableReference : public Reference public: virtual RouterInfoPtr getRouterInfo() const { return _routerInfo; } - std::vector<EndpointIPtr> getRoutedEndpoints() const; virtual bool getSecure() const; virtual bool getPreferSecure() const; @@ -223,8 +233,6 @@ public: virtual ReferencePtr changeEndpointSelection(Ice::EndpointSelectionType) const; virtual ReferencePtr changeThreadPerConnection(bool) const; - virtual Ice::ConnectionIPtr getConnection(bool&) const = 0; - virtual int hash() const; virtual bool operator==(const Reference&) const = 0; @@ -233,6 +241,10 @@ public: virtual ReferencePtr clone() const = 0; + Ice::ConnectionIPtr createConnection(const std::vector<EndpointIPtr>&, bool&) const; + void createConnection(const std::vector<EndpointIPtr>&, const GetConnectionCallbackPtr&) const; + void applyOverrides(std::vector<EndpointIPtr>&) const; + protected: RoutableReference(const InstancePtr&, const Ice::CommunicatorPtr&, const Ice::Identity&, const SharedContextPtr&, @@ -240,8 +252,7 @@ protected: Ice::EndpointSelectionType, bool); RoutableReference(const RoutableReference&); - Ice::ConnectionIPtr createConnection(const std::vector<EndpointIPtr>&, bool&) const; - void applyOverrides(std::vector<EndpointIPtr>&) const; + std::vector<EndpointIPtr> filterEndpoints(const std::vector<EndpointIPtr>&) const; private: @@ -284,6 +295,7 @@ public: virtual void streamWrite(BasicStream*) const; virtual std::string toString() const; virtual Ice::ConnectionIPtr getConnection(bool&) const; + virtual void getConnection(const GetConnectionCallbackPtr&) const; virtual bool operator==(const Reference&) const; virtual bool operator!=(const Reference&) const; @@ -323,6 +335,8 @@ public: virtual void streamWrite(BasicStream*) const; virtual std::string toString() const; virtual Ice::ConnectionIPtr getConnection(bool&) const; + virtual void getConnection(const GetConnectionCallbackPtr&) const; + virtual void getConnectionNoRouterInfo(const GetConnectionCallbackPtr&) const; virtual int hash() const; // Conceptually const. diff --git a/cpp/src/Ice/ReferenceFactory.cpp b/cpp/src/Ice/ReferenceFactory.cpp index 4c055017f68..0e894056597 100644 --- a/cpp/src/Ice/ReferenceFactory.cpp +++ b/cpp/src/Ice/ReferenceFactory.cpp @@ -623,8 +623,7 @@ IceInternal::ReferenceFactory::createFromProperties(const string& propertyPrefix } else { - ref = ref->changeRouter( - RouterPrx::uncheckedCast(_communicator->propertyToProxy(property))); + ref = ref->changeRouter(RouterPrx::uncheckedCast(_communicator->propertyToProxy(property))); } } diff --git a/cpp/src/Ice/RequestHandler.cpp b/cpp/src/Ice/RequestHandler.cpp new file mode 100644 index 00000000000..cf2845c77ae --- /dev/null +++ b/cpp/src/Ice/RequestHandler.cpp @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/RequestHandler.h> + +using namespace std; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(RequestHandler* obj) { return obj; } + +RequestHandler::~RequestHandler() +{ +} + +RequestHandler::RequestHandler(const ReferencePtr& reference) : _reference(reference) +{ +} diff --git a/cpp/src/Ice/RequestHandler.h b/cpp/src/Ice/RequestHandler.h new file mode 100644 index 00000000000..1b22794930c --- /dev/null +++ b/cpp/src/Ice/RequestHandler.h @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_REQUEST_HANDLER_H +#define ICE_REQUEST_HANDLER_H + +#include <IceUtil/Shared.h> + +#include <Ice/RequestHandlerF.h> +#include <Ice/ReferenceF.h> +#include <Ice/OutgoingAsyncF.h> +#include <Ice/ConnectionIF.h> + +namespace IceInternal +{ + +class BasicStream; +class Outgoing; +class BatchOutgoing; + +class RequestHandler : virtual public ::IceUtil::Shared +{ +public: + + virtual ~RequestHandler(); + + virtual void prepareBatchRequest(BasicStream*) = 0; + virtual void finishBatchRequest(BasicStream*) = 0; + virtual void abortBatchRequest() = 0; + + virtual Ice::ConnectionI* sendRequest(Outgoing*) = 0; + virtual void sendAsyncRequest(const OutgoingAsyncPtr&) = 0; + + virtual bool flushBatchRequests(BatchOutgoing*) = 0; + virtual void flushAsyncBatchRequests(const BatchOutgoingAsyncPtr&) = 0; + + const ReferencePtr& getReference() const { return _reference; } // Inlined for performances. + + virtual Ice::ConnectionIPtr getConnection(bool) = 0; + +protected: + + RequestHandler(const ReferencePtr&); + const ReferencePtr _reference; +}; + +} + +#endif diff --git a/cpp/src/Ice/RouterInfo.cpp b/cpp/src/Ice/RouterInfo.cpp index fd2e9ea5300..4ab5323593a 100644 --- a/cpp/src/Ice/RouterInfo.cpp +++ b/cpp/src/Ice/RouterInfo.cpp @@ -154,12 +154,168 @@ IceInternal::RouterInfo::getRouter() const vector<EndpointIPtr> IceInternal::RouterInfo::getClientEndpoints() { + { + IceUtil::Mutex::Lock sync(*this); + if(!_clientEndpoints.empty()) + { + return _clientEndpoints; + } + } + + return setClientEndpoints(_router->getClientProxy()); +} + +void +IceInternal::RouterInfo::getClientEndpoints(const GetClientEndpointsCallbackPtr& callback) +{ + vector<EndpointIPtr> clientEndpoints; + { + IceUtil::Mutex::Lock sync(*this); + clientEndpoints = _clientEndpoints; + } + + if(!clientEndpoints.empty()) + { + callback->setEndpoints(clientEndpoints); + return; + } + + class Callback : public AMI_Router_getClientProxy + { + public: + + virtual void + ice_response(const Ice::ObjectPrx& clientProxy) + { + _callback->setEndpoints(_routerInfo->setClientEndpoints(clientProxy)); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + _callback->setException(dynamic_cast<const Ice::LocalException&>(ex)); + } + + Callback(const RouterInfoPtr& routerInfo, const GetClientEndpointsCallbackPtr& callback) : + _routerInfo(routerInfo), _callback(callback) + { + } + + private: + + const RouterInfoPtr _routerInfo; + const GetClientEndpointsCallbackPtr _callback; + }; + + _router->getClientProxy_async(new Callback(this, callback)); +} + +vector<EndpointIPtr> +IceInternal::RouterInfo::getServerEndpoints() +{ + { + IceUtil::Mutex::Lock sync(*this); + if(!_serverEndpoints.empty()) + { + return _serverEndpoints; + } + } + + return setServerEndpoints(_router->getServerProxy()); +} + +void +IceInternal::RouterInfo::addProxy(const ObjectPrx& proxy) +{ + assert(proxy); // Must not be called for null proxies. + + { + IceUtil::Mutex::Lock sync(*this); + if(_identities.find(proxy->ice_getIdentity()) != _identities.end()) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return; + } + } + + ObjectProxySeq proxies; + proxies.push_back(proxy); + addAndEvictProxies(proxy, _router->addProxies(proxies)); +} + +bool +IceInternal::RouterInfo::addProxy(const Ice::ObjectPrx& proxy, const AddProxyCallbackPtr& callback) +{ + assert(proxy); + { + IceUtil::Mutex::Lock sync(*this); + if(_identities.find(proxy->ice_getIdentity()) == _identities.end()) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return true; + } + } + + class Callback : public AMI_Router_addProxies + { + public: + + virtual void + ice_response(const Ice::ObjectProxySeq& evictedProxies) + { + _routerInfo->addAndEvictProxies(_proxy, evictedProxies); + _callback->addedProxy(); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + _callback->setException(dynamic_cast<const Ice::LocalException&>(ex)); + } + + Callback(const RouterInfoPtr& routerInfo, const Ice::ObjectPrx& proxy, const AddProxyCallbackPtr& callback) : + _routerInfo(routerInfo), _proxy(proxy), _callback(callback) + { + } + + private: + + const RouterInfoPtr _routerInfo; + const Ice::ObjectPrx _proxy; + const AddProxyCallbackPtr _callback; + }; + + Ice::ObjectProxySeq proxies; + proxies.push_back(proxy); + _router->addProxies_async(new Callback(this, proxy, callback), proxies); + return false; +} + +void +IceInternal::RouterInfo::setAdapter(const ObjectAdapterPtr& adapter) +{ IceUtil::Mutex::Lock sync(*this); - - if(_clientEndpoints.size() == 0) // Lazy initialization. + _adapter = adapter; +} + +ObjectAdapterPtr +IceInternal::RouterInfo::getAdapter() const +{ + IceUtil::Mutex::Lock sync(*this); + return _adapter; +} + +vector<EndpointIPtr> +IceInternal::RouterInfo::setClientEndpoints(const Ice::ObjectPrx& proxy) +{ + IceUtil::Mutex::Lock sync(*this); + if(_clientEndpoints.empty()) { - ObjectPrx clientProxy = _router->getClientProxy(); - if(!clientProxy) + if(!proxy) { // // If getClientProxy() return nil, use router endpoints. @@ -168,7 +324,7 @@ IceInternal::RouterInfo::getClientEndpoints() } else { - clientProxy = clientProxy->ice_router(0); // The client proxy cannot be routed. + Ice::ObjectPrx clientProxy = proxy->ice_router(0); // The client proxy cannot be routed. // // In order to avoid creating a new connection to the router, @@ -187,16 +343,15 @@ IceInternal::RouterInfo::getClientEndpoints() _clientEndpoints = clientProxy->__reference()->getEndpoints(); } } - return _clientEndpoints; } + vector<EndpointIPtr> -IceInternal::RouterInfo::getServerEndpoints() +IceInternal::RouterInfo::setServerEndpoints(const Ice::ObjectPrx& serverProxy) { IceUtil::Mutex::Lock sync(*this); - - if(_serverEndpoints.size() == 0) // Lazy initialization. + if(_serverEndpoints.empty()) // Lazy initialization. { ObjectPrx serverProxy = _router->getServerProxy(); if(!serverProxy) @@ -208,53 +363,45 @@ IceInternal::RouterInfo::getServerEndpoints() _serverEndpoints = serverProxy->__reference()->getEndpoints(); } - return _serverEndpoints; } void -IceInternal::RouterInfo::addProxy(const ObjectPrx& proxy) +IceInternal::RouterInfo::addAndEvictProxies(const Ice::ObjectPrx& proxy, const Ice::ObjectProxySeq& evictedProxies) { - assert(proxy); // Must not be called for null proxies. - IceUtil::Mutex::Lock sync(*this); - set<Identity>::iterator p = _identities.find(proxy->ice_getIdentity()); - - if(p == _identities.end()) + // + // Check if the proxy hasn't already been evicted by a concurrent addProxies call. + // If it's the case, don't add it to our local map. + // + multiset<Identity>::iterator p = _evictedIdentities.find(proxy->ice_getIdentity()); + if(p != _evictedIdentities.end()) + { + _evictedIdentities.erase(p); + } + else { // - // Only add the proxy to the router if it's not already in our local map. - // - ObjectProxySeq proxies; - proxies.push_back(proxy); - ObjectProxySeq evictedProxies = _router->addProxies(proxies); - - // - // If we successfully added the proxy to the router, we add it to our local map. - // - _identities.insert(_identities.begin(), proxy->ice_getIdentity()); - - // - // We also must remove whatever proxies the router evicted. + // If we successfully added the proxy to the router, + // we add it to our local map. // - for(ObjectProxySeq::iterator q = evictedProxies.begin(); q != evictedProxies.end(); ++q) + _identities.insert(proxy->ice_getIdentity()); + } + + // + // We also must remove whatever proxies the router evicted. + // + for(Ice::ObjectProxySeq::const_iterator q = evictedProxies.begin(); q != evictedProxies.end(); ++q) + { + if(_identities.erase((*q)->ice_getIdentity()) == 0) { - _identities.erase((*q)->ice_getIdentity()); + // + // It's possible for the proxy to not have been + // added yet in the local map if two threads + // concurrently call addProxies. + // + _evictedIdentities.insert((*q)->ice_getIdentity()); } } } - -void -IceInternal::RouterInfo::setAdapter(const ObjectAdapterPtr& adapter) -{ - IceUtil::Mutex::Lock sync(*this); - _adapter = adapter; -} - -ObjectAdapterPtr -IceInternal::RouterInfo::getAdapter() const -{ - IceUtil::Mutex::Lock sync(*this); - return _adapter; -} diff --git a/cpp/src/Ice/RouterInfo.h b/cpp/src/Ice/RouterInfo.h index f7a6d9d773f..7a05dacddd2 100644 --- a/cpp/src/Ice/RouterInfo.h +++ b/cpp/src/Ice/RouterInfo.h @@ -16,6 +16,7 @@ #include <Ice/RouterF.h> #include <Ice/ProxyF.h> #include <Ice/EndpointIF.h> +#include <Ice/BuiltinSequences.h> #include <set> @@ -47,6 +48,24 @@ class RouterInfo : public IceUtil::Shared, public IceUtil::Mutex { public: + class GetClientEndpointsCallback : virtual public IceUtil::Shared + { + public: + + virtual void setEndpoints(const std::vector<EndpointIPtr>&) = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<GetClientEndpointsCallback> GetClientEndpointsCallbackPtr; + + class AddProxyCallback : virtual public IceUtil::Shared + { + public: + + virtual void addedProxy() = 0; + virtual void setException(const Ice::LocalException&) = 0; + }; + typedef IceUtil::Handle<AddProxyCallback> AddProxyCallbackPtr; + RouterInfo(const Ice::RouterPrx&); void destroy(); @@ -56,19 +75,27 @@ public: bool operator<(const RouterInfo&) const; Ice::RouterPrx getRouter() const; - std::vector<IceInternal::EndpointIPtr> getClientEndpoints(); - std::vector<IceInternal::EndpointIPtr> getServerEndpoints(); + std::vector<EndpointIPtr> getClientEndpoints(); + void getClientEndpoints(const GetClientEndpointsCallbackPtr&); + std::vector<EndpointIPtr> getServerEndpoints(); void addProxy(const Ice::ObjectPrx&); + bool addProxy(const Ice::ObjectPrx&, const AddProxyCallbackPtr&); + void setAdapter(const Ice::ObjectAdapterPtr&); Ice::ObjectAdapterPtr getAdapter() const; private: + std::vector<EndpointIPtr> setClientEndpoints(const Ice::ObjectPrx&); + std::vector<EndpointIPtr> setServerEndpoints(const Ice::ObjectPrx&); + void addAndEvictProxies(const Ice::ObjectPrx&, const Ice::ObjectProxySeq&); + const Ice::RouterPrx _router; - std::vector<IceInternal::EndpointIPtr> _clientEndpoints; - std::vector<IceInternal::EndpointIPtr> _serverEndpoints; + std::vector<EndpointIPtr> _clientEndpoints; + std::vector<EndpointIPtr> _serverEndpoints; Ice::ObjectAdapterPtr _adapter; std::set<Ice::Identity> _identities; + std::multiset<Ice::Identity> _evictedIdentities; }; } diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp new file mode 100644 index 00000000000..5e82c2f7ee3 --- /dev/null +++ b/cpp/src/Ice/Selector.cpp @@ -0,0 +1,497 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <IceUtil/DisableWarnings.h> +#include <Ice/Selector.h> +#include <Ice/Network.h> +#include <Ice/Instance.h> +#include <Ice/LoggerUtil.h> + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceInternal::Selector::Selector(const InstancePtr& instance, int timeout) : + _instance(instance), + _timeout(timeout) +{ +#if defined(_WIN32) + _fdsInUse = 0; + FD_ZERO(&_readFdSet); + FD_ZERO(&_writeFdSet); + FD_ZERO(&_errorFdSet); +#elif defined(ICE_USE_EPOLL) + _epollFd = epoll_create(1); + if(_epollFd < 0) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } +#elif defined(__APPLE__) + _kqueueFd = kqueue(); + if(_kqueueFd < 0) + { + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } +#endif + + SOCKET fds[2]; + createPipe(fds); + _fdIntrRead = fds[0]; + _fdIntrWrite = fds[1]; + setBlock(_fdIntrRead, false); + _maxFd = _fdIntrRead; + add(_fdIntrRead, NeedRead); +#if defined(_WIN32) + ++_fdsInUse; +#endif + + _lastFd = _fdIntrRead; +} + +IceInternal::Selector::~Selector() +{ +#if defined(ICE_USE_EPOLL) + try + { + closeSocket(_epollFd); + } + catch(const LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } +#elif defined(__APPLE__) + try + { + closeSocket(_kqueueFd); + } + catch(const LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } +#endif + + + try + { + closeSocket(_fdIntrWrite); + } + catch(const LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } + + try + { + closeSocket(_fdIntrRead); + } + catch(const LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector while calling closeSocket():\n" << ex; + } +} + +void +IceInternal::Selector::add(SOCKET fd, SocketStatus status) +{ + if(fd > _maxFd) + { + _maxFd = fd; + } +#if defined(_WIN32) + switch(status) + { + case NeedRead: + FD_SET(fd, &_readFdSet); + break; + case NeedWrite: + FD_SET(fd, &_writeFdSet); + break; + case NeedConnect: + FD_SET(fd, &_writeFdSet); + FD_SET(fd, &_errorFdSet); + break; + case Finished: + assert(false); + } +#elif defined(ICE_USE_EPOLL) + epoll_event event; + switch(status) + { + case NeedRead: + event.events = EPOLLIN; + break; + case NeedWrite: + case NeedConnect: + event.events = EPOLLOUT; + break; + case Finished: + assert(false); + } + event.data.fd = fd; + if(epoll_ctl(_epollFd, EPOLL_CTL_ADD, fd, &event) != 0) + { + Error out(_instance->initializationData().logger); + out << "error while adding filedescriptor to epoll set:\n"; + out << errorToString(getSocketErrno()); + } + _events.resize(_events.size() + 1); +#elif defined(__APPLE__) + struct kevent event; + switch(status) + { + case NeedRead: + EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, 0); + break; + case NeedWrite: + case NeedConnect: + EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); + break; + case Finished: + assert(false); + } + if(kevent(_kqueueFd, &event, 1, 0, 0, 0) < 0) + { + Error out(_instance->initializationData().logger); + out << "error while adding filedescriptor to kqueue:\n"; + out << errorToString(getSocketErrno()); + } + _events.resize(_events.size() + 1); +#else + struct pollfd pollFd; + pollFd.fd = fd; + switch(status) + { + case NeedRead: + pollFd.events = POLLIN; + break; + case NeedWrite: + case NeedConnect: + pollFd.events = POLLOUT; + break; + case Finished: + assert(false); + } + _pollFdSet.push_back(pollFd); +#endif +} + +void +Selector::remove(SOCKET fd, SocketStatus status) +{ +#if defined(_WIN32) + switch(status) + { + case NeedRead: + FD_CLR(fd, &_readFdSet); + break; + case NeedWrite: + FD_CLR(fd, &_writeFdSet); + break; + case NeedConnect: + FD_CLR(fd, &_writeFdSet); + FD_CLR(fd, &_errorFdSet); + break; + case Finished: + assert(false); + } +#elif defined(ICE_USE_EPOLL) + epoll_event event; + event.events = 0; + int rs = epoll_ctl(_epollFd, EPOLL_CTL_DEL, fd, &event); + if(rs < 0) + { + // + // It's possible for the socket to already be closed at this point. + // +// Error out(_instance->initializationData().logger); +// out << "error while removing filedescriptor from epoll set:\n"; +// out << errorToString(getSocketErrno()); + } + _events.resize(_events.size() - 1); +#elif defined(__APPLE__) + struct kevent event; + switch(status) + { + case NeedRead: + EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, 0); + break; + case NeedWrite: + case NeedConnect: + EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + break; + case Finished: + assert(false); + } + int rs = kevent(_kqueueFd, &event, 1, 0, 0, 0); + if(rs < 0) + { + // + // It's possible for the socket to already be closed at this point. + // +// Error out(_instance->initializationData().logger); +// out << "error while removing filedescriptor from kqueue:\n"; +// out << errorToString(getSocketErrno()); + } + _events.resize(_events.size() - 1); +#else + for(vector<struct pollfd>::iterator p = _pollFdSet.begin(); p != _pollFdSet.end(); ++p) + { + if(p->fd == fd) + { + _pollFdSet.erase(p); + break; + } + } +#endif +} + +SOCKET +IceInternal::Selector::getNextSelected() +{ + assert(_nSelected > 0); + if(_nSelectedReturned == _nSelected) + { + return INVALID_SOCKET; + } + + // + // Round robin for the filedescriptors. + // + SOCKET largerFd = _maxFd + 1; + SOCKET smallestFd = _maxFd + 1; +#if defined(_WIN32) + if(_selectedReadFdSet.fd_count == 0 && _selectedWriteFdSet.fd_count == 0 && _selectedErrorFdSet.fd_count == 0) + { + Error out(_instance->initializationData().logger); + out << "select() in selector returned " << _nSelected << " but no filedescriptor is ready"; + return INVALID_SOCKET; + } + + const fd_set* fdSet; + if(_nSelectedReturned < _selectedReadFdSet.fd_count) + { + fdSet = &_selectedReadFdSet; + } + else if(_nSelectedReturned < _selectedWriteFdSet.fd_count + _selectedReadFdSet.fd_count) + { + fdSet = &_selectedWriteFdSet; + } + else + { + fdSet = &_selectedErrorFdSet; + } + + for(u_short i = 0; i < fdSet->fd_count; ++i) + { + SOCKET fd = fdSet->fd_array[i]; +#elif defined(ICE_USE_EPOLL) + for(unsigned int i = 0; i < _nSelected; ++i) + { + SOCKET fd = _events[i].data.fd; +#elif defined(__APPLE__) + for(unsigned int i = 0; i < _nSelected; ++i) + { + SOCKET fd = _events[i].ident; +#else + for(vector<struct pollfd>::const_iterator p = _pollFdSet.begin(); p != _pollFdSet.end(); ++p) + { + if(p->revents == 0) + { + continue; + } + SOCKET fd = p->fd; +#endif + assert(fd != INVALID_SOCKET); + if(fd > _lastFd) + { + largerFd = min(largerFd, fd); + } + + smallestFd = min(smallestFd, fd); + } +#ifdef never // To match ICE_USE_EPOLL __APPLE + }}} +#endif + + if(largerFd <= _maxFd) + { + _lastFd = largerFd; + } + else + { + assert(smallestFd <= _maxFd); + _lastFd = smallestFd; + } + ++_nSelectedReturned; + return _lastFd; +} + +int +IceInternal::Selector::select() +{ + while(true) + { + int ret; + _nSelectedReturned = 0; + _nSelected = 0; +#if defined(_WIN32) + fd_set* rFdSet = fdSetCopy(_selectedReadFdSet, _readFdSet); + fd_set* wFdSet = fdSetCopy(_selectedWriteFdSet, _writeFdSet); + fd_set* eFdSet = fdSetCopy(_selectedErrorFdSet, _errorFdSet); + + if(_timeout > 0) + { + struct timeval tv; + tv.tv_sec = _timeout; + tv.tv_usec = 0; + ret = ::select(0, rFdSet, wFdSet, eFdSet, &tv); // The first parameter is ignored on Windows + } + else + { + ret = ::select(0, rFdSet, wFdSet, eFdSet, 0); // The first parameter is ignored on Windows + } +#elif defined(ICE_USE_EPOLL) + ret = epoll_wait(_epollFd, &_events[0], _events.size(), _timeout > 0 ? _timeout * 1000 : -1); +#elif defined(__APPLE__) + assert(!_events.empty()); + if(_timeout > 0) + { + struct timespec ts; + ts.tv_sec = _timeout; + ts.tv_nsec = 0; + ret = kevent(_kqueueFd, 0, 0, &_events[0], _events.size(), &ts); + } + else + { + ret = kevent(_kqueueFd, 0, 0, &_events[0], _events.size(), 0); + } +#else + ret = poll(&_pollFdSet[0], _pollFdSet.size(), _timeout > 0 ? _timeout * 1000 : -1); +#endif + if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + + assert(ret >= 0); + _nSelected = static_cast<unsigned int>(ret); + if(_nSelected == 0) + { + assert(_timeout > 0); + _timeout = 0; + } + return _nSelected; + } +} + +void +IceInternal::Selector::setInterrupt() +{ + char c = 0; + while(true) + { +#ifdef _WIN32 + if(::send(_fdIntrWrite, &c, 1, 0) == SOCKET_ERROR) +#else + if(::write(_fdIntrWrite, &c, 1) == SOCKET_ERROR) +#endif + { + if(interrupted()) + { + continue; + } + + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + break; + } +} + +void +IceInternal::Selector::clearInterrupt() +{ + char c; + + while(true) + { + ssize_t ret; +#ifdef _WIN32 + ret = ::recv(_fdIntrRead, &c, 1, 0); +#else + ret = ::read(_fdIntrRead, &c, 1); +#endif + if(ret == SOCKET_ERROR) + { + if(interrupted()) + { + continue; + } + + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + break; + } +} + +#ifdef _WIN32 +void +IceInternal::Selector::incFdsInUse() +{ + // This is windows specific since every other platform uses an API + // that doesn't have a specific FD limit. + if(_fdsInUse + 1 > FD_SETSIZE) + { + Warning warn(_instance->initializationData().logger); + warn << "maximum number of connections exceeded"; + + // + // No appropriate errno. + // + SocketException ex(__FILE__, __LINE__); + ex.error = 0; + throw ex; + } + ++_fdsInUse; +} +#endif + +#ifdef _WIN32 +void +IceInternal::Selector::decFdsInUse() +{ + // This is windows specific since every other platform uses an API + // that doesn't have a specific FD limit. + if(_fdsInUse <= 1) + { + Trace trace(_instance->initializationData().logger, "ThreadPool"); + trace << "selector: about to assert"; + } + --_fdsInUse; +} +#endif + diff --git a/cpp/src/Ice/Selector.h b/cpp/src/Ice/Selector.h new file mode 100644 index 00000000000..4d680f14302 --- /dev/null +++ b/cpp/src/Ice/Selector.h @@ -0,0 +1,137 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_SELECTOR_H +#define ICE_SELECTOR_H + +#include <Ice/Config.h> +#include <Ice/InstanceF.h> + +#if defined(_WIN32) +# include <winsock2.h> +#else +# define SOCKET int +# if defined(ICE_USE_EPOLL) +# include <sys/epoll.h> +# elif defined(__APPLE__) +# include <sys/event.h> +# else +# include <sys/poll.h> +# endif +#endif + + +namespace IceInternal +{ + +enum SocketStatus +{ + Finished, + NeedConnect, + NeedRead, + NeedWrite +}; + +class Selector +{ +public: + + Selector(const InstancePtr&, int = 0); + ~Selector(); + + void add(SOCKET, SocketStatus); + void remove(SOCKET, SocketStatus); + + int select(); + SOCKET getNextSelected(); + + bool isInterrupted() + { + assert(_nSelected > 0); +#if defined(_WIN32) + return FD_ISSET(_fdIntrRead, &_selectedReadFdSet); +#elif defined(ICE_USE_EPOLL) + for(unsigned int i = 0; i < _nSelected; ++i) + { + if(_events[i].data.fd == _fdIntrRead) + { + return true; + } + } + return false; +#elif defined(__APPLE__) + for(unsigned int i = 0; i < _nSelected; ++i) + { + if(_events[i].ident == static_cast<unsigned int>(_fdIntrRead)) + { + return true; + } + } + return false; +#else + assert(_pollFdSet[0]->fd == _fdIntrRead); + return _pollFdSet[0]->revents != 0; +#endif + } + void setInterrupt(); + void clearInterrupt(); + + void updateMinMax(SOCKET minFd, SOCKET maxFd); + void clearMinMax(); + +#if defined(_WIN32) + void incFdsInUse(); + void decFdsInUse(); +#endif + +private: + + InstancePtr _instance; + int _timeout; + SOCKET _maxFd; + SOCKET _lastFd; + unsigned int _nSelected; + unsigned int _nSelectedReturned; + SOCKET _fdIntrRead; + SOCKET _fdIntrWrite; +#if defined(_WIN32) + fd_set _readFdSet; + fd_set _writeFdSet; + fd_set _errorFdSet; + fd_set _selectedReadFdSet; + fd_set _selectedWriteFdSet; + fd_set _selectedErrorFdSet; + int _fdsInUse; + + fd_set* + fdSetCopy(fd_set& dest, fd_set& src) + { + if(src.fd_count > 0) + { + dest.fd_count = src.fd_count; + memcpy(dest.fd_array, src.fd_array, sizeof(SOCKET) * src.fd_count); + return &dest; + } + return 0; + } + +#elif defined(ICE_USE_EPOLL) + int _epollFd; + std::vector<struct epoll_event> _events; +#elif defined(__APPLE__) + int _kqueueFd; + std::vector<struct kevent> _events; +#else + std::vector<struct pollfd> _pollFdSet; +#endif +}; + +} + +#endif diff --git a/cpp/src/Ice/SelectorThread.cpp b/cpp/src/Ice/SelectorThread.cpp new file mode 100644 index 00000000000..b0eb5007257 --- /dev/null +++ b/cpp/src/Ice/SelectorThread.cpp @@ -0,0 +1,309 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <IceUtil/DisableWarnings.h> +#include <Ice/SelectorThread.h> +#include <Ice/Network.h> +#include <Ice/Instance.h> +#include <Ice/LoggerUtil.h> + +using namespace std; +using namespace Ice; +using namespace IceInternal; + +IceUtil::Shared* IceInternal::upCast(SelectorThread* p) { return p; } + +IceInternal::SelectorThread::SelectorThread(const InstancePtr& instance) : + _instance(instance), + _destroyed(false), + _selector(instance), + _timer(_instance->timer()) +{ + + __setNoDelete(true); + try + { + _thread = new HelperThread(this); + _thread->start(); + } + catch(const IceUtil::Exception& ex) + { + { + Error out(_instance->initializationData().logger); + out << "cannot create thread for selector thread:\n" << ex; + } + __setNoDelete(false); + throw; + } + catch(...) + { + __setNoDelete(false); + throw; + } + __setNoDelete(false); +} + +IceInternal::SelectorThread::~SelectorThread() +{ + assert(_destroyed); +} + +void +IceInternal::SelectorThread::destroy() +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); + _destroyed = true; + _selector.setInterrupt(); +} + +void +IceInternal::SelectorThread::incFdsInUse() +{ + // This is windows specific since every other platform uses an API + // that doesn't have a specific FD limit. +#ifdef _WIN32 + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); + _selector.incFdsInUse(); +#endif +} + +void +IceInternal::SelectorThread::decFdsInUse() +{ + // This is windows specific since every other platform uses an API + // that doesn't have a specific FD limit. +#ifdef _WIN32 + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); + _selector.decFdsInUse(); +#endif +} + +void +IceInternal::SelectorThread::_register(SOCKET fd, const SocketReadyCallbackPtr& cb, SocketStatus status, int timeout) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing connection factories. + assert(status != Finished); + SocketInfo info(fd, cb, status, timeout); + _changes.push_back(info); + if(info.timeout >= 0) + { + _timer->schedule(info.cb, IceUtil::Time::milliSeconds(info.timeout)); + } + _selector.setInterrupt(); +} + +void +IceInternal::SelectorThread::unregister(SOCKET fd) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing connection factories. + _changes.push_back(SocketInfo(fd, 0, Finished, 0)); + _selector.setInterrupt(); +} + +void +IceInternal::SelectorThread::joinWithThread() +{ + assert(_destroyed); + if(_thread) + { + _thread->getThreadControl().join(); + } +} + +void +IceInternal::SelectorThread::run() +{ + std::map<SOCKET, SocketInfo> socketMap; + vector<SocketInfo*> readyList; + vector<SocketInfo*> finishedList; + while(true) + { + try + { + _selector.select(); + } + catch(const Ice::LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector thread:\n" << ex; + continue; + } + + assert(readyList.empty() && finishedList.empty()); + + { + if(_selector.isInterrupted()) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + // + // There are two possiblities for an interrupt: + // + // 1. The selector thread has been destroyed. + // 2. A socket was registered or unregistered. + // + + // + // Thread destroyed? + // + if(_destroyed) + { + break; + } + + _selector.clearInterrupt(); + + SocketInfo& change = _changes.front(); + if(change.cb) // Registration + { + _selector.add(change.fd, change.status); + assert(socketMap.find(change.fd) == socketMap.end()); + socketMap.insert(make_pair(change.fd, change)); + _maxFd = max(_maxFd, change.fd); + _minFd = min(_minFd, change.fd); + } + else // Unregistration + { + map<SOCKET, SocketInfo>::iterator r = socketMap.find(change.fd); + if(r != socketMap.end() && r->second.status != Finished) + { + if(r->second.timeout >= 0) + { + _timer->cancel(r->second.cb); + } + assert(r->second.status != Finished); + _selector.remove(r->second.fd, r->second.status); + r->second.status = Finished; + readyList.push_back(&(r->second)); + } + } + _changes.pop_front(); + } + else + { + + // + // Examine the selection key set. + // + SOCKET fd; + while((fd = _selector.getNextSelected()) != INVALID_SOCKET) + { + map<SOCKET, SocketInfo>::iterator r = socketMap.find(fd); + if(r != socketMap.end()) + { + if(r->second.timeout >= 0) + { + _timer->cancel(r->second.cb); + } + + readyList.push_back(&(r->second)); + } + } + } + } + + for(vector<SocketInfo*>::iterator p = readyList.begin(); p != readyList.end(); ++p) + { + SocketInfo* info = *p; + SocketStatus status; + try + { + status = info->cb->socketReady(info->status == Finished); + } + catch(const std::exception& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in selector thread while calling socketReady():\n" << ex.what(); + status = Finished; + } + catch(...) + { + Error out(_instance->initializationData().logger); + out << "unknown exception in selector thread while calling socketReady()"; + status = Finished; + } + + if(status == Finished) + { + finishedList.push_back(info); + } + else if(status != info->status) + { + assert(info->status != Finished); + _selector.remove(info->fd, info->status); + info->status = status; + _selector.add(info->fd, info->status); + if(info->timeout >= 0) + { + _timer->schedule(info->cb, IceUtil::Time::milliSeconds(info->timeout)); + } + } + } + + readyList.clear(); + + if(finishedList.empty()) + { + continue; + } + + for(vector<SocketInfo*>::const_iterator p = finishedList.begin(); p != finishedList.end(); ++p) + { + if((*p)->status != Finished) + { + _selector.remove((*p)->fd, (*p)->status); + } + socketMap.erase((*p)->fd); + } + finishedList.clear(); + } + + assert(_destroyed); +} + +IceInternal::SelectorThread::HelperThread::HelperThread(const SelectorThreadPtr& selectorThread) : + _selectorThread(selectorThread) +{ +} + +void +IceInternal::SelectorThread::HelperThread::run() +{ + if(_selectorThread->_instance->initializationData().threadHook) + { + _selectorThread->_instance->initializationData().threadHook->start(); + } + + try + { + _selectorThread->run(); + } + catch(const std::exception& ex) + { + Error out(_selectorThread->_instance->initializationData().logger); + out << "exception in selector thread:\n" << ex.what(); + } + catch(...) + { + Error out(_selectorThread->_instance->initializationData().logger); + out << "unknown exception in selector thread"; + } + + if(_selectorThread->_instance->initializationData().threadHook) + { + _selectorThread->_instance->initializationData().threadHook->stop(); + } + + _selectorThread = 0; // Break cyclic dependency. +} diff --git a/cpp/src/Ice/SelectorThread.h b/cpp/src/Ice/SelectorThread.h new file mode 100644 index 00000000000..ccf5423984e --- /dev/null +++ b/cpp/src/Ice/SelectorThread.h @@ -0,0 +1,137 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_SELECTOR_THREAD_H +#define ICE_SELECTOR_THREAD_H + +#include <IceUtil/Shared.h> +#include <IceUtil/Handle.h> +#include <IceUtil/Mutex.h> +#include <IceUtil/Monitor.h> +#include <IceUtil/Thread.h> +#include <IceUtil/Timer.h> + +#include <Ice/Config.h> +#include <Ice/SelectorThreadF.h> +#include <Ice/InstanceF.h> +#include <Ice/Selector.h> + +#if defined(_WIN32) +# include <winsock2.h> +#else +# define SOCKET int +# if defined(ICE_USE_EPOLL) +# include <sys/epoll.h> +# elif defined(__APPLE__) +# include <sys/event.h> +# else +# include <sys/poll.h> +# endif +#endif + +#include <deque> + +namespace IceInternal +{ + +class SocketReadyCallback : public IceUtil::TimerTask +{ +public: + + // + // The selector thread unregisters the callback when socketReady returns SocketStatus.Finished. + // + virtual SocketStatus socketReady(bool) = 0; + + // + // The selector thread doesn't unregister the callback when sockectTimeout is called; socketTimeout + // must unregister the callback either explicitly with unregister() or by shutting down the socket + // (if necessary). + // + virtual void socketTimeout() = 0; + +private: + + void + runTimerTask() + { + this->socketTimeout(); + } + + friend class SelectorThread; +}; +typedef IceUtil::Handle<SocketReadyCallback> SocketReadyCallbackPtr; + +class SelectorThread : public IceUtil::Shared, public IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + SelectorThread(const InstancePtr&); + virtual ~SelectorThread(); + + void destroy(); + + void incFdsInUse(); + void decFdsInUse(); + + void _register(SOCKET, const SocketReadyCallbackPtr&, SocketStatus status, int timeout); + void unregister(SOCKET); + void joinWithThread(); + +private: + + void run(); + + struct SocketInfo + { + SOCKET fd; + SocketReadyCallbackPtr cb; + SocketStatus status; + int timeout; + + SocketInfo(SOCKET fd, const SocketReadyCallbackPtr& cb, SocketStatus status, int timeout) + { + this->fd = fd; + this->cb = cb; + this->status = status; + this->timeout = timeout; + } + }; + + class HelperThread : public IceUtil::Thread + { + public: + + HelperThread(const SelectorThreadPtr&); + virtual void run(); + + private: + + SelectorThreadPtr _selectorThread; + }; + friend class HelperThread; + + InstancePtr _instance; + bool _destroyed; + + SOCKET _maxFd; + SOCKET _minFd; + SOCKET _fdIntrRead; + SOCKET _fdIntrWrite; + Selector _selector; + + std::deque<SocketInfo> _changes; + + IceUtil::ThreadPtr _thread; + IceUtil::TimerPtr _timer; +}; + +} + +#endif diff --git a/cpp/src/Ice/SelectorThreadF.h b/cpp/src/Ice/SelectorThreadF.h new file mode 100644 index 00000000000..1e80b87a8b0 --- /dev/null +++ b/cpp/src/Ice/SelectorThreadF.h @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef ICE_SELECTOR_THREAD_F_H +#define ICE_SELECTOR_THREAD_F_H + +#include <IceUtil/Shared.h> + +#include <Ice/Handle.h> + +namespace IceInternal +{ + +class SelectorThread; +IceUtil::Shared* upCast(SelectorThread*); +typedef Handle<SelectorThread> SelectorThreadPtr; + +} + +#endif diff --git a/cpp/src/Ice/TcpAcceptor.cpp b/cpp/src/Ice/TcpAcceptor.cpp index fd233738286..baa93aa594a 100644 --- a/cpp/src/Ice/TcpAcceptor.cpp +++ b/cpp/src/Ice/TcpAcceptor.cpp @@ -72,7 +72,7 @@ IceInternal::TcpAcceptor::accept(int timeout) out << "accepted tcp connection\n" << fdToString(fd); } - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd, true); } void diff --git a/cpp/src/Ice/TcpConnector.cpp b/cpp/src/Ice/TcpConnector.cpp index 5979914fedd..a4394598ba9 100644 --- a/cpp/src/Ice/TcpConnector.cpp +++ b/cpp/src/Ice/TcpConnector.cpp @@ -32,15 +32,16 @@ IceInternal::TcpConnector::connect(int timeout) SOCKET fd = createSocket(false); setBlock(fd, false); setTcpBufSize(fd, _instance->initializationData().properties, _logger); - doConnect(fd, _addr, timeout); - - if(_traceLevels->network >= 1) + bool connected = doConnect(fd, _addr, timeout); + if(connected) { - Trace out(_logger, _traceLevels->networkCat); - out << "tcp connection established\n" << fdToString(fd); + if(_traceLevels->network >= 1) + { + Trace out(_logger, _traceLevels->networkCat); + out << "tcp connection established\n" << fdToString(fd); + } } - - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd, connected); } Short @@ -118,21 +119,6 @@ IceInternal::TcpConnector::operator<(const Connector& r) const return compareAddress(_addr, p->_addr) == -1; } -bool -IceInternal::TcpConnector::equivalent(const string& host, int port) const -{ - struct sockaddr_in addr; - try - { - getAddress(host, port, addr); - } - catch(const DNSException&) - { - return false; - } - return compareAddress(addr, _addr) == 0; -} - IceInternal::TcpConnector::TcpConnector(const InstancePtr& instance, const struct sockaddr_in& addr, Ice::Int timeout, const string& connectionId) : _instance(instance), diff --git a/cpp/src/Ice/TcpConnector.h b/cpp/src/Ice/TcpConnector.h index ae0bc1a72a8..2147f30cccc 100644 --- a/cpp/src/Ice/TcpConnector.h +++ b/cpp/src/Ice/TcpConnector.h @@ -16,8 +16,8 @@ #include <Ice/LoggerF.h> #include <Ice/Connector.h> -#ifdef _WIN32
-# include <winsock2.h>
+#ifdef _WIN32 +# include <winsock2.h> #else # include <netinet/in.h> // For struct sockaddr_in #endif @@ -30,6 +30,7 @@ class TcpConnector : public Connector public: virtual TransceiverPtr connect(int); + virtual Ice::Short type() const; virtual std::string toString() const; @@ -37,8 +38,6 @@ public: virtual bool operator!=(const Connector&) const; virtual bool operator<(const Connector&) const; - bool equivalent(const std::string&, int) const; - private: TcpConnector(const InstancePtr&, const struct sockaddr_in&, Ice::Int, const std::string&); diff --git a/cpp/src/Ice/TcpEndpointI.cpp b/cpp/src/Ice/TcpEndpointI.cpp index 073ece450a4..0cab29774ad 100644 --- a/cpp/src/Ice/TcpEndpointI.cpp +++ b/cpp/src/Ice/TcpEndpointI.cpp @@ -292,13 +292,13 @@ IceInternal::TcpEndpointI::transceiver(EndpointIPtr& endp) const vector<ConnectorPtr> IceInternal::TcpEndpointI::connectors() const { - vector<ConnectorPtr> connectors; - vector<struct sockaddr_in> addresses = getAddresses(_host, _port); - for(unsigned int i = 0; i < addresses.size(); ++i) - { - connectors.push_back(new TcpConnector(_instance, addresses[i], _timeout, _connectionId)); - } - return connectors; + return connectors(getAddresses(_host, _port)); +} + +void +IceInternal::TcpEndpointI::connectors_async(const EndpointI_connectorsPtr& callback) const +{ + _instance->endpointHostResolver()->resolve(_host, _port, const_cast<TcpEndpointI*>(this), callback); } AcceptorPtr @@ -333,14 +333,14 @@ IceInternal::TcpEndpointI::expand() const } bool -IceInternal::TcpEndpointI::equivalent(const ConnectorPtr& connector) const +IceInternal::TcpEndpointI::equivalent(const EndpointIPtr& endpoint) const { - const TcpConnector* tcpConnector = dynamic_cast<const TcpConnector*>(connector.get()); - if(!tcpConnector) + const TcpEndpointI* tcpEndpointI = dynamic_cast<const TcpEndpointI*>(endpoint.get()); + if(!tcpEndpointI) { return false; } - return tcpConnector->equivalent(_host, _port); + return tcpEndpointI->_host == _host && tcpEndpointI->_port == _port; } bool @@ -453,6 +453,17 @@ IceInternal::TcpEndpointI::operator<(const EndpointI& r) const return false; } +vector<ConnectorPtr> +IceInternal::TcpEndpointI::connectors(const vector<struct sockaddr_in>& addresses) const +{ + vector<ConnectorPtr> connectors; + for(unsigned int i = 0; i < addresses.size(); ++i) + { + connectors.push_back(new TcpConnector(_instance, addresses[i], _timeout, _connectionId)); + } + return connectors; +} + IceInternal::TcpEndpointFactory::TcpEndpointFactory(const InstancePtr& instance) : _instance(instance) { diff --git a/cpp/src/Ice/TcpEndpointI.h b/cpp/src/Ice/TcpEndpointI.h index 7ea83d790d9..361d7150de8 100644 --- a/cpp/src/Ice/TcpEndpointI.h +++ b/cpp/src/Ice/TcpEndpointI.h @@ -39,9 +39,10 @@ public: virtual bool unknown() const; virtual TransceiverPtr transceiver(EndpointIPtr&) const; virtual std::vector<ConnectorPtr> connectors() const; + virtual void connectors_async(const EndpointI_connectorsPtr&) const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand() const; - virtual bool equivalent(const ConnectorPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; virtual bool operator==(const EndpointI&) const; virtual bool operator!=(const EndpointI&) const; @@ -49,6 +50,8 @@ public: private: + virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const; + #if defined(__SUNPRO_CC) // // COMPILERFIX: prevent the compiler from emitting a warning about diff --git a/cpp/src/Ice/TcpTransceiver.cpp b/cpp/src/Ice/TcpTransceiver.cpp index 200778293c6..09f54e846fa 100644 --- a/cpp/src/Ice/TcpTransceiver.cpp +++ b/cpp/src/Ice/TcpTransceiver.cpp @@ -52,6 +52,11 @@ IceInternal::TcpTransceiver::close() void IceInternal::TcpTransceiver::shutdownWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels->network >= 2) { Trace out(_logger, _traceLevels->networkCat); @@ -65,6 +70,11 @@ IceInternal::TcpTransceiver::shutdownWrite() void IceInternal::TcpTransceiver::shutdownReadWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels->network >= 2) { Trace out(_logger, _traceLevels->networkCat); @@ -75,7 +85,7 @@ IceInternal::TcpTransceiver::shutdownReadWrite() shutdownSocketReadWrite(_fd); } -void +bool IceInternal::TcpTransceiver::write(Buffer& buf, int timeout) { // Its impossible for the packetSize to be more than an Int. @@ -118,6 +128,11 @@ IceInternal::TcpTransceiver::write(Buffer& buf, int timeout) if(wouldBlock()) { + if(timeout == 0) + { + return false; + } + repeatSelect: int rs; @@ -194,9 +209,11 @@ IceInternal::TcpTransceiver::write(Buffer& buf, int timeout) packetSize = static_cast<int>(buf.b.end() - buf.i); } } + + return true; } -void +bool IceInternal::TcpTransceiver::read(Buffer& buf, int timeout) { // Its impossible for the packetSize to be more than an Int. @@ -240,6 +257,11 @@ IceInternal::TcpTransceiver::read(Buffer& buf, int timeout) if(wouldBlock()) { + if(timeout == 0) + { + return false; + } + repeatSelect: int rs; @@ -324,6 +346,8 @@ IceInternal::TcpTransceiver::read(Buffer& buf, int timeout) packetSize = static_cast<int>(buf.b.end() - buf.i); } } + + return true; } string @@ -338,9 +362,27 @@ IceInternal::TcpTransceiver::toString() const return _desc; } -void -IceInternal::TcpTransceiver::initialize(int) +SocketStatus +IceInternal::TcpTransceiver::initialize(int timeout) { + if(_state == StateNeedConnect && timeout == 0) + { + _state = StateConnectPending; + return NeedConnect; + } + else if(_state <= StateConnectPending) + { + doFinishConnect(_fd, timeout); + _state = StateConnected; + _desc = fdToString(_fd); + if(_traceLevels->network >= 1) + { + Trace out(_logger, _traceLevels->networkCat); + out << "tcp connection established\n" << _desc; + } + } + assert(_state == StateConnected); + return Finished; } void @@ -352,12 +394,13 @@ IceInternal::TcpTransceiver::checkSendSize(const Buffer& buf, size_t messageSize } } -IceInternal::TcpTransceiver::TcpTransceiver(const InstancePtr& instance, SOCKET fd) : +IceInternal::TcpTransceiver::TcpTransceiver(const InstancePtr& instance, SOCKET fd, bool connected) : _traceLevels(instance->traceLevels()), _logger(instance->initializationData().logger), _stats(instance->initializationData().stats), _fd(fd), - _desc(fdToString(fd)) + _state(connected ? StateConnected : StateNeedConnect), + _desc(fdToString(_fd)) { FD_ZERO(&_rFdSet); FD_ZERO(&_wFdSet); diff --git a/cpp/src/Ice/TcpTransceiver.h b/cpp/src/Ice/TcpTransceiver.h index fe4f78d1724..e86464df408 100644 --- a/cpp/src/Ice/TcpTransceiver.h +++ b/cpp/src/Ice/TcpTransceiver.h @@ -24,22 +24,29 @@ class TcpAcceptor; class TcpTransceiver : public Transceiver { + enum State + { + StateNeedConnect, + StateConnectPending, + StateConnected + }; + public: virtual SOCKET fd(); virtual void close(); virtual void shutdownWrite(); virtual void shutdownReadWrite(); - virtual void write(Buffer&, int); - virtual void read(Buffer&, int); + virtual bool write(Buffer&, int); + virtual bool read(Buffer&, int); virtual std::string type() const; virtual std::string toString() const; - virtual void initialize(int); + virtual SocketStatus initialize(int); virtual void checkSendSize(const Buffer&, size_t); private: - TcpTransceiver(const InstancePtr&, SOCKET); + TcpTransceiver(const InstancePtr&, SOCKET, bool); virtual ~TcpTransceiver(); friend class TcpConnector; friend class TcpAcceptor; @@ -51,8 +58,8 @@ private: SOCKET _fd; fd_set _rFdSet; fd_set _wFdSet; - - const std::string _desc; + State _state; + std::string _desc; #ifdef _WIN32 int _maxPacketSize; #endif diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp index 9d2cd3bff6a..3f192fe2e7e 100644 --- a/cpp/src/Ice/ThreadPool.cpp +++ b/cpp/src/Ice/ThreadPool.cpp @@ -29,8 +29,7 @@ IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& p _instance(instance), _destroyed(false), _prefix(prefix), - _lastFd(INVALID_SOCKET), - _timeout(timeout), + _selector(instance, timeout), _size(0), _sizeMax(0), _sizeWarn(0), @@ -41,59 +40,6 @@ IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& p _promote(true), _warnUdp(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Datagrams") > 0) { - SOCKET fds[2]; - createPipe(fds); - _fdIntrRead = fds[0]; - _fdIntrWrite = fds[1]; - setBlock(_fdIntrRead, false); - _maxFd = _fdIntrRead; - _minFd = _fdIntrRead; - -#if defined(_WIN32) - _fdsInUse = 1; // _fdIntrRead is always in use. - FD_ZERO(&_fdSet); - FD_SET(_fdIntrRead, &_fdSet); -#elif defined(ICE_USE_EPOLL) - _epollFd = epoll_create(1); - if(_epollFd < 0) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - _events.resize(1); - struct epoll_event event; - event.events = EPOLLIN; - event.data.fd = _fdIntrRead; - if(epoll_ctl(_epollFd, EPOLL_CTL_ADD, _fdIntrRead, &event) != 0) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } -#elif defined(__APPLE__) - _kqueueFd = kqueue(); - if(_kqueueFd < 0) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - _events.resize(1); - struct kevent event; - EV_SET(&event, _fdIntrRead, EVFILT_READ, EV_ADD, 0, 0, 0); - if(kevent(_kqueueFd, &event, 1, 0, 0, 0) < 0) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } -#else - _pollFdSet.resize(1); - _pollFdSet[0].fd = _fdIntrRead; - _pollFdSet[0].events = POLLIN; -#endif - // // We use just one thread as the default. This is the fastest // possible setting, still allows one level of nesting, and @@ -172,48 +118,6 @@ IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& p IceInternal::ThreadPool::~ThreadPool() { assert(_destroyed); - - try - { - closeSocket(_fdIntrWrite); - } - catch(const LocalException& ex) - { - Error out(_instance->initializationData().logger); - out << "exception in `" << _prefix << "' while calling closeSocket():\n" << ex; - } - - try - { - closeSocket(_fdIntrRead); - } - catch(const LocalException& ex) - { - Error out(_instance->initializationData().logger); - out << "exception in `" << _prefix << "' while calling closeSocket():\n" << ex; - } - -#if defined(ICE_USE_EPOLL) - try - { - closeSocket(_epollFd); - } - catch(const LocalException& ex) - { - Error out(_instance->initializationData().logger); - out << "exception in `" << _prefix << "' while calling closeSocket():\n" << ex; - } -#elif defined(__APPLE__) - try - { - closeSocket(_kqueueFd); - } - catch(const LocalException& ex) - { - Error out(_instance->initializationData().logger); - out << "exception in `" << _prefix << "' while calling closeSocket():\n" << ex; - } -#endif } void @@ -223,8 +127,9 @@ IceInternal::ThreadPool::destroy() assert(!_destroyed); assert(_handlerMap.empty()); assert(_changes.empty()); + assert(_workItems.empty()); _destroyed = true; - setInterrupt(); + _selector.setInterrupt(); } void @@ -234,20 +139,7 @@ IceInternal::ThreadPool::incFdsInUse() // that doesn't have a specific FD limit. #ifdef _WIN32 IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - assert(!_destroyed); - if(_fdsInUse + 1 > FD_SETSIZE) - { - Warning warn(_instance->initializationData().logger); - warn << "maximum number of connections exceeded"; - - // - // No appropriate errno. - // - SocketException ex(__FILE__, __LINE__); - ex.error = 0; - throw ex; - } - ++_fdsInUse; + _selector.incFdsInUse(); #endif } @@ -258,14 +150,7 @@ IceInternal::ThreadPool::decFdsInUse() // that doesn't have a specific FD limit. #ifdef _WIN32 IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); - assert(!_destroyed); - if(_fdsInUse <= 1) - { - Trace trace(_instance->initializationData().logger, "ThreadPool"); - trace << _prefix << ": about to assert"; - } - assert(_fdsInUse > 1); // _fdIntrRead is always in use. - --_fdsInUse; + _selector.decFdsInUse(); #endif } @@ -275,7 +160,7 @@ IceInternal::ThreadPool::_register(SOCKET fd, const EventHandlerPtr& handler) IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); assert(!_destroyed); _changes.push_back(make_pair(fd, handler)); - setInterrupt(); + _selector.setInterrupt(); } void @@ -284,7 +169,16 @@ IceInternal::ThreadPool::unregister(SOCKET fd) IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); assert(!_destroyed); _changes.push_back(make_pair(fd, EventHandlerPtr(0))); - setInterrupt(); + _selector.setInterrupt(); +} + +void +IceInternal::ThreadPool::execute(const ThreadPoolWorkItemPtr& workItem) +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_destroyed); + _workItems.push_back(workItem); + _selector.setInterrupt(); } void @@ -352,74 +246,6 @@ IceInternal::ThreadPool::prefix() const return _prefix; } -void -IceInternal::ThreadPool::clearInterrupt() -{ - char c; - -repeat: - -#ifdef _WIN32 - if(::recv(_fdIntrRead, &c, 1, 0) == SOCKET_ERROR) - { - if(interrupted()) - { - goto repeat; - } - - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } -#else - if(::read(_fdIntrRead, &c, 1) == -1) - { - if(interrupted()) - { - goto repeat; - } - - SyscallException ex(__FILE__, __LINE__); - ex.error = getSystemErrno(); - throw ex; - } -#endif -} - -void -IceInternal::ThreadPool::setInterrupt() -{ - char c = 0; - -repeat: - -#ifdef _WIN32 - if(::send(_fdIntrWrite, &c, 1, 0) == SOCKET_ERROR) - { - if(interrupted()) - { - goto repeat; - } - - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } -#else - if(::write(_fdIntrWrite, &c, 1) == -1) - { - if(interrupted()) - { - goto repeat; - } - - SyscallException ex(__FILE__, __LINE__); - ex.error = getSystemErrno(); - throw ex; - } -#endif -} - bool IceInternal::ThreadPool::run() { @@ -440,54 +266,19 @@ IceInternal::ThreadPool::run() while(true) { int ret; -#if defined(_WIN32) - fd_set fdSet; - memcpy(&fdSet, &_fdSet, sizeof(fd_set)); - if(_timeout > 0) - { - struct timeval tv; - tv.tv_sec = _timeout; - tv.tv_usec = 0; - ret = ::select(static_cast<int>(_maxFd + 1), &fdSet, 0, 0, &tv); - } - else - { - ret = ::select(static_cast<int>(_maxFd + 1), &fdSet, 0, 0, 0); - } -#elif defined(ICE_USE_EPOLL) - ret = epoll_wait(_epollFd, &_events[0], _events.size(), _timeout > 0 ? _timeout * 1000 : -1); -#elif defined(__APPLE__) - if(_timeout > 0) + try { - struct timespec ts; - ts.tv_sec = _timeout; - ts.tv_nsec = 0; - ret = kevent(_kqueueFd, 0, 0, &_events[0], _events.size(), &ts); + ret = _selector.select(); } - else + catch(const Ice::LocalException& ex) { - ret = kevent(_kqueueFd, 0, 0, &_events[0], _events.size(), 0); - } -#else - ret = poll(&_pollFdSet[0], _pollFdSet.size(), _timeout > 0 ? _timeout * 1000 : -1); -#endif - - if(ret == SOCKET_ERROR) - { - if(interrupted()) - { - continue; - } - - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - //throw ex; Error out(_instance->initializationData().logger); out << "exception in `" << _prefix << "':\n" << ex; continue; } - + EventHandlerPtr handler; + ThreadPoolWorkItemPtr workItem; bool finished = false; bool shutdown = false; @@ -496,38 +287,11 @@ IceInternal::ThreadPool::run() if(ret == 0) // We initiate a shutdown if there is a thread pool timeout. { - assert(_timeout > 0); - _timeout = 0; shutdown = true; } else { - bool interrupted = false; -#if defined(_WIN32) - interrupted = FD_ISSET(_fdIntrRead, &fdSet); -#elif defined(ICE_USE_EPOLL) - for(int i = 0; i < ret; ++i) - { - if(_events[i].data.fd == _fdIntrRead) - { - interrupted = true; - break; - } - } -#elif defined(__APPLE__) - for(int i = 0; i < ret; ++i) - { - if(_events[i].ident == static_cast<unsigned int>(_fdIntrRead)) - { - interrupted = true; - break; - } - } -#else - assert(_pollFdSet[0].fd == _fdIntrRead); - interrupted = _pollFdSet[0].revents != 0; -#endif - if(interrupted) + if(_selector.isInterrupted()) { // // There are two possiblities for an interrupt: @@ -536,7 +300,9 @@ IceInternal::ThreadPool::run() // // 2. An event handler was registered or unregistered. // - + // 3. A work item has been schedulded. + // + // // Thread pool destroyed? // @@ -549,169 +315,52 @@ IceInternal::ThreadPool::run() return true; } - clearInterrupt(); + _selector.clearInterrupt(); // // An event handler must have been registered or // unregistered. // - assert(!_changes.empty()); - pair<SOCKET, EventHandlerPtr> change = _changes.front(); - _changes.pop_front(); - - if(change.second) // Addition if handler is set. + if(_changes.empty()) { - _handlerMap.insert(change); -#if defined(_WIN32) - FD_SET(change.first, &_fdSet); -#elif defined(ICE_USE_EPOLL) - epoll_event event; - event.events = EPOLLIN; - event.data.fd = change.first; - if(epoll_ctl(_epollFd, EPOLL_CTL_ADD, change.first, &event) != 0) - { - Error out(_instance->initializationData().logger); - out << "error while adding filedescriptor to epoll set:\n"; - out << errorToString(getSocketErrno()); - continue; - } - _events.resize(_handlerMap.size() + 1); -#elif defined(__APPLE__) - struct kevent event; - EV_SET(&event, change.first, EVFILT_READ, EV_ADD, 0, 0, 0); - if(kevent(_kqueueFd, &event, 1, 0, 0, 0) < 0) - { - Error out(_instance->initializationData().logger); - out << "error while adding filedescriptor to kqueue:\n"; - out << errorToString(getSocketErrno()); - continue; - } - _events.resize(_handlerMap.size() + 1); -#else - struct pollfd pollFd; - pollFd.fd = change.first; - pollFd.events = POLLIN; - _pollFdSet.push_back(pollFd); -#endif - _maxFd = max(_maxFd, change.first); - _minFd = min(_minFd, change.first); - continue; + assert(!_workItems.empty()); + workItem = _workItems.front(); + _workItems.pop_front(); } - else // Removal if handler is not set. + else { - map<SOCKET, EventHandlerPtr>::iterator p = _handlerMap.find(change.first); - assert(p != _handlerMap.end()); - handler = p->second; - finished = true; - _handlerMap.erase(p); -#if defined(_WIN32) - FD_CLR(change.first, &_fdSet); -#elif defined(ICE_USE_EPOLL) - epoll_event event; - event.events = 0; - if(epoll_ctl(_epollFd, EPOLL_CTL_DEL, change.first, &event) != 0) + assert(!_changes.empty()); + pair<SOCKET, EventHandlerPtr> change = _changes.front(); + _changes.pop_front(); + + if(change.second) // Addition if handler is set. { - Error out(_instance->initializationData().logger); - out << "error while adding filedescriptor from epoll set:\n"; - out << errorToString(getSocketErrno()); + _handlerMap.insert(change); + _selector.add(change.first, NeedRead); continue; } - _events.resize(_handlerMap.size() + 1); -#elif defined(__APPLE__) - struct kevent event; - EV_SET(&event, change.first, EVFILT_READ, EV_DELETE, 0, 0, 0); - if(kevent(_kqueueFd, &event, 1, 0, 0, 0) < 0) - { - Error out(_instance->initializationData().logger); - out << "error while removing filedescriptor from kqueue:\n"; - out << errorToString(getSocketErrno()); - continue; - } - _events.resize(_handlerMap.size() + 1); -#else - for(vector<struct pollfd>::iterator p = _pollFdSet.begin(); p != _pollFdSet.end(); ++p) - { - if(p->fd == change.first) - { - _pollFdSet.erase(p); - break; - } - } -#endif - _maxFd = _fdIntrRead; - _minFd = _fdIntrRead; - if(!_handlerMap.empty()) + else // Removal if handler is not set. { - _maxFd = max(_maxFd, (--_handlerMap.end())->first); - _minFd = min(_minFd, _handlerMap.begin()->first); + map<SOCKET, EventHandlerPtr>::iterator p = _handlerMap.find(change.first); + assert(p != _handlerMap.end()); + handler = p->second; + finished = true; + _handlerMap.erase(p); + _selector.remove(change.first, NeedRead); + // Don't continue; we have to call + // finished() on the event handler below, outside + // the thread synchronization. } - // Don't continue; we have to call - // finished() on the event handler below, outside - // the thread synchronization. } } else { - // - // Round robin for the filedescriptors. - // - SOCKET largerFd = _maxFd + 1; - SOCKET smallestFd = _maxFd + 1; -#if defined(_WIN32) - if(fdSet.fd_count == 0) - { - Error out(_instance->initializationData().logger); - out << "select() in `" << _prefix << "' returned " << ret - << " but no filedescriptor is readable"; - continue; - } - for(u_short i = 0; i < fdSet.fd_count; ++i) - { - SOCKET fd = fdSet.fd_array[i]; -#elif defined(ICE_USE_EPOLL) - for(int i = 0; i < ret; ++i) - { - SOCKET fd = _events[i].data.fd; -#elif defined(__APPLE__) - for(int i = 0; i < ret; ++i) - { - SOCKET fd = _events[i].ident; -#else - for(vector<struct pollfd>::const_iterator p = _pollFdSet.begin(); p != _pollFdSet.end(); ++p) - { - if(p->revents == 0) - { - continue; - } - SOCKET fd = p->fd; -#endif - assert(fd != INVALID_SOCKET); - if(fd > _lastFd || _lastFd == INVALID_SOCKET) - { - largerFd = min(largerFd, fd); - } - - smallestFd = min(smallestFd, fd); - } -#ifdef never // To match ICE_USE_EPOLL __APPLE - }}} -#endif - if(largerFd <= _maxFd) - { - assert(largerFd >= _minFd); - _lastFd = largerFd; - } - else - { - assert(smallestFd >= _minFd && smallestFd <= _maxFd); - _lastFd = smallestFd; - } - assert(_lastFd != _fdIntrRead); - map<SOCKET, EventHandlerPtr>::iterator p = _handlerMap.find(_lastFd); + SOCKET fd = _selector.getNextSelected(); + map<SOCKET, EventHandlerPtr>::iterator p = _handlerMap.find(fd); if(p == _handlerMap.end()) { Error out(_instance->initializationData().logger); - out << "filedescriptor " << _lastFd << " not registered with `" << _prefix << "'"; + out << "filedescriptor " << fd << " not registered with `" << _prefix << "'"; continue; } @@ -747,6 +396,29 @@ IceInternal::ThreadPool::run() // promoteFollower(). // } + else if(workItem) + { + try + { + // + // "self" is faster than "this", as the reference + // count is not modified. + // + workItem->execute(self); + } + catch(const LocalException& ex) + { + Error out(_instance->initializationData().logger); + out << "exception in `" << _prefix << "' while calling execute():\n" << ex; + } + + // + // No "continue", because we want execute() to be + // called in its own thread from this pool. Note that + // this means that execute() must call + // promoteFollower(). + // + } else { assert(handler); @@ -790,10 +462,14 @@ IceInternal::ThreadPool::run() { try { - read(handler); + if(!read(handler)) + { + continue; // Can't read without blocking. + } } - catch(const TimeoutException&) // Expected. + catch(const TimeoutException&) { + assert(false); // This shouldn't occur as we only perform non-blocking reads. continue; } catch(const DatagramLimitException&) // Expected. @@ -809,8 +485,7 @@ IceInternal::ThreadPool::run() { if(handler->datagram()) { - if(_instance->initializationData().properties-> - getPropertyAsInt("Ice.Warn.Connections") > 0) + if(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Connections") > 0) { Warning out(_instance->initializationData().logger); out << "datagram connection exception:\n" << ex << '\n' << handler->toString(); @@ -939,7 +614,7 @@ IceInternal::ThreadPool::run() } } -void +bool IceInternal::ThreadPool::read(const EventHandlerPtr& handler) { BasicStream& stream = handler->_stream; @@ -952,7 +627,10 @@ IceInternal::ThreadPool::read(const EventHandlerPtr& handler) if(stream.i != stream.b.end()) { - handler->read(stream); + if(!handler->read(stream)) + { + return false; + } assert(stream.i == stream.b.end()); } @@ -1036,10 +714,15 @@ IceInternal::ThreadPool::read(const EventHandlerPtr& handler) } else { - handler->read(stream); + if(!handler->read(stream)) + { + return false; + } assert(stream.i == stream.b.end()); } } + + return true; } IceInternal::ThreadPool::EventHandlerThread::EventHandlerThread(const ThreadPoolPtr& pool) : diff --git a/cpp/src/Ice/ThreadPool.h b/cpp/src/Ice/ThreadPool.h index 7f7aae48e19..9e520d60ec9 100644 --- a/cpp/src/Ice/ThreadPool.h +++ b/cpp/src/Ice/ThreadPool.h @@ -15,31 +15,15 @@ #include <IceUtil/Monitor.h> #include <IceUtil/Thread.h> +#include <Ice/Config.h> #include <Ice/ThreadPoolF.h> #include <Ice/InstanceF.h> #include <Ice/LoggerF.h> #include <Ice/PropertiesF.h> #include <Ice/EventHandlerF.h> +#include <Ice/Selector.h> #include <list> -#if defined(__linux) && !defined(ICE_NO_EPOLL) -# define ICE_USE_EPOLL 1 -#endif - -#if defined(_WIN32) -# include <winsock2.h> -#else -# define SOCKET int -# if defined(ICE_USE_EPOLL) -# include <sys/epoll.h> -# elif defined(__APPLE__) -# include <sys/event.h> -# else -# include <sys/poll.h> -# endif -#endif - - namespace IceInternal { @@ -59,6 +43,7 @@ public: void _register(SOCKET, const EventHandlerPtr&); void unregister(SOCKET); + void execute(const ThreadPoolWorkItemPtr&); void promoteFollower(); void joinWithAllThreads(); @@ -66,40 +51,19 @@ public: private: - void clearInterrupt(); - void setInterrupt(); - bool run(); // Returns true if a follower should be promoted. - void read(const EventHandlerPtr&); + bool read(const EventHandlerPtr&); InstancePtr _instance; bool _destroyed; const std::string _prefix; - SOCKET _maxFd; - SOCKET _minFd; - SOCKET _lastFd; - SOCKET _fdIntrRead; - SOCKET _fdIntrWrite; -#if defined(_WIN32) - fd_set _fdSet; - int _fdsInUse; -#elif defined(ICE_USE_EPOLL) - int _epollFd; - std::vector<struct epoll_event> _events; -#elif defined(__APPLE__) - int _kqueueFd; - std::vector<struct kevent> _events; -#else - std::vector<struct pollfd> _pollFdSet; -#endif + Selector _selector; std::list<std::pair<SOCKET, EventHandlerPtr> > _changes; // Event handler set for addition; null for removal. - + std::list<ThreadPoolWorkItemPtr> _workItems; std::map<SOCKET, EventHandlerPtr> _handlerMap; - int _timeout; - class EventHandlerThread : public IceUtil::Thread { public: diff --git a/cpp/src/Ice/TraceUtil.cpp b/cpp/src/Ice/TraceUtil.cpp index cb371f4e35a..b8c4d1f10b1 100644 --- a/cpp/src/Ice/TraceUtil.cpp +++ b/cpp/src/Ice/TraceUtil.cpp @@ -44,6 +44,26 @@ printIdentityFacetOperation(ostream& s, BasicStream& stream) s << "\noperation = " << operation; } +static string +getMessageTypeAsString(Byte type) +{ + switch(type) + { + case requestMsg: + return "request"; + case requestBatchMsg: + return "batch request"; + case replyMsg: + return "reply"; + case closeConnectionMsg: + return "close connection"; + case validateConnectionMsg: + return "validate connection"; + default: + return "unknown"; + } +} + static void printRequestHeader(ostream& s, BasicStream& stream) { @@ -95,7 +115,7 @@ printRequestHeader(ostream& s, BasicStream& stream) } } -static void +static Byte printHeader(ostream& s, BasicStream& stream) { Byte magicNumber; @@ -120,105 +140,238 @@ printHeader(ostream& s, BasicStream& stream) Byte type; stream.read(type); - s << "\nmessage type = " << static_cast<int>(type) << ' '; + s << "\nmessage type = " << static_cast<int>(type) << " (" << getMessageTypeAsString(type) << ')'; - switch(type) + Byte compress; + stream.read(compress); + s << "\ncompression status = " << static_cast<int>(compress) << ' '; + + switch(compress) { - case requestMsg: + case 0: { - s << "(request)"; + s << "(not compressed; do not compress response, if any)"; break; } - case requestBatchMsg: + case 1: { - s << "(batch request)"; + s << "(not compressed; compress response, if any)"; break; } - case replyMsg: + case 2: { - s << "(reply)"; + s << "(compressed; compress response, if any)"; break; } - case closeConnectionMsg: + default: { - s << "(close connection)"; + s << "(unknown)"; break; } + } - case validateConnectionMsg: + Int size; + stream.read(size); + s << "\nmessage size = " << size; + + return type; +} + +static void +printRequest(ostream& s, BasicStream& stream) +{ + Int requestId; + stream.read(requestId); + s << "\nrequest id = " << requestId; + if(requestId == 0) + { + s << " (oneway)"; + } + + printRequestHeader(s, stream); +} + +static void +printBatchRequest(ostream& s, BasicStream& stream) +{ + int batchRequestNum; + stream.read(batchRequestNum); + s << "\nnumber of requests = " << batchRequestNum; + + for(int i = 0; i < batchRequestNum; ++i) + { + s << "\nrequest #" << i << ':'; + printRequestHeader(s, stream); + stream.skipEncaps(); + } +} + +static void +printReply(ostream& s, BasicStream& stream) +{ + Int requestId; + stream.read(requestId); + s << "\nrequest id = " << requestId; + + Byte replyStatus; + stream.read(replyStatus); + s << "\nreply status = " << static_cast<int>(replyStatus) << ' '; + switch(replyStatus) + { + case replyOK: + { + s << "(ok)"; + break; + } + + case replyUserException: + { + s << "(user exception)"; + break; + } + + case replyObjectNotExist: + case replyFacetNotExist: + case replyOperationNotExist: + { + switch(replyStatus) + { + case replyObjectNotExist: + { + s << "(object not exist)"; + break; + } + + case replyFacetNotExist: + { + s << "(facet not exist)"; + break; + } + + case replyOperationNotExist: { - s << "(validate connection)"; + s << "(operation not exist)"; break; } default: { - s << "(unknown)"; + assert(false); break; } - } + } - Byte compress; - stream.read(compress); - s << "\ncompression status = " << static_cast<int>(compress) << ' '; + printIdentityFacetOperation(s, stream); + break; + } - switch(compress) + case replyUnknownException: + case replyUnknownLocalException: + case replyUnknownUserException: { - case 0: + switch(replyStatus) { - s << "(not compressed; do not compress response, if any)"; + case replyUnknownException: + { + s << "(unknown exception)"; break; } - case 1: + case replyUnknownLocalException: { - s << "(not compressed; compress response, if any)"; + s << "(unknown local exception)"; break; } - case 2: + case replyUnknownUserException: { - s << "(compressed; compress response, if any)"; + s << "(unknown user exception)"; break; } default: { - s << "(unknown)"; + assert(false); break; } + } + + string unknown; + stream.read(unknown, false); + s << "\nunknown = " << unknown; + break; } - Int size; - stream.read(size); - s << "\nmessage size = " << size; + default: + { + s << "(unknown)"; + break; + } + } } -void -IceInternal::traceHeader(const char* heading, const BasicStream& str, const LoggerPtr& logger, - const TraceLevelsPtr& tl) +static Byte +printMessage(ostream& s, BasicStream& stream) { - if(tl->protocol >= 1) + Byte type = printHeader(s, stream); + + switch(type) { - BasicStream& stream = const_cast<BasicStream&>(str); - BasicStream::Container::iterator p = stream.i; - stream.i = stream.b.begin(); + case closeConnectionMsg: + case validateConnectionMsg: + { + // We're done. + break; + } + + case requestMsg: + { + printRequest(s, stream); + break; + } + + case requestBatchMsg: + { + printBatchRequest(s, stream); + break; + } + + case replyMsg: + { + printReply(s, stream); + break; + } + + default: + { + break; + } + } - ostringstream s; - s << heading; - printHeader(s, stream); + return type; +} - logger->trace(tl->protocolCat, s.str()); - stream.i = p; +static IceUtil::StaticMutex slicingMutex = ICE_STATIC_MUTEX_INITIALIZER; + +void +IceInternal::traceSlicing(const char* kind, const string& typeId, const char* slicingCat, const LoggerPtr& logger) +{ + IceUtil::StaticMutex::Lock lock(slicingMutex); + static set<string> slicingIds; + if(slicingIds.insert(typeId).second) + { + string s("unknown "); + s += kind; + s += " type `" + typeId + "'"; + logger->trace(slicingCat, s); } } void -IceInternal::traceRequest(const char* heading, const BasicStream& str, const LoggerPtr& logger, - const TraceLevelsPtr& tl) +IceInternal::traceSend(const BasicStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) { if(tl->protocol >= 1) { @@ -227,27 +380,15 @@ IceInternal::traceRequest(const char* heading, const BasicStream& str, const Log stream.i = stream.b.begin(); ostringstream s; - s << heading; - printHeader(s, stream); + Byte type = printMessage(s, stream); - Int requestId; - stream.read(requestId); - s << "\nrequest id = " << requestId; - if(requestId == 0) - { - s << " (oneway)"; - } - - printRequestHeader(s, stream); - - logger->trace(tl->protocolCat, s.str()); + logger->trace(tl->protocolCat, "sending " + getMessageTypeAsString(type) + " " + s.str()); stream.i = p; } } void -IceInternal::traceBatchRequest(const char* heading, const BasicStream& str, const LoggerPtr& logger, - const TraceLevelsPtr& tl) +IceInternal::traceRecv(const BasicStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) { if(tl->protocol >= 1) { @@ -256,28 +397,15 @@ IceInternal::traceBatchRequest(const char* heading, const BasicStream& str, cons stream.i = stream.b.begin(); ostringstream s; - s << heading; - printHeader(s, stream); + Byte type = printMessage(s, stream); - int batchRequestNum; - stream.read(batchRequestNum); - s << "\nnumber of requests = " << batchRequestNum; - - for(int i = 0; i < batchRequestNum; ++i) - { - s << "\nrequest #" << i << ':'; - printRequestHeader(s, stream); - stream.skipEncaps(); - } - - logger->trace(tl->protocolCat, s.str()); + logger->trace(tl->protocolCat, "received " + getMessageTypeAsString(type) + " " + s.str()); stream.i = p; } } void -IceInternal::traceReply(const char* heading, const BasicStream& str, const LoggerPtr& logger, - const TraceLevelsPtr& tl) +IceInternal::trace(const char* heading, const BasicStream& str, const LoggerPtr& logger, const TraceLevelsPtr& tl) { if(tl->protocol >= 1) { @@ -287,125 +415,10 @@ IceInternal::traceReply(const char* heading, const BasicStream& str, const Logge ostringstream s; s << heading; - printHeader(s, stream); - - Int requestId; - stream.read(requestId); - s << "\nrequest id = " << requestId; - - Byte replyStatus; - stream.read(replyStatus); - s << "\nreply status = " << static_cast<int>(replyStatus) << ' '; - switch(replyStatus) - { - case replyOK: - { - s << "(ok)"; - break; - } - - case replyUserException: - { - s << "(user exception)"; - break; - } - - case replyObjectNotExist: - case replyFacetNotExist: - case replyOperationNotExist: - { - switch(replyStatus) - { - case replyObjectNotExist: - { - s << "(object not exist)"; - break; - } - - case replyFacetNotExist: - { - s << "(facet not exist)"; - break; - } - - case replyOperationNotExist: - { - s << "(operation not exist)"; - break; - } - - default: - { - assert(false); - break; - } - } - - printIdentityFacetOperation(s, stream); - break; - } - - case replyUnknownException: - case replyUnknownLocalException: - case replyUnknownUserException: - { - switch(replyStatus) - { - case replyUnknownException: - { - s << "(unknown exception)"; - break; - } - - case replyUnknownLocalException: - { - s << "(unknown local exception)"; - break; - } - - case replyUnknownUserException: - { - s << "(unknown user exception)"; - break; - } - - default: - { - assert(false); - break; - } - } - - string unknown; - stream.read(unknown, false); - s << "\nunknown = " << unknown; - break; - } - - default: - { - s << "(unknown)"; - break; - } - } + printMessage(s, stream); logger->trace(tl->protocolCat, s.str()); stream.i = p; } } -static IceUtil::StaticMutex slicingMutex = ICE_STATIC_MUTEX_INITIALIZER; - -void -IceInternal::traceSlicing(const char* kind, const string& typeId, const char* slicingCat, const LoggerPtr& logger) -{ - IceUtil::StaticMutex::Lock lock(slicingMutex); - static set<string> slicingIds; - if(slicingIds.insert(typeId).second) - { - string s("unknown "); - s += kind; - s += " type `" + typeId + "'"; - logger->trace(slicingCat, s); - } -} diff --git a/cpp/src/Ice/TraceUtil.h b/cpp/src/Ice/TraceUtil.h index d61af61e1eb..01db5958af0 100644 --- a/cpp/src/Ice/TraceUtil.h +++ b/cpp/src/Ice/TraceUtil.h @@ -18,10 +18,9 @@ namespace IceInternal class BasicStream; -void traceHeader(const char*, const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); -void traceRequest(const char*, const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); -void traceBatchRequest(const char*, const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); -void traceReply(const char*, const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void traceSend(const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void traceRecv(const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); +void trace(const char*, const BasicStream&, const ::Ice::LoggerPtr&, const TraceLevelsPtr&); void traceSlicing(const char*, const ::std::string&, const char *, const ::Ice::LoggerPtr&); } diff --git a/cpp/src/Ice/Transceiver.h b/cpp/src/Ice/Transceiver.h index 1e3d637c9f0..8670779213d 100644 --- a/cpp/src/Ice/Transceiver.h +++ b/cpp/src/Ice/Transceiver.h @@ -12,9 +12,10 @@ #include <IceUtil/Shared.h> #include <Ice/TransceiverF.h> +#include <Ice/Selector.h> #ifdef _WIN32 -# include <winsock2.h>
+# include <winsock2.h> typedef int ssize_t; #else # define SOCKET int @@ -33,11 +34,11 @@ public: virtual void close() = 0; virtual void shutdownWrite() = 0; virtual void shutdownReadWrite() = 0; - virtual void write(Buffer&, int) = 0; - virtual void read(Buffer&, int) = 0; + virtual bool write(Buffer&, int) = 0; + virtual bool read(Buffer&, int) = 0; virtual std::string type() const = 0; virtual std::string toString() const = 0; - virtual void initialize(int) = 0; + virtual SocketStatus initialize(int) = 0; virtual void checkSendSize(const Buffer&, size_t) = 0; }; diff --git a/cpp/src/Ice/UdpConnector.cpp b/cpp/src/Ice/UdpConnector.cpp index 128fca83447..05c202a8310 100644 --- a/cpp/src/Ice/UdpConnector.cpp +++ b/cpp/src/Ice/UdpConnector.cpp @@ -168,21 +168,6 @@ IceInternal::UdpConnector::operator<(const Connector& r) const return compareAddress(_addr, p->_addr) == -1; } -bool -IceInternal::UdpConnector::equivalent(const string& host, int port) const -{ - struct sockaddr_in addr; - try - { - getAddress(host, port, addr); - } - catch(const DNSException&) - { - return false; - } - return compareAddress(addr, _addr) == 0; -} - IceInternal::UdpConnector::UdpConnector(const InstancePtr& instance, const struct sockaddr_in& addr, const string& mcastInterface, int mcastTtl, Ice::Byte protocolMajor, Ice::Byte protocolMinor, Ice::Byte encodingMajor, Ice::Byte encodingMinor, diff --git a/cpp/src/Ice/UdpConnector.h b/cpp/src/Ice/UdpConnector.h index fa33c3cb330..77d73bba277 100644 --- a/cpp/src/Ice/UdpConnector.h +++ b/cpp/src/Ice/UdpConnector.h @@ -28,6 +28,7 @@ class UdpConnector : public Connector public: virtual TransceiverPtr connect(int); + virtual Ice::Short type() const; virtual std::string toString() const; @@ -35,8 +36,6 @@ public: virtual bool operator!=(const Connector&) const; virtual bool operator<(const Connector&) const; - bool equivalent(const std::string&, int) const; - private: UdpConnector(const InstancePtr&, const struct sockaddr_in&, const std::string&, int, Ice::Byte, Ice::Byte, diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp index 2668a589142..b5f4588714c 100644 --- a/cpp/src/Ice/UdpEndpointI.cpp +++ b/cpp/src/Ice/UdpEndpointI.cpp @@ -480,14 +480,13 @@ IceInternal::UdpEndpointI::transceiver(EndpointIPtr& endp) const vector<ConnectorPtr> IceInternal::UdpEndpointI::connectors() const { - vector<ConnectorPtr> connectors; - vector<struct sockaddr_in> addresses = getAddresses(_host, _port); - for(unsigned int i = 0; i < addresses.size(); ++i) - { - connectors.push_back(new UdpConnector(_instance, addresses[i], _mcastInterface, _mcastTtl, _protocolMajor, - _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); - } - return connectors; + return connectors(getAddresses(_host, _port)); +} + +void +IceInternal::UdpEndpointI::connectors_async(const EndpointI_connectorsPtr& callback) const +{ + _instance->endpointHostResolver()->resolve(_host, _port, const_cast<UdpEndpointI*>(this), callback); } AcceptorPtr @@ -522,14 +521,14 @@ IceInternal::UdpEndpointI::expand() const } bool -IceInternal::UdpEndpointI::equivalent(const ConnectorPtr& connector) const +IceInternal::UdpEndpointI::equivalent(const EndpointIPtr& endpoint) const { - const UdpConnector* udpConnector = dynamic_cast<const UdpConnector*>(connector.get()); - if(!udpConnector) + const UdpEndpointI* udpEndpointI = dynamic_cast<const UdpEndpointI*>(endpoint.get()); + if(!udpEndpointI) { return false; } - return udpConnector->equivalent(_host, _port); + return udpEndpointI->_host == _host && udpEndpointI->_port == _port; } bool @@ -726,6 +725,18 @@ IceInternal::UdpEndpointI::operator<(const EndpointI& r) const return false; } +vector<ConnectorPtr> +IceInternal::UdpEndpointI::connectors(const vector<struct sockaddr_in>& addresses) const +{ + vector<ConnectorPtr> connectors; + for(unsigned int i = 0; i < addresses.size(); ++i) + { + connectors.push_back(new UdpConnector(_instance, addresses[i], _mcastInterface, _mcastTtl, _protocolMajor, + _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); + } + return connectors; +} + IceInternal::UdpEndpointFactory::UdpEndpointFactory(const InstancePtr& instance) : _instance(instance) { diff --git a/cpp/src/Ice/UdpEndpointI.h b/cpp/src/Ice/UdpEndpointI.h index 80c33c873e2..07fb3daaf2d 100644 --- a/cpp/src/Ice/UdpEndpointI.h +++ b/cpp/src/Ice/UdpEndpointI.h @@ -40,9 +40,10 @@ public: virtual bool unknown() const; virtual TransceiverPtr transceiver(EndpointIPtr&) const; virtual std::vector<ConnectorPtr> connectors() const; + virtual void connectors_async(const EndpointI_connectorsPtr&) const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand() const; - virtual bool equivalent(const ConnectorPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; virtual bool operator==(const EndpointI&) const; virtual bool operator!=(const EndpointI&) const; @@ -50,6 +51,8 @@ public: private: + virtual std::vector<ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const; + #if defined(__SUNPRO_CC) // // COMPILERFIX: prevent the compiler from emitting a warning about diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp index 32ab7600c88..2736587f7a8 100644 --- a/cpp/src/Ice/UdpTransceiver.cpp +++ b/cpp/src/Ice/UdpTransceiver.cpp @@ -63,7 +63,7 @@ IceInternal::UdpTransceiver::shutdownReadWrite() IceUtil::Mutex::Lock sync(_shutdownReadWriteMutex); _shutdownReadWrite = true; -#if defined(_WIN32) || defined(__sun) || defined(__hppa) || defined(_AIX) +#if defined(_WIN32) || defined(__sun) || defined(__hppa) || defined(_AIX) || defined(__APPLE__) // // On certain platforms, we have to explicitly wake up a thread blocked in // select(). This is only relevant when using thread per connection. @@ -105,8 +105,8 @@ IceInternal::UdpTransceiver::shutdownReadWrite() #endif } -void -IceInternal::UdpTransceiver::write(Buffer& buf, int) +bool +IceInternal::UdpTransceiver::write(Buffer& buf, int timeout) { assert(buf.i == buf.b.begin()); // @@ -120,6 +120,7 @@ IceInternal::UdpTransceiver::write(Buffer& buf, int) // // We don't log a warning here because the client gets an exception anyway. // + cerr << packetSize << " " << _maxPacketSize << " " << _sndSize << endl; throw DatagramLimitException(__FILE__, __LINE__); } @@ -127,11 +128,9 @@ repeat: assert(_fd != INVALID_SOCKET); #ifdef _WIN32 - ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), - static_cast<int>(buf.b.size()), 0); + ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), static_cast<int>(buf.b.size()), 0); #else - ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), - buf.b.size(), 0); + ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&buf.b[0]), buf.b.size(), 0); #endif if(ret == SOCKET_ERROR) @@ -145,16 +144,33 @@ repeat: { repeatSelect: + if(timeout == 0) + { + return false; + } + + int rs; assert(_fd != INVALID_SOCKET); #ifdef _WIN32 FD_SET(_fd, &_wFdSet); - int rs = ::select(static_cast<int>(_fd + 1), 0, &_wFdSet, 0, 0); + + if(timeout >= 0) + { + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; + rs = ::select(static_cast<int>(_fd + 1), 0, &_wFdSet, 0, &tv); + } + else + { + rs = ::select(static_cast<int>(_fd + 1), 0, &_wFdSet, 0, 0); + } #else - struct pollfd fdSet[1]; - fdSet[0].fd = _fd; - fdSet[0].events = POLLOUT; - int rs = ::poll(fdSet, 1, -1); -#endif + struct pollfd pollFd[1]; + pollFd[0].fd = _fd; + pollFd[0].events = POLLOUT; + rs = ::poll(pollFd, 1, timeout); +#endif if(rs == SOCKET_ERROR) { if(interrupted()) @@ -166,6 +182,11 @@ repeat: ex.error = getSocketErrno(); throw ex; } + + if(rs == 0) + { + throw new Ice::TimeoutException(__FILE__, __LINE__); + } goto repeat; } @@ -188,10 +209,11 @@ repeat: assert(ret == static_cast<ssize_t>(buf.b.size())); buf.i = buf.b.end(); + return true; } -void -IceInternal::UdpTransceiver::read(Buffer& buf, int) +bool +IceInternal::UdpTransceiver::read(Buffer& buf, int timeout) { assert(buf.i == buf.b.begin()); @@ -270,6 +292,11 @@ repeat: if(wouldBlock()) { + if(timeout == 0) + { + return false; + } + repeatSelect: assert(_fd != INVALID_SOCKET); @@ -295,6 +322,11 @@ repeat: throw ex; } + if(rs == 0) + { + throw TimeoutException(__FILE__, __LINE__); + } + goto repeat; } @@ -328,6 +360,7 @@ repeat: buf.b.resize(ret); buf.i = buf.b.end(); + return true; } string @@ -351,9 +384,10 @@ IceInternal::UdpTransceiver::toString() const } } -void +SocketStatus IceInternal::UdpTransceiver::initialize(int) { + return Finished; } void diff --git a/cpp/src/Ice/UdpTransceiver.h b/cpp/src/Ice/UdpTransceiver.h index 8c4c3282e3d..6fe77182793 100644 --- a/cpp/src/Ice/UdpTransceiver.h +++ b/cpp/src/Ice/UdpTransceiver.h @@ -36,11 +36,11 @@ public: virtual void close(); virtual void shutdownWrite(); virtual void shutdownReadWrite(); - virtual void write(Buffer&, int); - virtual void read(Buffer&, int); + virtual bool write(Buffer&, int); + virtual bool read(Buffer&, int); virtual std::string type() const; virtual std::string toString() const; - virtual void initialize(int); + virtual SocketStatus initialize(int); virtual void checkSendSize(const Buffer&, size_t); int effectivePort() const; diff --git a/cpp/src/Ice/UnknownEndpointI.cpp b/cpp/src/Ice/UnknownEndpointI.cpp index c3f91d7563f..e7762649979 100644 --- a/cpp/src/Ice/UnknownEndpointI.cpp +++ b/cpp/src/Ice/UnknownEndpointI.cpp @@ -213,6 +213,12 @@ IceInternal::UnknownEndpointI::connectors() const return ret; } +void +IceInternal::UnknownEndpointI::connectors_async(const EndpointI_connectorsPtr& callback) const +{ + callback->connectors(vector<ConnectorPtr>()); +} + AcceptorPtr IceInternal::UnknownEndpointI::acceptor(EndpointIPtr& endp, const string&) const { @@ -229,7 +235,7 @@ IceInternal::UnknownEndpointI::expand() const } bool -IceInternal::UnknownEndpointI::equivalent(const ConnectorPtr&) const +IceInternal::UnknownEndpointI::equivalent(const EndpointIPtr&) const { return false; } diff --git a/cpp/src/Ice/UnknownEndpointI.h b/cpp/src/Ice/UnknownEndpointI.h index e9c0069f261..69f33defe0f 100644 --- a/cpp/src/Ice/UnknownEndpointI.h +++ b/cpp/src/Ice/UnknownEndpointI.h @@ -36,9 +36,10 @@ public: virtual bool unknown() const; virtual TransceiverPtr transceiver(EndpointIPtr&) const; virtual std::vector<ConnectorPtr> connectors() const; + virtual void connectors_async(const EndpointI_connectorsPtr&) const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand() const; - virtual bool equivalent(const ConnectorPtr&) const; + virtual bool equivalent(const EndpointIPtr&) const; virtual bool operator==(const EndpointI&) const; virtual bool operator!=(const EndpointI&) const; diff --git a/cpp/src/IceGrid/Allocatable.cpp b/cpp/src/IceGrid/Allocatable.cpp index 402a5cc32d6..899d20562bc 100644 --- a/cpp/src/IceGrid/Allocatable.cpp +++ b/cpp/src/IceGrid/Allocatable.cpp @@ -107,7 +107,7 @@ AllocationRequest::cancel(const AllocationException& ex) } void -AllocationRequest::run() // TimerTask::run() method implementation +AllocationRequest::runTimerTask() // TimerTask::runTimerTask() method implementation { Lock sync(*this); switch(_state) diff --git a/cpp/src/IceGrid/Allocatable.h b/cpp/src/IceGrid/Allocatable.h index f052c89f4d8..3eb1b3e60ee 100644 --- a/cpp/src/IceGrid/Allocatable.h +++ b/cpp/src/IceGrid/Allocatable.h @@ -42,7 +42,7 @@ public: bool pending(); bool allocate(const AllocatablePtr&, const SessionIPtr&); void cancel(const AllocationException&); - void run(); // Implementation of IceUtil::TimerTask::run() + void runTimerTask(); // Implementation of IceUtil::TimerTask::runTimerTask() int getTimeout() const { return _timeout; } const SessionIPtr& getSession() const { return _session; } diff --git a/cpp/src/IceGrid/NodeCache.h b/cpp/src/IceGrid/NodeCache.h index 1e4a1caf584..4ed6dab0399 100644 --- a/cpp/src/IceGrid/NodeCache.h +++ b/cpp/src/IceGrid/NodeCache.h @@ -10,7 +10,7 @@ #ifndef ICE_GRID_NODECACHE_H #define ICE_GRID_NODECACHE_H -#include <IceUtil/Mutex.h> +#include <IceUtil/RecMutex.h> #include <IceUtil/Shared.h> #include <IceGrid/Cache.h> #include <IceGrid/Internal.h> diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp index 71315d1a6c4..507867753d8 100644 --- a/cpp/src/IceGrid/ServerI.cpp +++ b/cpp/src/IceGrid/ServerI.cpp @@ -194,7 +194,7 @@ public: { } - virtual void run() + virtual void runTimerTask() { _command->timeout(); } @@ -214,7 +214,7 @@ public: { } - virtual void run() + virtual void runTimerTask() { try { diff --git a/cpp/src/IceSSL/AcceptorI.cpp b/cpp/src/IceSSL/AcceptorI.cpp index 39d9976f9cb..7f467fee5c0 100644 --- a/cpp/src/IceSSL/AcceptorI.cpp +++ b/cpp/src/IceSSL/AcceptorI.cpp @@ -108,7 +108,7 @@ IceSSL::AcceptorI::accept(int timeout) // SSL handshaking is performed in TransceiverI::initialize, since // accept must not block. // - return new TransceiverI(_instance, ssl, fd, true, _adapterName); + return new TransceiverI(_instance, ssl, fd, true, true, _adapterName); } void diff --git a/cpp/src/IceSSL/ConnectorI.cpp b/cpp/src/IceSSL/ConnectorI.cpp index e1bad76f96b..feb4c4b4e89 100644 --- a/cpp/src/IceSSL/ConnectorI.cpp +++ b/cpp/src/IceSSL/ConnectorI.cpp @@ -43,7 +43,7 @@ IceSSL::ConnectorI::connect(int timeout) SOCKET fd = IceInternal::createSocket(false); IceInternal::setBlock(fd, false); IceInternal::setTcpBufSize(fd, _instance->communicator()->getProperties(), _logger); - IceInternal::doConnect(fd, _addr, timeout); + bool connected = IceInternal::doConnect(fd, _addr, timeout); // This static_cast is necessary due to 64bit windows. There SOCKET is a non-int type. BIO* bio = BIO_new_socket(static_cast<int>(fd), BIO_CLOSE); @@ -65,112 +65,11 @@ IceSSL::ConnectorI::connect(int timeout) } SSL_set_bio(ssl, bio, bio); - try - { - do - { - int result = SSL_connect(ssl); - switch(SSL_get_error(ssl, result)) - { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_ZERO_RETURN: - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } - case SSL_ERROR_WANT_READ: - if(!selectRead(fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - break; - case SSL_ERROR_WANT_WRITE: - if(!selectWrite(fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - break; - case SSL_ERROR_SYSCALL: - { - if(result == -1) - { - if(IceInternal::interrupted()) - { - break; - } - - if(IceInternal::wouldBlock()) - { - if(SSL_want_read(ssl)) - { - if(!selectRead(fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - } - else if(SSL_want_write(ssl)) - { - if(!selectWrite(fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - } - - continue; - } - - if(IceInternal::connectionLost()) - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } - } - - if(result == 0) - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = 0; - throw ex; - } - - SocketException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; - } - case SSL_ERROR_SSL: - { - ProtocolException ex(__FILE__, __LINE__); - ex.reason = "SSL error for new outgoing connection:\nremote address = " + - IceInternal::addrToString(_addr) + "\n" + _instance->sslErrors(); - throw ex; - } - } - } - while(!SSL_is_init_finished(ssl)); - - _instance->verifyPeer(ssl, fd, _host, "", false); - } - catch(...) - { - SSL_free(ssl); - throw; - } - - if(_instance->networkTraceLevel() >= 1) - { - Trace out(_logger, _instance->networkTraceCategory()); - out << "ssl connection established\n" << IceInternal::fdToString(fd); - } - - if(_instance->securityTraceLevel() >= 1) - { - _instance->traceConnection(ssl, false); - } - - return new TransceiverI(_instance, ssl, fd, false); + // + // SSL handshaking is performed in TransceiverI::initialize, since + // connect must not block. + // + return new TransceiverI(_instance, ssl, fd, connected, false); } Short @@ -248,21 +147,6 @@ IceSSL::ConnectorI::operator<(const IceInternal::Connector& r) const return IceInternal::compareAddress(_addr, p->_addr) == -1; } -bool -IceSSL::ConnectorI::equivalent(const string& host, int port) const -{ - struct sockaddr_in addr; - try - { - IceInternal::getAddress(host, port, addr); - } - catch(const DNSException&) - { - return false; - } - return IceInternal::compareAddress(_addr, addr) == 0; -} - IceSSL::ConnectorI::ConnectorI(const InstancePtr& instance, const struct sockaddr_in& addr, Ice::Int timeout, const string& connectionId) : _instance(instance), diff --git a/cpp/src/IceSSL/ConnectorI.h b/cpp/src/IceSSL/ConnectorI.h index d7ae8f88494..72f7a61fb32 100644 --- a/cpp/src/IceSSL/ConnectorI.h +++ b/cpp/src/IceSSL/ConnectorI.h @@ -31,6 +31,7 @@ class ConnectorI : public IceInternal::Connector public: virtual IceInternal::TransceiverPtr connect(int); + virtual Ice::Short type() const; virtual std::string toString() const; @@ -38,8 +39,6 @@ public: virtual bool operator!=(const IceInternal::Connector&) const; virtual bool operator<(const IceInternal::Connector&) const; - bool equivalent(const std::string&, int) const; - private: ConnectorI(const InstancePtr&, const struct sockaddr_in&, Ice::Int, const std::string&); @@ -52,6 +51,7 @@ private: struct sockaddr_in _addr; const Ice::Int _timeout; const std::string _connectionId; + SOCKET _fd; }; } diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp index ca03a133260..fd9edd4f42d 100644 --- a/cpp/src/IceSSL/EndpointI.cpp +++ b/cpp/src/IceSSL/EndpointI.cpp @@ -292,13 +292,13 @@ IceSSL::EndpointI::transceiver(IceInternal::EndpointIPtr& endp) const vector<IceInternal::ConnectorPtr> IceSSL::EndpointI::connectors() const { - vector<IceInternal::ConnectorPtr> connectors; - vector<struct sockaddr_in> addresses = IceInternal::getAddresses(_host, _port); - for(unsigned int i = 0; i < addresses.size(); ++i) - { - connectors.push_back(new ConnectorI(_instance, addresses[i], _timeout, _connectionId)); - } - return connectors; + return connectors(IceInternal::getAddresses(_host, _port)); +} + +void +IceSSL::EndpointI::connectors_async(const IceInternal::EndpointI_connectorsPtr& callback) const +{ + _instance->endpointHostResolver()->resolve(_host, _port, const_cast<EndpointI*>(this), callback); } IceInternal::AcceptorPtr @@ -332,14 +332,14 @@ IceSSL::EndpointI::expand() const } bool -IceSSL::EndpointI::equivalent(const IceInternal::ConnectorPtr& connector) const +IceSSL::EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const { - const ConnectorI* sslConnector = dynamic_cast<const ConnectorI*>(connector.get()); - if(!sslConnector) + const EndpointI* sslEndpointI = dynamic_cast<const EndpointI*>(endpoint.get()); + if(!sslEndpointI) { return false; } - return sslConnector->equivalent(_host, _port); + return sslEndpointI->_host == _host && sslEndpointI->_port == _port; } bool @@ -452,6 +452,17 @@ IceSSL::EndpointI::operator<(const IceInternal::EndpointI& r) const return false; } +vector<IceInternal::ConnectorPtr> +IceSSL::EndpointI::connectors(const vector<struct sockaddr_in>& addresses) const +{ + vector<IceInternal::ConnectorPtr> connectors; + for(unsigned int i = 0; i < addresses.size(); ++i) + { + connectors.push_back(new ConnectorI(_instance, addresses[i], _timeout, _connectionId)); + } + return connectors; +} + IceSSL::EndpointFactoryI::EndpointFactoryI(const InstancePtr& instance) : _instance(instance) { diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h index c5a51375609..99e748e7782 100644 --- a/cpp/src/IceSSL/EndpointI.h +++ b/cpp/src/IceSSL/EndpointI.h @@ -40,9 +40,10 @@ public: virtual bool unknown() const; virtual IceInternal::TransceiverPtr transceiver(IceInternal::EndpointIPtr&) const; virtual std::vector<IceInternal::ConnectorPtr> connectors() const; + virtual void connectors_async(const IceInternal::EndpointI_connectorsPtr&) const; virtual IceInternal::AcceptorPtr acceptor(IceInternal::EndpointIPtr&, const std::string&) const; virtual std::vector<IceInternal::EndpointIPtr> expand() const; - virtual bool equivalent(const IceInternal::ConnectorPtr&) const; + virtual bool equivalent(const IceInternal::EndpointIPtr&) const; virtual bool operator==(const IceInternal::EndpointI&) const; virtual bool operator!=(const IceInternal::EndpointI&) const; @@ -50,6 +51,8 @@ public: private: + virtual std::vector<IceInternal::ConnectorPtr> connectors(const std::vector<struct sockaddr_in>&) const; + #if defined(__SUNPRO_CC) // // COMPILERFIX: prevent the compiler from emitting a warning about diff --git a/cpp/src/IceSSL/Instance.cpp b/cpp/src/IceSSL/Instance.cpp index a840d019d8e..a0933c5420d 100644 --- a/cpp/src/IceSSL/Instance.cpp +++ b/cpp/src/IceSSL/Instance.cpp @@ -532,6 +532,12 @@ IceSSL::Instance::communicator() const return _facade->getCommunicator(); } +IceInternal::EndpointHostResolverPtr +IceSSL::Instance::endpointHostResolver() const +{ + return _facade->getEndpointHostResolver(); +} + string IceSSL::Instance::defaultHost() const { diff --git a/cpp/src/IceSSL/Instance.h b/cpp/src/IceSSL/Instance.h index 01ee3e8c8dd..9f3d69284ff 100644 --- a/cpp/src/IceSSL/Instance.h +++ b/cpp/src/IceSSL/Instance.h @@ -35,6 +35,7 @@ public: void setPasswordPrompt(const PasswordPromptPtr&); Ice::CommunicatorPtr communicator() const; + IceInternal::EndpointHostResolverPtr endpointHostResolver() const; std::string defaultHost() const; int networkTraceLevel() const; std::string networkTraceCategory() const; diff --git a/cpp/src/IceSSL/TransceiverI.cpp b/cpp/src/IceSSL/TransceiverI.cpp index d4b86a2a427..d930c3d8cff 100644 --- a/cpp/src/IceSSL/TransceiverI.cpp +++ b/cpp/src/IceSSL/TransceiverI.cpp @@ -54,6 +54,11 @@ IceSSL::TransceiverI::close() void IceSSL::TransceiverI::shutdownWrite() { + if(_state < StateConnected) + { + return; + } + if(_instance->networkTraceLevel() >= 2) { Trace out(_logger, _instance->networkTraceCategory()); @@ -69,6 +74,11 @@ IceSSL::TransceiverI::shutdownWrite() void IceSSL::TransceiverI::shutdownReadWrite() { + if(_state < StateConnected) + { + return; + } + if(_instance->networkTraceLevel() >= 2) { Trace out(_logger, _instance->networkTraceCategory()); @@ -81,7 +91,7 @@ IceSSL::TransceiverI::shutdownReadWrite() IceInternal::shutdownSocketReadWrite(_fd); } -void +bool IceSSL::TransceiverI::write(IceInternal::Buffer& buf, int timeout) { // Its impossible for the packetSize to be more than an Int. @@ -102,12 +112,11 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf, int timeout) ERR_clear_error(); // Clear any spurious errors. assert(_fd != INVALID_SOCKET); int ret, err; - bool wantRead, wantWrite; + bool wantWrite; { IceUtil::Mutex::Lock sync(_sslMutex); ret = SSL_write(_ssl, reinterpret_cast<const void*>(&*buf.i), packetSize); err = SSL_get_error(_ssl, ret); - wantRead = SSL_want_read(_ssl); wantWrite = SSL_want_write(_ssl); } @@ -126,14 +135,15 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf, int timeout) } case SSL_ERROR_WANT_READ: { - if(!selectRead(_fd, timeout)) - { - throw TimeoutException(__FILE__, __LINE__); - } - continue; + assert(false); + break; } case SSL_ERROR_WANT_WRITE: { + if(timeout == 0) + { + return false; + } if(!selectWrite(_fd, timeout)) { throw TimeoutException(__FILE__, __LINE__); @@ -157,15 +167,12 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf, int timeout) if(IceInternal::wouldBlock()) { - if(wantRead) + if(wantWrite) { - if(!selectRead(_fd, timeout)) + if(timeout == 0) { - throw TimeoutException(__FILE__, __LINE__); + return false; } - } - else if(wantWrite) - { if(!selectWrite(_fd, timeout)) { throw TimeoutException(__FILE__, __LINE__); @@ -221,9 +228,11 @@ IceSSL::TransceiverI::write(IceInternal::Buffer& buf, int timeout) packetSize = static_cast<int>(buf.b.end() - buf.i); } } + + return true; } -void +bool IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) { // It's impossible for the packetSize to be more than an Int. @@ -234,13 +243,12 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) ERR_clear_error(); // Clear any spurious errors. assert(_fd != INVALID_SOCKET); int ret, err; - bool wantRead, wantWrite; + bool wantRead; { IceUtil::Mutex::Lock sync(_sslMutex); ret = SSL_read(_ssl, reinterpret_cast<void*>(&*buf.i), packetSize); err = SSL_get_error(_ssl, ret); wantRead = SSL_want_read(_ssl); - wantWrite = SSL_want_write(_ssl); } if(ret <= 0) @@ -269,6 +277,10 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) } case SSL_ERROR_WANT_READ: { + if(timeout == 0) + { + return false; + } if(!selectRead(_fd, timeout)) { throw TimeoutException(__FILE__, __LINE__); @@ -277,11 +289,8 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) } case SSL_ERROR_WANT_WRITE: { - if(!selectWrite(_fd, timeout)) - { - throw TimeoutException(__FILE__, __LINE__); - } - continue; + assert(false); + break; } case SSL_ERROR_SYSCALL: { @@ -302,19 +311,15 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) { if(wantRead) { - if(!selectRead(_fd, timeout)) + if(timeout == 0) { - throw TimeoutException(__FILE__, __LINE__); + return false; } - } - else if(wantWrite) - { - if(!selectWrite(_fd, timeout)) + if(!selectRead(_fd, timeout)) { throw TimeoutException(__FILE__, __LINE__); } } - continue; } @@ -361,8 +366,8 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) //if(ERR_GET_LIB(e) == ERR_LIB_SSL && ERR_GET_REASON(e) == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC) // unsigned long e = ERR_peek_error(); - if(ERR_GET_LIB(e) == ERR_LIB_SSL && - strcmp(ERR_reason_error_string(e), "decryption failed or bad record mac") == 0) + const char* estr = ERR_GET_LIB(e) == ERR_LIB_SSL ? ERR_reason_error_string(e) : 0; + if(estr && strcmp(estr, "decryption failed or bad record mac") == 0) { ConnectionLostException ex(__FILE__, __LINE__); ex.error = 0; @@ -396,6 +401,8 @@ IceSSL::TransceiverI::read(IceInternal::Buffer& buf, int timeout) packetSize = static_cast<int>(buf.b.end() - buf.i); } } + + return true; } string @@ -410,129 +417,157 @@ IceSSL::TransceiverI::toString() const return _desc; } -void +IceInternal::SocketStatus IceSSL::TransceiverI::initialize(int timeout) { - if(_incoming) + if(_state == StateNeedConnect && timeout == 0) + { + _state = StateConnectPending; + return IceInternal::NeedConnect; + } + else if(_state <= StateConnectPending) + { + IceInternal::doFinishConnect(_fd, timeout); + _state = StateConnected; + _desc = IceInternal::fdToString(_fd); + } + assert(_state == StateConnected); + + do { - // TODO: The timeout is 0 when called by the thread pool. - // Make this configurable? - if(timeout == 0) + // + // Only one thread calls initialize(), so synchronization is not necessary here. + // + int ret = _incoming ? SSL_accept(_ssl) : SSL_connect(_ssl); + switch(SSL_get_error(_ssl, ret)) { - timeout = -1; + case SSL_ERROR_NONE: + assert(SSL_is_init_finished(_ssl)); + break; + case SSL_ERROR_ZERO_RETURN: + { + ConnectionLostException ex(__FILE__, __LINE__); + ex.error = IceInternal::getSocketErrno(); + throw ex; } - - do + case SSL_ERROR_WANT_READ: { - // - // Only one thread calls initialize(), so synchronization is not necessary here. - // - int ret = SSL_accept(_ssl); - switch(SSL_get_error(_ssl, ret)) + if(timeout == 0) { - case SSL_ERROR_NONE: - assert(SSL_is_init_finished(_ssl)); - break; - case SSL_ERROR_ZERO_RETURN: + return IceInternal::NeedRead; + } + if(!selectRead(_fd, timeout)) { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; + throw ConnectTimeoutException(__FILE__, __LINE__); } - case SSL_ERROR_WANT_READ: + break; + } + case SSL_ERROR_WANT_WRITE: + { + if(timeout == 0) { - if(!selectRead(_fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - break; + return IceInternal::NeedWrite; } - case SSL_ERROR_WANT_WRITE: + if(!selectWrite(_fd, timeout)) { - if(!selectWrite(_fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } - break; + throw ConnectTimeoutException(__FILE__, __LINE__); } - case SSL_ERROR_SYSCALL: + break; + } + case SSL_ERROR_SYSCALL: + { + if(ret == -1) { - if(ret == -1) + if(IceInternal::interrupted()) { - if(IceInternal::interrupted()) - { - break; - } - - if(IceInternal::wouldBlock()) + break; + } + + if(IceInternal::wouldBlock()) + { + if(SSL_want_read(_ssl)) { - if(SSL_want_read(_ssl)) + if(timeout == 0) { - if(!selectRead(_fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } + return IceInternal::NeedRead; } - else if(SSL_want_write(_ssl)) + if(!selectRead(_fd, timeout)) { - if(!selectWrite(_fd, timeout)) - { - throw ConnectTimeoutException(__FILE__, __LINE__); - } + throw ConnectTimeoutException(__FILE__, __LINE__); } - - break; } - - if(IceInternal::connectionLost()) + else if(SSL_want_write(_ssl)) { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; + if(timeout == 0) + { + return IceInternal::NeedWrite; + } + if(!selectWrite(_fd, timeout)) + { + throw ConnectTimeoutException(__FILE__, __LINE__); + } } + + break; } - - if(ret == 0) + + if(IceInternal::connectionLost()) { ConnectionLostException ex(__FILE__, __LINE__); - ex.error = 0; + ex.error = IceInternal::getSocketErrno(); throw ex; } - - SocketException ex(__FILE__, __LINE__); - ex.error = IceInternal::getSocketErrno(); - throw ex; } - case SSL_ERROR_SSL: + + if(ret == 0) { - struct sockaddr_in remoteAddr; - string desc; - if(IceInternal::fdToRemoteAddress(_fd, remoteAddr)) - { - desc = IceInternal::addrToString(remoteAddr); - } - ProtocolException ex(__FILE__, __LINE__); - ex.reason = "SSL error occurred for new incoming connection:\nremote address = " + desc + "\n" + - _instance->sslErrors(); + ConnectionLostException ex(__FILE__, __LINE__); + ex.error = 0; throw ex; } + + SocketException ex(__FILE__, __LINE__); + ex.error = IceInternal::getSocketErrno(); + throw ex; + } + case SSL_ERROR_SSL: + { + struct sockaddr_in remoteAddr; + string desc; + if(IceInternal::fdToRemoteAddress(_fd, remoteAddr)) + { + desc = IceInternal::addrToString(remoteAddr); } + ProtocolException ex(__FILE__, __LINE__); + ex.reason = "SSL error occurred for new incoming connection:\nremote address = " + desc + "\n" + + _instance->sslErrors(); + throw ex; } - while(!SSL_is_init_finished(_ssl)); - - _instance->verifyPeer(_ssl, _fd, "", _adapterName, true); + } + } + while(!SSL_is_init_finished(_ssl)); + + _instance->verifyPeer(_ssl, _fd, "", _adapterName, _incoming); - if(_instance->networkTraceLevel() >= 1) + if(_instance->networkTraceLevel() >= 1) + { + Trace out(_logger, _instance->networkTraceCategory()); + if(_incoming) { - Trace out(_logger, _instance->networkTraceCategory()); out << "accepted ssl connection\n" << IceInternal::fdToString(_fd); } - - if(_instance->securityTraceLevel() >= 1) + else { - _instance->traceConnection(_ssl, true); + out << "ssl connection established\n" << IceInternal::fdToString(_fd); } } + + if(_instance->securityTraceLevel() >= 1) + { + _instance->traceConnection(_ssl, _incoming); + } + + return IceInternal::Finished; } void @@ -554,7 +589,7 @@ IceSSL::TransceiverI::getConnectionInfo() const return populateConnectionInfo(_ssl, _fd, _adapterName, _incoming); } -IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SSL* ssl, SOCKET fd, +IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SSL* ssl, SOCKET fd, bool connected, bool incoming, const string& adapterName) : _instance(instance), _logger(instance->communicator()->getLogger()), @@ -563,6 +598,7 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, SSL* ssl, SOCKET _fd(fd), _adapterName(adapterName), _incoming(incoming), + _state(connected ? StateConnected : StateNeedConnect), _desc(IceInternal::fdToString(fd)) { #ifdef _WIN32 diff --git a/cpp/src/IceSSL/TransceiverI.h b/cpp/src/IceSSL/TransceiverI.h index 298fd206538..f3d055ea3bd 100644 --- a/cpp/src/IceSSL/TransceiverI.h +++ b/cpp/src/IceSSL/TransceiverI.h @@ -29,24 +29,31 @@ class AcceptorI; class TransceiverI : public IceInternal::Transceiver { + enum State + { + StateNeedConnect, + StateConnectPending, + StateConnected + }; + public: virtual SOCKET fd(); virtual void close(); virtual void shutdownWrite(); virtual void shutdownReadWrite(); - virtual void write(IceInternal::Buffer&, int); - virtual void read(IceInternal::Buffer&, int); + virtual bool write(IceInternal::Buffer&, int); + virtual bool read(IceInternal::Buffer&, int); virtual std::string type() const; virtual std::string toString() const; - virtual void initialize(int); + virtual IceInternal::SocketStatus initialize(int); virtual void checkSendSize(const IceInternal::Buffer&, size_t); ConnectionInfo getConnectionInfo() const; private: - TransceiverI(const InstancePtr&, SSL*, SOCKET, bool, const std::string& = ""); + TransceiverI(const InstancePtr&, SSL*, SOCKET, bool, bool, const std::string& = ""); virtual ~TransceiverI(); friend class ConnectorI; friend class AcceptorI; @@ -65,7 +72,8 @@ private: const std::string _adapterName; const bool _incoming; - const std::string _desc; + State _state; + std::string _desc; #ifdef _WIN32 int _maxPacketSize; #endif diff --git a/cpp/src/IceStorm/Subscriber.cpp b/cpp/src/IceStorm/Subscriber.cpp index b7e5ef45aa9..ae899ee231d 100644 --- a/cpp/src/IceStorm/Subscriber.cpp +++ b/cpp/src/IceStorm/Subscriber.cpp @@ -233,12 +233,11 @@ SubscriberOneway::flush() vector<Ice::Byte> dummy; if(v.size() > 1 && !_batch) { + Ice::ConnectionPtr conn = _objBatch->ice_getConnection(); for(EventDataSeq::const_iterator p = v.begin(); p != v.end(); ++p) { _objBatch->ice_invoke((*p)->op, (*p)->mode, (*p)->data, dummy, (*p)->context); } - Ice::ConnectionPtr conn = _objBatch->ice_getCachedConnection(); - assert(conn); conn->flushBatchRequests(); } else diff --git a/cpp/src/IceUtil/Timer.cpp b/cpp/src/IceUtil/Timer.cpp index 16d34ef0c0a..b440934be16 100755 --- a/cpp/src/IceUtil/Timer.cpp +++ b/cpp/src/IceUtil/Timer.cpp @@ -13,12 +13,6 @@ using namespace std; using namespace IceUtil; -bool -TimerTask::operator<(const TimerTask& r) const -{ - return this < &r; -} - Timer::Timer() : _destroyed(false) { start(); @@ -96,7 +90,7 @@ Timer::cancel(const TimerTaskPtr& task) return false; } - map<TimerTaskPtr, IceUtil::Time>::iterator p = _tasks.find(task); + map<TimerTaskPtr, IceUtil::Time, TimerTaskCompare>::iterator p = _tasks.find(task); if(p == _tasks.end()) { return false; @@ -125,7 +119,7 @@ Timer::run() // if(token.delay != IceUtil::Time()) { - map<TimerTaskPtr, IceUtil::Time>::iterator p = _tasks.find(token.task); + map<TimerTaskPtr, IceUtil::Time, TimerTaskCompare>::iterator p = _tasks.find(token.task); if(p != _tasks.end()) { token.scheduledTime = IceUtil::Time::now(IceUtil::Time::Monotonic) + token.delay; @@ -176,7 +170,7 @@ Timer::run() { try { - token.task->run(); + token.task->runTimerTask(); } catch(const std::exception& e) { diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index dbc34fc94f7..7179373716e 100755 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -2258,7 +2258,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) { C << nl << "__checkTwowayOnly(" << p->flattenedScope() + p->name() + "_name);"; } - C << nl << "__delBase = __getDelegate();"; + C << nl << "__delBase = __getDelegate(false);"; C << nl << "::IceDelegate" << thisPointer << " __del = dynamic_cast< ::IceDelegate" << thisPointer << ">(__delBase.get());"; C << nl; @@ -2603,8 +2603,8 @@ Slice::Gen::DelegateMVisitor::visitOperation(const OperationPtr& p) H << sp << nl << "virtual " << retS << ' ' << name << spar << params << epar << ';'; C << sp << nl << retS << nl << "IceDelegateM" << scoped << spar << paramsDecl << epar; C << sb; - C << nl << "::IceInternal::Outgoing __og(__connection.get(), __reference.get(), " << flatName << ", " - << operationModeToString(p->sendMode()) << ", __context, __compress);"; + C << nl << "::IceInternal::Outgoing __og(__handler.get(), " << flatName << ", " + << operationModeToString(p->sendMode()) << ", __context);"; if(!inParams.empty()) { C << nl << "try"; @@ -5217,6 +5217,10 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) C << sb; C << nl << "try"; C << sb; + if(p->returnsData()) + { + C << nl << "__prx->__checkTwowayOnly(\"" << p->name() << "\");"; + } C << nl << "__prepare(__prx, " << flatName << ", " << operationModeToString(p->sendMode()) << ", __ctx);"; writeMarshalCode(C, inParams, 0, StringList(), true); if(p->sendsClasses()) diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index 1192172a13e..fc472391b7e 100755 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -3100,7 +3100,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) { _out << nl << "checkTwowayOnly__(\"" << op->name() << "\");"; } - _out << nl << "delBase__ = getDelegate__();"; + _out << nl << "delBase__ = getDelegate__(false);"; _out << nl << name << "Del_ del__ = (" << name << "Del_)delBase__;"; _out << nl; if(ret) @@ -3834,9 +3834,8 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) << "_System.Collections.Generic.Dictionary<string, string> context__" << epar; _out << sb; - _out << nl << "IceInternal.Outgoing og__ = getOutgoing(\"" << op->name() << "\", " - << sliceModeToIceMode(op->sendMode()) - << ", context__);"; + _out << nl << "IceInternal.Outgoing og__ = handler__.getOutgoing(\"" << op->name() << "\", " + << sliceModeToIceMode(op->sendMode()) << ", context__);"; _out << nl << "try"; _out << sb; if(!inParams.empty()) @@ -3979,7 +3978,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) _out << eb; _out << nl << "finally"; _out << sb; - _out << nl << "reclaimOutgoing(og__);"; + _out << nl << "handler__.reclaimOutgoing(og__);"; _out << eb; _out << eb; } @@ -4411,8 +4410,11 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) _out << sb; _out << nl << "try"; _out << sb; - _out << nl << "prepare__(prx__, \"" << name << "\", " << sliceModeToIceMode(p->sendMode()) - << ", ctx__);"; + if(p->returnsData()) + { + _out << nl << "((Ice.ObjectPrxHelperBase)prx__).checkTwowayOnly__(\"" << p->name() << "\");"; + } + _out << nl << "prepare__(prx__, \"" << name << "\", " << sliceModeToIceMode(p->sendMode()) << ", ctx__);"; for(q = inParams.begin(); q != inParams.end(); ++q) { string typeS = typeToString(q->first); diff --git a/cpp/src/slice2freezej/Main.cpp b/cpp/src/slice2freezej/Main.cpp index d82468ab033..8e30f9d4097 100644 --- a/cpp/src/slice2freezej/Main.cpp +++ b/cpp/src/slice2freezej/Main.cpp @@ -541,9 +541,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) { out << nl << "__os.endWriteEncaps();"; } - out << nl << "java.nio.ByteBuffer __buf = __os.prepareWrite();"; - out << nl << "byte[] __r = new byte[__buf.limit()];"; - out << nl << "__buf.get(__r);"; + out << nl << "IceInternal.Buffer __buf = __os.prepareWrite();"; + out << nl << "byte[] __r = new byte[__buf.size()];"; + out << nl << "__buf.b.get(__r);"; out << nl << "return __r;"; out << eb; @@ -559,10 +559,10 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) out << nl << "__is.sliceObjects(false);"; } out << nl << "__is.resize(b.length, true);"; - out << nl << "java.nio.ByteBuffer __buf = __is.prepareRead();"; - out << nl << "__buf.position(0);"; - out << nl << "__buf.put(b);"; - out << nl << "__buf.position(0);"; + out << nl << "IceInternal.Buffer __buf = __is.getBuffer();"; + out << nl << "__buf.b.position(0);"; + out << nl << "__buf.b.put(b);"; + out << nl << "__buf.b.position(0);"; if(encaps) { out << nl << "__is.startReadEncaps();"; @@ -696,9 +696,9 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) writeMarshalUnmarshalCode(out, "", indexTypes[i], keyS, true, iter, false); assert(!indexTypes[i]->usesClasses()); - out << nl << "java.nio.ByteBuffer buf = __os.prepareWrite();"; - out << nl << "byte[] r = new byte[buf.limit()];"; - out << nl << "buf.get(r);"; + out << nl << "IceInternal.Buffer buf = __os.prepareWrite();"; + out << nl << "byte[] r = new byte[buf.size()];"; + out << nl << "buf.b.get(r);"; out << nl << "return r;"; } out << eb; @@ -720,10 +720,10 @@ FreezeGenerator::generate(UnitPtr& u, const Dict& dict) { out << nl << "IceInternal.BasicStream __is = new IceInternal.BasicStream(Ice.Util.getInstance(communicator));"; out << nl << "__is.resize(bytes.length, true);"; - out << nl << "java.nio.ByteBuffer buf = __is.prepareRead();"; - out << nl << "buf.position(0);"; - out << nl << "buf.put(bytes);"; - out << nl << "buf.position(0);"; + out << nl << "IceInternal.Buffer buf = __is.getBuffer();"; + out << nl << "buf.b.position(0);"; + out << nl << "buf.b.put(bytes);"; + out << nl << "buf.b.position(0);"; int iter = 0; list<string> metaData; @@ -1057,9 +1057,9 @@ FreezeGenerator::generate(UnitPtr& u, const Index& index) { out << nl << "__os.writePendingObjects();"; } - out << nl << "java.nio.ByteBuffer __buf = __os.prepareWrite();"; - out << nl << "byte[] __r = new byte[__buf.limit()];"; - out << nl << "__buf.get(__r);"; + out << nl << "IceInternal.Buffer __buf = __os.prepareWrite();"; + out << nl << "byte[] __r = new byte[__buf.size()];"; + out << nl << "__buf.b.get(__r);"; out << nl << "return __r;"; out << eb; diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index 37fe9a2d6d8..32a9e57a7ae 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -3398,7 +3398,7 @@ Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p) { out << nl << "__checkTwowayOnly(\"" << opName << "\");"; } - out << nl << "__delBase = __getDelegate();"; + out << nl << "__delBase = __getDelegate(false);"; out << nl << '_' << name << "Del __del = (_" << name << "Del)__delBase;"; out << nl; if(ret) @@ -4164,8 +4164,8 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) writeDelegateThrowsClause(package, throws); out << sb; - out << nl << "IceInternal.Outgoing __og = __connection.getOutgoing(__reference, \"" << op->name() << "\", " - << sliceModeToIceMode(op->sendMode()) << ", __ctx, __compress);"; + out << nl << "IceInternal.Outgoing __og = __handler.getOutgoing(\"" << op->name() << "\", " + << sliceModeToIceMode(op->sendMode()) << ", __ctx);"; out << nl << "try"; out << sb; if(!inParams.empty()) @@ -4253,7 +4253,7 @@ Slice::Gen::DelegateMVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; out << nl << "finally"; out << sb; - out << nl << "__connection.reclaimOutgoing(__og);"; + out << nl << "__handler.reclaimOutgoing(__og);"; out << eb; out << eb; } @@ -4987,8 +4987,11 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) out << sb; out << nl << "try"; out << sb; - out << nl << "__prepare(__prx, \"" << p->name() << "\", " - << sliceModeToIceMode(p->sendMode()) << ", __ctx);"; + if(p->returnsData()) + { + out << nl << "((Ice.ObjectPrxHelperBase)__prx).__checkTwowayOnly(\"" << p->name() << "\");"; + } + out << nl << "__prepare(__prx, \"" << p->name() << "\", " << sliceModeToIceMode(p->sendMode()) << ", __ctx);"; iter = 0; for(pli = inParams.begin(); pli != inParams.end(); ++pli) { diff --git a/cpp/test/Freeze/oldevictor/Client.cpp b/cpp/test/Freeze/oldevictor/Client.cpp index cfafd704ef7..2dd10200004 100644 --- a/cpp/test/Freeze/oldevictor/Client.cpp +++ b/cpp/test/Freeze/oldevictor/Client.cpp @@ -9,6 +9,7 @@ #include <Ice/Ice.h> #include <IceUtil/Thread.h> +#include <IceUtil/RecMutex.h> #include <IceUtil/Time.h> #include <TestCommon.h> #include <Test.h> diff --git a/cpp/test/Glacier2/router/Client.cpp b/cpp/test/Glacier2/router/Client.cpp index 65717e620cc..0f878bb7469 100644 --- a/cpp/test/Glacier2/router/Client.cpp +++ b/cpp/test/Glacier2/router/Client.cpp @@ -515,8 +515,16 @@ CallbackClient::run(int argc, char* argv[]) { cout << "creating session with correct password... " << flush; - session = router->createSession("userid", "abc123"); - cout << "ok" << endl; + try + { + session = router->createSession("userid", "abc123"); + cout << "ok" << endl; + } + catch(const Glacier2::PermissionDeniedException& ex) + { + cerr << ex << ":\n" << ex.reason << endl; + test(false); + } } { @@ -701,7 +709,7 @@ CallbackClient::run(int argc, char* argv[]) } { - cout << "testing buffered mode... " << flush; + cout << "testing with blocking clients... " << flush; // // Start 3 misbehaving clients. diff --git a/cpp/test/Glacier2/router/run.py b/cpp/test/Glacier2/router/run.py index 0edaed9d6f6..e674550143c 100755 --- a/cpp/test/Glacier2/router/run.py +++ b/cpp/test/Glacier2/router/run.py @@ -22,35 +22,57 @@ import TestUtil router = os.path.join(TestUtil.getBinDir(__file__), "glacier2router") -args = r' --Ice.Warn.Dispatch=0' + \ - r' --Ice.Warn.Connections=0' + \ - r' --Glacier2.Filter.Category.Accept="c1 c2"' + \ - r' --Glacier2.Filter.Category.AcceptUser="2"' + \ - r' --Glacier2.SessionTimeout="30"' + \ - r' --Glacier2.Client.Endpoints="default -p 12347 -t 10000"' + \ - r' --Glacier2.Server.Endpoints="tcp -h 127.0.0.1 -t 10000"' \ - r' --Ice.Admin.Endpoints="tcp -h 127.0.0.1 -p 12348 -t 10000"' + \ - r' --Ice.Admin.InstanceName="Glacier2"' + \ - r' --Glacier2.CryptPasswords="' + TestUtil.getMappingDir(__file__) + r'/test/Glacier2/router/passwords"' - -print "starting router...", -if TestUtil.debug: - print "(" + command + ")", -starterPipe = TestUtil.startServer(router, args + " 2>&1") -TestUtil.getServerPid(starterPipe) -# -# For this test we don't want to add the router to the server threads -# since we want the the router to run over two calls to -# mixedClientServerTest -# -TestUtil.getAdapterReady(starterPipe, False) -print "ok" +def startRouter(buffered): + + args = r' --Ice.Warn.Dispatch=0' + \ + r' --Ice.Warn.Connections=0' + \ + r' --Glacier2.Filter.Category.Accept="c1 c2"' + \ + r' --Glacier2.Filter.Category.AcceptUser="2"' + \ + r' --Glacier2.SessionTimeout="30"' + \ + r' --Glacier2.Client.Endpoints="default -p 12347 -t 10000"' + \ + r' --Glacier2.Server.Endpoints="tcp -h 127.0.0.1 -t 10000"' \ + r' --Ice.Admin.Endpoints="tcp -h 127.0.0.1 -p 12348 -t 10000"' + \ + r' --Ice.Admin.InstanceName="Glacier2"' + \ + r' --Glacier2.CryptPasswords="' + TestUtil.getMappingDir(__file__) + r'/test/Glacier2/router/passwords"' + + if buffered: + args += ' --Glacier2.Client.Buffered=1 --Glacier2.Server.Buffered=1' + print "starting router in buffered mode...", + else: + args += ' --Glacier2.Client.Buffered=0 --Glacier2.Server.Buffered=0' + print "starting router in unbuffered mode...", + + starterPipe = TestUtil.startServer(router, args + " 2>&1") + TestUtil.getServerPid(starterPipe) + + # + # For this test we don't want to add the router to the server threads + # since we want the the router to run over two calls to + # mixedClientServerTest + # + TestUtil.getAdapterReady(starterPipe, False) + print "ok" -starterThread = TestUtil.ReaderThread(starterPipe); -starterThread.start() + routerThread = TestUtil.ReaderThread(starterPipe); + routerThread.start() + + return routerThread name = os.path.join("Glacier2", "router") +# +# We first run the test with unbuffered mode. +# +routerThread = startRouter(False) +TestUtil.mixedClientServerTestWithOptions(name, "", " --shutdown") +routerThread.join() +if routerThread.getStatus(): + sys.exit(1) + +# +# Then we run the test in buffered mode. +# +routerThread = startRouter(True) TestUtil.mixedClientServerTest(name) # @@ -60,8 +82,8 @@ TestUtil.mixedClientServerTest(name) # TestUtil.mixedClientServerTestWithOptions(name, "", " --shutdown") -starterThread.join() -if starterThread.getStatus(): +routerThread.join() +if routerThread.getStatus(): sys.exit(1) sys.exit(0) diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile index 2c577b0081e..db697847888 100644 --- a/cpp/test/Ice/Makefile +++ b/cpp/test/Ice/Makefile @@ -32,7 +32,8 @@ SUBDIRS = proxy \ servantLocator \ threads \ interceptor \ - stringConverter + stringConverter \ + background $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak index dfe04be6621..f1e43713e81 100644 --- a/cpp/test/Ice/Makefile.mak +++ b/cpp/test/Ice/Makefile.mak @@ -32,7 +32,8 @@ SUBDIRS = proxy \ servantLocator \ threads \ interceptor \ - stringConverter + stringConverter \ + background $(EVERYTHING):: @for %i in ( $(SUBDIRS) ) do \ diff --git a/cpp/test/Ice/background/.depend b/cpp/test/Ice/background/.depend new file mode 100644 index 00000000000..02b0c387ca0 --- /dev/null +++ b/cpp/test/Ice/background/.depend @@ -0,0 +1,17 @@ +Configuration$(OBJEXT): Configuration.cpp Configuration.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Handle.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h +Connector$(OBJEXT): Connector.cpp Connector.h ../../../src/Ice/Connector.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../src/Ice/ConnectorF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../src/Ice/TransceiverF.h Configuration.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h Transceiver.h ../../../src/Ice/Transceiver.h EndpointI.h ../../../src/Ice/EndpointI.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../src/Ice/AcceptorF.h +Acceptor$(OBJEXT): Acceptor.cpp Acceptor.h ../../../src/Ice/Acceptor.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../src/Ice/AcceptorF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../src/Ice/TransceiverF.h Transceiver.h ../../../src/Ice/Transceiver.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h Configuration.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h +EndpointI$(OBJEXT): EndpointI.cpp EndpointI.h ../../../src/Ice/EndpointI.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/Endpoint.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/InstanceF.h ../../../src/Ice/TransceiverF.h ../../../src/Ice/ConnectorF.h ../../../src/Ice/AcceptorF.h Configuration.h ../../../include/Ice/LocalException.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Selector.h Transceiver.h ../../../src/Ice/Transceiver.h Connector.h ../../../src/Ice/Connector.h Acceptor.h ../../../src/Ice/Acceptor.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h +Transceiver$(OBJEXT): Transceiver.cpp Transceiver.h ../../../src/Ice/Transceiver.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../src/Ice/TransceiverF.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h Configuration.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h +EndpointFactory$(OBJEXT): EndpointFactory.cpp ../../../src/Ice/Instance.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/RecMutex.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/InstanceF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/StatsF.h ../../../src/Ice/TraceLevelsF.h ../../../src/Ice/DefaultsAndOverridesF.h ../../../src/Ice/RouterInfoF.h ../../../src/Ice/LocatorInfoF.h ../../../src/Ice/ReferenceFactoryF.h ../../../include/Ice/ProxyFactoryF.h ../../../src/Ice/ThreadPoolF.h ../../../src/Ice/SelectorThreadF.h ../../../include/Ice/ConnectionFactoryF.h ../../../include/Ice/ConnectionMonitorF.h ../../../src/Ice/ObjectFactoryManagerF.h ../../../include/Ice/ObjectAdapterFactoryF.h ../../../src/Ice/EndpointFactoryManagerF.h ../../../include/Ice/DynamicLibraryF.h ../../../include/Ice/PluginF.h ../../../include/Ice/Initialize.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/Proxy.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/SharedContext.h ../../../src/Ice/ImplicitContextI.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/LocalException.h ../../../include/Ice/FacetMap.h ../../../include/Ice/Process.h ../../../include/Ice/Outgoing.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../src/Ice/EndpointFactoryManager.h ../../../include/Ice/EndpointFactoryF.h EndpointFactory.h ../../../include/Ice/EndpointFactory.h EndpointI.h ../../../src/Ice/EndpointI.h ../../../src/Ice/TransceiverF.h ../../../src/Ice/ConnectorF.h ../../../src/Ice/AcceptorF.h Configuration.h ../../../src/Ice/Selector.h +PluginI$(OBJEXT): PluginI.cpp ../../../include/Ice/Initialize.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/InstanceF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Instance.h ../../../include/IceUtil/RecMutex.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../src/Ice/TraceLevelsF.h ../../../src/Ice/DefaultsAndOverridesF.h ../../../src/Ice/RouterInfoF.h ../../../src/Ice/LocatorInfoF.h ../../../src/Ice/ReferenceFactoryF.h ../../../src/Ice/ThreadPoolF.h ../../../src/Ice/SelectorThreadF.h ../../../include/Ice/ConnectionFactoryF.h ../../../include/Ice/ConnectionMonitorF.h ../../../src/Ice/ObjectFactoryManagerF.h ../../../include/Ice/ObjectAdapterFactoryF.h ../../../src/Ice/EndpointFactoryManagerF.h ../../../include/Ice/DynamicLibraryF.h ../../../include/Ice/PluginF.h ../../../src/Ice/SharedContext.h ../../../src/Ice/ImplicitContextI.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/LocalException.h ../../../include/Ice/FacetMap.h ../../../include/Ice/Process.h ../../../include/Ice/Outgoing.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/ProtocolPluginFacade.h ../../../include/Ice/ProtocolPluginFacadeF.h ../../../include/Ice/EndpointFactoryF.h ../../../src/Ice/EndpointFactoryManager.h PluginI.h ../../../include/Ice/Plugin.h Configuration.h ../../../src/Ice/Selector.h EndpointFactory.h ../../../include/Ice/EndpointFactory.h +Configuration$(OBJEXT): Configuration.cpp Configuration.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Handle.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h +Test$(OBJEXT): Test.cpp Test.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/InstanceF.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/ObjectFactory.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/ScopedArray.h +Client$(OBJEXT): Client.cpp ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/InstanceF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/FacetMap.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/IceUtil/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/Locator.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/ProcessF.h ../../../include/Ice/Router.h ../../../include/Ice/DispatchInterceptor.h ../../../include/Ice/IconvStringConverter.h ../../include/TestCommon.h Test.h Configuration.h ../../../src/Ice/Selector.h +AllTests$(OBJEXT): AllTests.cpp ../../../include/IceUtil/IceUtil.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/AbstractMutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Algorithm.h ../../../include/IceUtil/ArgVector.h ../../../include/IceUtil/Base64.h ../../../include/IceUtil/Cache.h ../../../include/IceUtil/Handle.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/CountDownLatch.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/IceUtil/CtrlCHandler.h ../../../include/IceUtil/Functional.h ../../../include/IceUtil/InputUtil.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/MD5.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Options.h ../../../include/IceUtil/RecMutex.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/OutputUtil.h ../../../include/IceUtil/RWRecMutex.h ../../../include/IceUtil/Thread.h ../../../include/IceUtil/Random.h ../../../include/IceUtil/ScopedArray.h ../../../include/IceUtil/StaticMutex.h ../../../include/IceUtil/StringUtil.h ../../../include/IceUtil/UUID.h ../../../include/IceUtil/Unicode.h ../../../include/IceUtil/Timer.h ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/InstanceF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Outgoing.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/FacetMap.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/OutgoingAsync.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/Locator.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/ProcessF.h ../../../include/Ice/Router.h ../../../include/Ice/DispatchInterceptor.h ../../../include/Ice/IconvStringConverter.h ../../include/TestCommon.h Test.h PluginI.h ../../../include/Ice/Plugin.h Configuration.h ../../../src/Ice/Selector.h +Configuration$(OBJEXT): Configuration.cpp Configuration.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/IceUtil/Handle.h ../../../include/Ice/LocalException.h ../../../include/Ice/LocalObjectF.h ../../../include/Ice/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/BuiltinSequences.h ../../../src/Ice/Selector.h ../../../include/Ice/InstanceF.h +Test$(OBJEXT): Test.cpp Test.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/InstanceF.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/ObjectFactory.h ../../../include/IceUtil/Iterator.h ../../../include/IceUtil/ScopedArray.h +TestI$(OBJEXT): TestI.cpp TestI.h Test.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/InstanceF.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/Ice/StringConverter.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/BuiltinSequences.h Configuration.h ../../../include/Ice/LocalException.h ../../../src/Ice/Selector.h ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/Properties.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/FacetMap.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/IceUtil/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/Locator.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/ProcessF.h ../../../include/Ice/Router.h ../../../include/Ice/DispatchInterceptor.h ../../../include/Ice/IconvStringConverter.h +Server$(OBJEXT): Server.cpp ../../../include/IceUtil/DisableWarnings.h ../../../include/Ice/Ice.h ../../../include/Ice/Initialize.h ../../../include/Ice/CommunicatorF.h ../../../include/Ice/LocalObjectF.h ../../../include/IceUtil/Shared.h ../../../include/IceUtil/Config.h ../../../include/IceUtil/Mutex.h ../../../include/IceUtil/Lock.h ../../../include/IceUtil/ThreadException.h ../../../include/IceUtil/Exception.h ../../../include/Ice/Handle.h ../../../include/IceUtil/Handle.h ../../../include/Ice/Config.h ../../../include/Ice/ProxyHandle.h ../../../include/Ice/ProxyF.h ../../../include/Ice/ObjectF.h ../../../include/Ice/GCCountMap.h ../../../include/Ice/GCShared.h ../../../include/Ice/Exception.h ../../../include/Ice/LocalObject.h ../../../include/Ice/UndefSysMacros.h ../../../include/Ice/PropertiesF.h ../../../include/Ice/Proxy.h ../../../include/Ice/ProxyFactoryF.h ../../../include/Ice/ConnectionIF.h ../../../include/Ice/RequestHandlerF.h ../../../include/Ice/EndpointIF.h ../../../include/Ice/Endpoint.h ../../../include/Ice/ObjectAdapterF.h ../../../include/Ice/ReferenceF.h ../../../include/Ice/OutgoingAsyncF.h ../../../include/Ice/Current.h ../../../include/Ice/ConnectionF.h ../../../include/Ice/Identity.h ../../../include/Ice/StreamF.h ../../../include/Ice/Object.h ../../../include/Ice/IncomingAsyncF.h ../../../include/Ice/InstanceF.h ../../../include/Ice/LoggerF.h ../../../include/Ice/StatsF.h ../../../include/Ice/StringConverter.h ../../../include/Ice/BuiltinSequences.h ../../../include/Ice/LocalException.h ../../../include/Ice/Properties.h ../../../include/Ice/Outgoing.h ../../../include/IceUtil/Monitor.h ../../../include/IceUtil/Cond.h ../../../include/IceUtil/Time.h ../../../include/Ice/BasicStream.h ../../../include/Ice/ObjectFactoryF.h ../../../include/Ice/Buffer.h ../../../include/Ice/Protocol.h ../../../include/IceUtil/Unicode.h ../../../include/Ice/Incoming.h ../../../include/Ice/ServantLocatorF.h ../../../include/Ice/ServantManagerF.h ../../../include/Ice/Direct.h ../../../include/Ice/Logger.h ../../../include/Ice/LoggerUtil.h ../../../include/Ice/Stats.h ../../../include/Ice/Communicator.h ../../../include/Ice/RouterF.h ../../../include/Ice/LocatorF.h ../../../include/Ice/PluginF.h ../../../include/Ice/ImplicitContextF.h ../../../include/Ice/ObjectFactory.h ../../../include/Ice/ObjectAdapter.h ../../../include/Ice/FacetMap.h ../../../include/Ice/ServantLocator.h ../../../include/Ice/OutgoingAsync.h ../../../include/IceUtil/Timer.h ../../../include/IceUtil/Thread.h ../../../include/Ice/IncomingAsync.h ../../../include/Ice/Process.h ../../../include/Ice/Application.h ../../../include/Ice/Connection.h ../../../include/Ice/Functional.h ../../../include/IceUtil/Functional.h ../../../include/Ice/Stream.h ../../../include/Ice/ImplicitContext.h ../../../include/Ice/Locator.h ../../../include/Ice/UserExceptionFactory.h ../../../include/Ice/FactoryTable.h ../../../include/Ice/FactoryTableDef.h ../../../include/IceUtil/StaticMutex.h ../../../include/Ice/UserExceptionFactoryF.h ../../../include/Ice/ProcessF.h ../../../include/Ice/Router.h ../../../include/Ice/DispatchInterceptor.h ../../../include/Ice/IconvStringConverter.h TestI.h Test.h Configuration.h ../../../src/Ice/Selector.h PluginI.h ../../../include/Ice/Plugin.h +Test.cpp: Test.ice ../../../../slice/Ice/BuiltinSequences.ice +Test.ice: $(SLICE2CPP) $(SLICEPARSERLIB) diff --git a/cpp/test/Ice/background/.gitignore b/cpp/test/Ice/background/.gitignore new file mode 100644 index 00000000000..67872faa673 --- /dev/null +++ b/cpp/test/Ice/background/.gitignore @@ -0,0 +1,7 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +client +server +Test.cpp +Test.h diff --git a/cpp/test/Ice/background/Acceptor.cpp b/cpp/test/Ice/background/Acceptor.cpp new file mode 100644 index 00000000000..d7158bdc4d4 --- /dev/null +++ b/cpp/test/Ice/background/Acceptor.cpp @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Acceptor.h> +#include <Transceiver.h> + +using namespace std; + +SOCKET +Acceptor::fd() +{ + return _acceptor->fd(); +} + +void +Acceptor::close() +{ + _acceptor->close(); +} + +void +Acceptor::listen() +{ + _acceptor->listen(); +} + +IceInternal::TransceiverPtr +Acceptor::accept(int timeout) +{ + return new Transceiver(_acceptor->accept(timeout)); +} + +void +Acceptor::connectToSelf() +{ + _acceptor->connectToSelf(); +} + +string +Acceptor::toString() const +{ + return _acceptor->toString(); +} + +Acceptor::Acceptor(const IceInternal::AcceptorPtr& acceptor) : _acceptor(acceptor) +{ +} + diff --git a/cpp/test/Ice/background/Acceptor.h b/cpp/test/Ice/background/Acceptor.h new file mode 100644 index 00000000000..a6fa166cd7f --- /dev/null +++ b/cpp/test/Ice/background/Acceptor.h @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ACCEPTOR_H +#define TEST_ACCEPTOR_H + +#include <Ice/Acceptor.h> + +class Acceptor : public IceInternal::Acceptor +{ +public: + + virtual SOCKET fd(); + virtual void close(); + virtual void listen(); + virtual IceInternal::TransceiverPtr accept(int); + virtual void connectToSelf(); + virtual std::string toString() const; + +private: + + Acceptor(const IceInternal::AcceptorPtr&); + friend class EndpointI; + + const IceInternal::AcceptorPtr _acceptor; +}; + +#endif diff --git a/cpp/test/Ice/background/AllTests.cpp b/cpp/test/Ice/background/AllTests.cpp new file mode 100644 index 00000000000..a4f0464575b --- /dev/null +++ b/cpp/test/Ice/background/AllTests.cpp @@ -0,0 +1,1171 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <IceUtil/IceUtil.h> +#include <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> +#include <PluginI.h> +#include <Configuration.h> + +using namespace std; +using namespace Test; + +class Callback : public IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + Callback() : _called(false) + { + } + + bool + check(bool wait) + { + if(wait) + { + Lock sync(*this); + while(!_called) + { + timedWait(IceUtil::Time::seconds(5)); + if(!_called) + { + return false; // Must be timeout. + } + } + _called = false; + return true; + } + return _called; + } + + void + called() + { + Lock sync(*this); + assert(!_called); + _called = true; + notify(); + } + +private: + + bool _called; +}; + +class OpAMICallback : public Test::AMI_Background_op +{ +public: + + virtual void + ice_response() + { + callback.called(); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } + + bool + response(bool wait) + { + return callback.check(wait); + } + +private: + + Callback callback; +}; +typedef IceUtil::Handle<OpAMICallback> OpAMICallbackPtr; + +class FlushBatchRequestsCallback : public Ice::AMI_Object_ice_flushBatchRequests +{ +public: + + virtual void + ice_exception(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } +}; +typedef IceUtil::Handle<FlushBatchRequestsCallback> FlushBatchRequestsCallbackPtr; + +class OpExAMICallback : public Test::AMI_Background_op +{ +public: + + virtual void + ice_response() + { + test(false); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + callback.called(); + } + + bool + exception(bool wait) + { + return callback.check(wait); + } + +private: + + Callback callback; +}; +typedef IceUtil::Handle<OpExAMICallback> OpExAMICallbackPtr; + +class OpWithPayloadOnewayAMICallback : public Test::AMI_Background_opWithPayload +{ +public: + + virtual void + ice_response() + { + test(false); + } + + virtual void + ice_exception(const Ice::Exception& ex) + { + cerr << ex << endl; + test(false); + } +}; +typedef IceUtil::Handle<OpWithPayloadOnewayAMICallback> OpWithPayloadOnewayAMICallbackPtr; + +class OpThread : public IceUtil::Thread, public IceUtil::Mutex +{ +public: + + OpThread(const BackgroundPrx& background) : + _destroyed(false), + _background(BackgroundPrx::uncheckedCast(background->ice_oneway())) + { + start(); + } + + void + run() + { + int count = 0; + while(true) + { + { + IceUtil::Mutex::Lock sync(*this); + if(_destroyed) + { + return; + } + } + + try + { + if(++count == 10) // Don't blast the connection with only oneway's + { + count = 0; + _background->ice_twoway()->ice_ping(); + } + _background->op_async(new OpExAMICallback()); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(1)); + } + catch(const Ice::LocalException&) + { + } + } + } + + void + destroy() + { + IceUtil::Mutex::Lock sync(*this); + _destroyed = true; + } + +private: + + bool _destroyed; + BackgroundPrx _background; +}; +typedef IceUtil::Handle<OpThread> OpThreadPtr; + +void connectTests(const ConfigurationPtr&, const Test::BackgroundPrx&); +void initializeTests(const ConfigurationPtr&, const Test::BackgroundPrx&, const Test::BackgroundControllerPrx&); +void validationTests(const ConfigurationPtr&, const Test::BackgroundPrx&, const Test::BackgroundControllerPrx&); +void readWriteTests(const ConfigurationPtr&, const Test::BackgroundPrx&, const Test::BackgroundControllerPrx&); + +BackgroundPrx +allTests(const Ice::CommunicatorPtr& communicator) +{ + string sref = "background:default -p 12010 -t 10000"; + Ice::ObjectPrx obj = communicator->stringToProxy(sref); + test(obj); + + BackgroundPrx background = BackgroundPrx::uncheckedCast(obj); + + sref = "backgroundController:tcp -p 12011 -t 10000"; + obj = communicator->stringToProxy(sref); + test(obj); + + BackgroundControllerPrx backgroundController = BackgroundControllerPrx::uncheckedCast(obj); + + PluginI* plugin = dynamic_cast<PluginI*>(communicator->getPluginManager()->getPlugin("Test").get()); + assert(plugin); + ConfigurationPtr configuration = plugin->getConfiguration(); + + cout << "testing connect... " << flush; + { + connectTests(configuration, background); + } + cout << "ok" << endl; + + cout << "testing initialization... " << flush; + { + initializeTests(configuration, background, backgroundController); + } + cout << "ok" << endl; + + cout << "testing connection validation... " << flush; + { + validationTests(configuration, background, backgroundController); + } + cout << "ok" << endl; + + cout << "testing read/write... " << flush; + { + readWriteTests(configuration, background, backgroundController); + } + cout << "ok" << endl; + + cout << "testing locator... " << flush; + { + Ice::LocatorPrx locator; + obj = communicator->stringToProxy("locator:default -p 12010 -t 500"); + locator = Ice::LocatorPrx::uncheckedCast(obj); + obj = communicator->stringToProxy("background@Test")->ice_locator(locator)->ice_oneway(); + + // + // TODO: The following test doesn't work on Windows because of a bug + // in thread per connection mode where the thread per connection read + // call doesn't return when the transceiver is shutdown. + // +#ifdef _WIN32 + if(communicator->getProperties()->getPropertyAsInt("Ice.ThreadPerConnection") == 0) + { +#endif + backgroundController->pauseCall("findAdapterById"); + try + { + obj->ice_ping(); + test(false); + } + catch(const Ice::TimeoutException&) + { + } + backgroundController->resumeCall("findAdapterById"); +#ifdef _WIN32 + } +#endif + + obj = communicator->stringToProxy("locator:default -p 12010 -t 10000"); + locator = Ice::LocatorPrx::uncheckedCast(obj); + obj = obj->ice_locator(locator); + obj->ice_ping(); + + obj = communicator->stringToProxy("background@Test")->ice_locator(locator); + BackgroundPrx bg = BackgroundPrx::uncheckedCast(obj); + + backgroundController->pauseCall("findAdapterById"); + OpAMICallbackPtr cb = new OpAMICallback(); + bg->op_async(cb); + OpAMICallbackPtr cb2 = new OpAMICallback(); + bg->op_async(cb2); + test(!cb->response(false)); + test(!cb2->response(false)); + backgroundController->resumeCall("findAdapterById"); + test(cb->response(true)); + test(cb2->response(true)); + } + cout << "ok" << endl; + + cout << "testing router... " << flush; + { + Ice::RouterPrx router; + + obj = communicator->stringToProxy("router:default -p 12010 -t 500"); + router = Ice::RouterPrx::uncheckedCast(obj); + obj = communicator->stringToProxy("background@Test")->ice_router(router)->ice_oneway(); + + // + // TODO: The following test doesn't work on Windows because of a bug + // in thread per connection mode where the thread per connection read + // call doesn't return when the transceiver is shutdown. + // +#ifdef _WIN32 + if(communicator->getProperties()->getPropertyAsInt("Ice.ThreadPerConnection") == 0) + { +#endif + backgroundController->pauseCall("getClientProxy"); + try + { + obj->ice_ping(); + test(false); + } + catch(const Ice::TimeoutException&) + { + } + backgroundController->resumeCall("getClientProxy"); +#ifdef _WIN32 + } +#endif + + obj = communicator->stringToProxy("router:default -p 12010 -t 10000"); + router = Ice::RouterPrx::uncheckedCast(obj); + obj = communicator->stringToProxy("background@Test")->ice_router(router); + BackgroundPrx bg = BackgroundPrx::uncheckedCast(obj); + test(bg->ice_getRouter()); + + backgroundController->pauseCall("getClientProxy"); + OpAMICallbackPtr cb = new OpAMICallback(); + bg->op_async(cb); + OpAMICallbackPtr cb2 = new OpAMICallback(); + bg->op_async(cb2); + test(!cb->response(false)); + test(!cb2->response(false)); + backgroundController->resumeCall("getClientProxy"); + test(cb->response(true)); + test(cb2->response(true)); + } + cout << "ok" << endl; + + return background; +} + +void +connectTests(const ConfigurationPtr& configuration, const Test::BackgroundPrx& background) +{ + try + { + background->op(); + } + catch(const Ice::LocalException&) + { + test(false); + } + background->ice_getConnection()->close(false); + + try + { + configuration->connectorsException(new Ice::DNSException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::DNSException&) + { + configuration->connectorsException(0); + } + + OpExAMICallbackPtr cbEx = new OpExAMICallback(); + + configuration->connectorsException(new Ice::DNSException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->connectorsException(0); + + configuration->connectorsException(new Ice::DNSException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->connectorsException(0); + + try + { + configuration->connectException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->connectException(0); + } + + configuration->connectException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->connectException(0); + + configuration->connectException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->connectException(0); + + OpThreadPtr thread1 = new OpThread(background); + OpThreadPtr thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + test(false); + } + + configuration->connectException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_getCachedConnection()->close(true); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + configuration->connectException(0); + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + } + } + + thread1->destroy(); + thread2->destroy(); + + thread1->getThreadControl().join(); + thread2->getThreadControl().join(); +} + +void +initializeTests(const ConfigurationPtr& configuration, + const Test::BackgroundPrx& background, + const Test::BackgroundControllerPrx& ctl) +{ + try + { + background->op(); + } + catch(const Ice::LocalException& ex) + { + cerr << ex << endl; + test(false); + } + background->ice_getConnection()->close(false); + + try + { + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->initializeException(0); + } + + OpExAMICallbackPtr cbEx = new OpExAMICallback(); + + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->initializeException(0); + + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->initializeException(0); + + try + { + configuration->initializeSocketStatus(IceInternal::NeedWrite); + background->op(); + configuration->initializeSocketStatus(IceInternal::Finished); + } + catch(const Ice::LocalException&) + { + test(false); + } + background->ice_getConnection()->close(false); + + try + { + configuration->initializeSocketStatus(IceInternal::NeedConnect); + background->op(); + configuration->initializeSocketStatus(IceInternal::Finished); + } + catch(const Ice::LocalException&) + { + test(false); + } + background->ice_getConnection()->close(false); + + try + { + configuration->initializeSocketStatus(IceInternal::NeedWrite); + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->initializeException(0); + configuration->initializeSocketStatus(IceInternal::Finished); + } + + configuration->initializeSocketStatus(IceInternal::NeedWrite); + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->initializeException(0); + configuration->initializeSocketStatus(IceInternal::Finished); + + configuration->initializeSocketStatus(IceInternal::NeedWrite); + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->initializeException(0); + configuration->initializeSocketStatus(IceInternal::Finished); + + // + // Now run the same tests with the server side. + // + + try + { + ctl->initializeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->initializeException(false); + } + catch(const Ice::SecurityException&) + { + ctl->initializeException(false); + } + + try + { + ctl->initializeSocketStatus(IceInternal::NeedWrite); + background->op(); + ctl->initializeSocketStatus(IceInternal::Finished); + } + catch(const Ice::LocalException&) + { + test(false); + } + background->ice_getConnection()->close(false); + + try + { + ctl->initializeSocketStatus(IceInternal::NeedWrite); + ctl->initializeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->initializeException(false); + ctl->initializeSocketStatus(IceInternal::Finished); + } + catch(const Ice::SecurityException&) + { + ctl->initializeException(false); + ctl->initializeSocketStatus(IceInternal::Finished); + } + + OpThreadPtr thread1 = new OpThread(background); + OpThreadPtr thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + test(false); + } + + configuration->initializeException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_getCachedConnection()->close(true); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + configuration->initializeException(0); + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + } + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + test(false); + } + + configuration->initializeSocketStatus(IceInternal::NeedWrite); + background->ice_getCachedConnection()->close(true); + background->ice_ping(); + configuration->initializeSocketStatus(IceInternal::Finished); + + ctl->initializeException(true); + background->ice_getCachedConnection()->close(true); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + ctl->initializeException(false); + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + } + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + ctl->initializeSocketStatus(IceInternal::NeedWrite); + background->ice_getCachedConnection()->close(true); + background->op(); + ctl->initializeSocketStatus(IceInternal::Finished); + } + catch(const Ice::LocalException& ex) + { + cerr << ex << endl; + test(false); + } + } + + thread1->destroy(); + thread2->destroy(); + + thread1->getThreadControl().join(); + thread2->getThreadControl().join(); +} + +void +validationTests(const ConfigurationPtr& configuration, + const Test::BackgroundPrx& background, + const Test::BackgroundControllerPrx& ctl) +{ + try + { + background->op(); + } + catch(const Ice::LocalException&) + { + test(false); + } + background->ice_getConnection()->close(false); + + try + { + // Get the read() of connection validation to throw right away. + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->readException(0); + } + + OpExAMICallbackPtr cbEx = new OpExAMICallback(); + + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readException(0); + + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readException(0); + + if(background->ice_getCommunicator()->getProperties()->getProperty("Ice.Default.Protocol") != "test-ssl") + { + try + { + // Get the read() of the connection validation to return "would block" + configuration->readReady(false); + background->op(); + configuration->readReady(true); + } + catch(const Ice::LocalException& ex) + { + cerr << ex << endl; + test(false); + } + background->ice_getConnection()->close(false); + + try + { + // Get the read() of the connection validation to return "would block" and then throw. + configuration->readReady(false); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->readException(0); + configuration->readReady(true); + } + + configuration->readReady(false); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readException(0); + configuration->readReady(true); + + configuration->readReady(false); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readException(0); + configuration->readReady(true); + } + + ctl->holdAdapter(); // Hold to block in connection validation + OpAMICallbackPtr cb = new OpAMICallback(); + background->op_async(cb); + OpAMICallbackPtr cb2 = new OpAMICallback(); + background->op_async(cb2); + test(!cb->response(false)); + test(!cb2->response(false)); + ctl->resumeAdapter(); + test(cb->response(true)); + test(cb2->response(true)); + + try + { + // Get the write() of connection validation to throw right away. + ctl->writeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->writeException(false); + } + + try + { + // Get the write() of the connection validation to return "would block" + ctl->writeReady(false); + background->op(); + ctl->writeReady(true); + } + catch(const Ice::LocalException& ex) + { + cerr << ex << endl; + test(false); + } + background->ice_getConnection()->close(false); + + try + { + // Get the write() of the connection validation to return "would block" and then throw. + ctl->writeReady(false); + ctl->writeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->writeException(false); + ctl->writeReady(true); + } + + Ice::ByteSeq seq; + seq.resize(512 * 1024); + + BackgroundPrx backgroundBatchOneway = BackgroundPrx::uncheckedCast(background->ice_batchOneway()); + + // + // First send small requests to test without auto-flushing. + // + backgroundBatchOneway->ice_getConnection()->close(false); + try + { + backgroundBatchOneway->ice_ping(); + test(false); + } + catch(const Ice::CloseConnectionException&) + { + } + ctl->holdAdapter(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + ctl->resumeAdapter(); + backgroundBatchOneway->ice_flushBatchRequests(); + + // + // Send bigger requests to test with auto-flushing. + // + backgroundBatchOneway->ice_getConnection()->close(false); + try + { + backgroundBatchOneway->ice_ping(); + test(false); + } + catch(const Ice::CloseConnectionException&) + { + } + ctl->holdAdapter(); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + ctl->resumeAdapter(); + backgroundBatchOneway->ice_flushBatchRequests(); + + // + // Then try the same thing with async flush. + // + + backgroundBatchOneway->ice_getConnection()->close(false); + try + { + backgroundBatchOneway->ice_ping(); + test(false); + } + catch(const Ice::CloseConnectionException&) + { + } + ctl->holdAdapter(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + backgroundBatchOneway->op(); + ctl->resumeAdapter(); + backgroundBatchOneway->ice_flushBatchRequests_async(new FlushBatchRequestsCallback()); + backgroundBatchOneway->ice_getConnection()->close(false); + + backgroundBatchOneway->ice_getConnection()->close(false); + try + { + backgroundBatchOneway->ice_ping(); + test(false); + } + catch(const Ice::CloseConnectionException&) + { + } + ctl->holdAdapter(); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + backgroundBatchOneway->opWithPayload(seq); + ctl->resumeAdapter(); + FlushBatchRequestsCallbackPtr fcb = new FlushBatchRequestsCallback(); + backgroundBatchOneway->ice_flushBatchRequests_async(fcb); + // + // We can't close the connection before ensuring all the batches have been sent since + // with auto-flushing the close connection message might be sent once the first call + // opWithPayload is sent and before the flushBatchRequests (this would therefore result + // in the flush to report a CloseConnectionException). Instead we flush a second time + // with the same callback to wait for the first flush to complete. + // + //backgroundBatchOneway->ice_getConnection()->close(false); + backgroundBatchOneway->ice_flushBatchRequests_async(fcb); + backgroundBatchOneway->ice_getConnection()->close(false); +} + +void +readWriteTests(const ConfigurationPtr& configuration, + const Test::BackgroundPrx& background, + const Test::BackgroundControllerPrx& ctl) +{ + try + { + background->op(); + } + catch(const Ice::LocalException& ex) + { + cerr << ex << endl; + test(false); + } + + try + { + background->ice_ping(); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->writeException(0); + } + + OpExAMICallbackPtr cbEx = new OpExAMICallback(); + + background->ice_ping(); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->writeException(0); + + background->ice_ping(); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->writeException(0); + + try + { + background->ice_ping(); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->readException(0); + } + + background->ice_ping(); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readException(0); + + try + { + background->ice_ping(); + configuration->writeReady(false); + background->op(); + configuration->writeReady(true); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + background->ice_ping(); + configuration->readReady(false); + background->op(); + configuration->readReady(true); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + background->ice_ping(); + configuration->writeReady(false); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->writeReady(true); + configuration->writeException(0); + } + + background->ice_ping(); + configuration->writeReady(false); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->writeReady(true); + configuration->writeException(0); + + background->ice_ping(); + configuration->writeReady(false); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + background->ice_oneway()->op_async(cbEx); + test(cbEx->exception(true)); + configuration->writeReady(true); + configuration->writeException(0); + + try + { + background->ice_ping(); + configuration->readReady(false); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op(); + test(false); + } + catch(const Ice::SocketException&) + { + configuration->readException(0); + configuration->readReady(true); + } + + background->ice_ping(); + configuration->readReady(false); + configuration->readException(new Ice::SocketException(__FILE__, __LINE__)); + background->op_async(cbEx); + test(cbEx->exception(true)); + configuration->readReady(true); + configuration->readException(0); + + background->ice_ping(); // Establish the connection + + BackgroundPrx backgroundOneway = BackgroundPrx::uncheckedCast(background->ice_oneway()); + test(backgroundOneway->ice_getConnection() == background->ice_getConnection()); + + ctl->holdAdapter(); // Hold to block in request send. + + Ice::ByteSeq seq; + seq.resize(512 * 1024); + backgroundOneway->opWithPayload_async(new OpWithPayloadOnewayAMICallback(), seq); + OpAMICallbackPtr cb = new OpAMICallback(); + background->op_async(cb); + OpAMICallbackPtr cb2 = new OpAMICallback(); + background->op_async(cb2); + backgroundOneway->opWithPayload_async(new OpWithPayloadOnewayAMICallback(), seq); + backgroundOneway->opWithPayload_async(new OpWithPayloadOnewayAMICallback(), seq); + test(!cb->response(false)); + test(!cb2->response(false)); + ctl->resumeAdapter(); + test(cb->response(true)); + test(cb2->response(true)); + + try + { + background->ice_ping(); + ctl->writeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->writeException(false); + } + + try + { + background->ice_ping(); + ctl->readException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->readException(false); + } + + try + { + background->ice_ping(); + ctl->writeReady(false); + background->op(); + ctl->writeReady(true); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + background->ice_ping(); + ctl->readReady(false); + background->op(); + ctl->readReady(true); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + background->ice_ping(); + ctl->writeReady(false); + ctl->writeException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->writeException(false); + ctl->writeReady(true); + } + + try + { + background->ice_ping(); + ctl->readReady(false); + ctl->readException(true); + background->op(); + test(false); + } + catch(const Ice::ConnectionLostException&) + { + ctl->readException(false); + ctl->readReady(true); + } + + OpThreadPtr thread1 = new OpThread(background); + OpThreadPtr thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background->ice_ping(); + } + catch(const Ice::LocalException&) + { + test(false); + } + + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + configuration->writeException(new Ice::SocketException(__FILE__, __LINE__)); + try + { + background->op(); + } + catch(const Ice::LocalException&) + { + } + configuration->writeException(0); + + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + + background->ice_ping(); + background->ice_getCachedConnection()->close(true); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); + + background->ice_getCachedConnection()->close(true); + } + + thread1->destroy(); + thread2->destroy(); + + thread1->getThreadControl().join(); + thread2->getThreadControl().join(); +} diff --git a/cpp/test/Ice/background/Client.cpp b/cpp/test/Ice/background/Client.cpp new file mode 100644 index 00000000000..93ec94c5770 --- /dev/null +++ b/cpp/test/Ice/background/Client.cpp @@ -0,0 +1,78 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> +#include <Configuration.h> + +using namespace std; +using namespace Test; + +int +run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator) +{ + BackgroundPrx allTests(const Ice::CommunicatorPtr&); + BackgroundPrx background = allTests(communicator); + background->shutdown(); + return EXIT_SUCCESS; +} + +int +main(int argc, char* argv[]) +{ + int status; + Ice::CommunicatorPtr communicator; + + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + + // + // For this test, we want to disable retries. + // + initData.properties->setProperty("Ice.RetryIntervals", "-1"); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties->setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + initData.properties->setProperty("Ice.Plugin.Test", "TestTransport:createTestTransport"); + string defaultProtocol = initData.properties->getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties->setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice::initialize(argc, argv, initData); + status = run(argc, argv, communicator); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + + if(communicator) + { + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + } + + return status; +} diff --git a/cpp/test/Ice/background/Configuration.cpp b/cpp/test/Ice/background/Configuration.cpp new file mode 100644 index 00000000000..d2f7e82a1c1 --- /dev/null +++ b/cpp/test/Ice/background/Configuration.cpp @@ -0,0 +1,182 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Configuration.h> + +Configuration* Configuration::_instance = 0; + +Configuration::Configuration() : + _initializeSocketStatus(IceInternal::Finished), + _initializeResetCount(0), + _readReadyCount(0), + _writeReadyCount(0) +{ + assert(!_instance); + _instance = this; +} + +Configuration::~Configuration() +{ + _instance = 0; +} + +void +Configuration::connectorsException(Ice::LocalException* ex) +{ + Lock sync(*this); + _connectorsException.reset(ex); +} + +void +Configuration::checkConnectorsException() +{ + Lock sync(*this); + if(_connectorsException.get()) + { + _connectorsException->ice_throw(); + } +} + +void +Configuration::connectException(Ice::LocalException* ex) +{ + Lock sync(*this); + _connectException.reset(ex); +} + +void +Configuration::checkConnectException() +{ + Lock sync(*this); + if(_connectException.get()) + { + _connectException->ice_throw(); + } +} + +void +Configuration::initializeSocketStatus(IceInternal::SocketStatus status) +{ + Lock sync(*this); + if(status == IceInternal::Finished) + { + _initializeResetCount = 0; + return; + } + _initializeResetCount = 10; + _initializeSocketStatus = status; +} + +void +Configuration::initializeException(Ice::LocalException* ex) +{ + Lock sync(*this); + _initializeException.reset(ex); +} + +IceInternal::SocketStatus +Configuration::initializeSocketStatus() +{ + Lock sync(*this); + if(_initializeResetCount == 0) + { + return IceInternal::Finished; + } + --_initializeResetCount; + return _initializeSocketStatus; +} + +void +Configuration::checkInitializeException() +{ + Lock sync(*this); + if(_initializeException.get()) + { + _initializeException->ice_throw(); + } +} + +void +Configuration::readReady(bool ready) +{ + Lock sync(*this); + _readReadyCount = ready ? 0 : 10; +} + +void +Configuration::readException(Ice::LocalException* ex) +{ + Lock sync(*this); + _readException.reset(ex); +} + +bool +Configuration::readReady() +{ + Lock sync(*this); + if(_readReadyCount == 0) + { + return true; + } + --_readReadyCount; + return false; +} + +void +Configuration::checkReadException() +{ + Lock sync(*this); + if(_readException.get()) + { + _readException->ice_throw(); + } +} + +void +Configuration::writeReady(bool ready) +{ + Lock sync(*this); + _writeReadyCount = ready ? 0 : 10; +} + +void +Configuration::writeException(Ice::LocalException* ex) +{ + Lock sync(*this); + _writeException.reset(ex); +} + +bool +Configuration::writeReady() +{ + Lock sync(*this); + if(_writeReadyCount == 0) + { + return true; + } + --_writeReadyCount; + return false; +} + +void +Configuration::checkWriteException() +{ + Lock sync(*this); + if(_writeException.get()) + { + _writeException->ice_throw(); + } +} + +Configuration* +Configuration::getInstance() +{ + return _instance; +} + diff --git a/cpp/test/Ice/background/Configuration.h b/cpp/test/Ice/background/Configuration.h new file mode 100644 index 00000000000..3277bd8d5f8 --- /dev/null +++ b/cpp/test/Ice/background/Configuration.h @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_CONFIGURATION_H +#define TEST_CONFIGURATION_H + +#include <IceUtil/Shared.h> +#include <IceUtil/Handle.h> + +#include <Ice/LocalException.h> +#include <Ice/Selector.h> + +class Configuration; +typedef IceUtil::Handle<Configuration> ConfigurationPtr; + +class Configuration : public IceUtil::Shared, public IceUtil::Mutex +{ +public: + + Configuration(); + virtual ~Configuration(); + + virtual void connectorsException(Ice::LocalException*); + virtual void checkConnectorsException(); + + virtual void connectException(Ice::LocalException*); + virtual void checkConnectException(); + + virtual void initializeSocketStatus(IceInternal::SocketStatus); + virtual void initializeException(Ice::LocalException*); + virtual IceInternal::SocketStatus initializeSocketStatus(); + virtual void checkInitializeException(); + + virtual void readReady(bool); + virtual void readException(Ice::LocalException*); + virtual bool readReady(); + virtual void checkReadException(); + + virtual void writeReady(bool); + virtual void writeException(Ice::LocalException*); + virtual bool writeReady(); + virtual void checkWriteException(); + + static Configuration* getInstance(); + +private: + + std::auto_ptr<Ice::LocalException> _connectorsException; + std::auto_ptr<Ice::LocalException> _connectException; + IceInternal::SocketStatus _initializeSocketStatus; + int _initializeResetCount; + std::auto_ptr<Ice::LocalException> _initializeException; + int _readReadyCount; + std::auto_ptr<Ice::LocalException> _readException; + int _writeReadyCount; + std::auto_ptr<Ice::LocalException> _writeException; + + static Configuration* _instance; +}; + +#endif diff --git a/cpp/test/Ice/background/Connector.cpp b/cpp/test/Ice/background/Connector.cpp new file mode 100644 index 00000000000..9e75d4672c3 --- /dev/null +++ b/cpp/test/Ice/background/Connector.cpp @@ -0,0 +1,69 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Connector.h> +#include <Transceiver.h> +#include <EndpointI.h> + +using namespace std; + +IceInternal::TransceiverPtr +Connector::connect(int timeout) +{ + _configuration->checkConnectException(); + return new Transceiver(_connector->connect(timeout)); +} + +Ice::Short +Connector::type() const +{ + return (Ice::Short)(EndpointI::TYPE_BASE + _connector->type()); +} + +string +Connector::toString() const +{ + return _connector->toString(); +} + +bool +Connector::operator==(const IceInternal::Connector& r) const +{ + const Connector* p = dynamic_cast<const Connector*>(&r); + if(!p) + { + return false; + } + + return *_connector == *p->_connector; +} + +bool +Connector::operator!=(const IceInternal::Connector& r) const +{ + return !operator==(r); +} + +bool +Connector::operator<(const IceInternal::Connector& r) const +{ + const Connector* p = dynamic_cast<const Connector*>(&r); + if(!p) + { + return type() < r.type(); + } + + return *_connector < *p->_connector; +} + +Connector::Connector(const IceInternal::ConnectorPtr& connector) : + _connector(connector), + _configuration(Configuration::getInstance()) +{ +} diff --git a/cpp/test/Ice/background/Connector.h b/cpp/test/Ice/background/Connector.h new file mode 100644 index 00000000000..d8ffb10ea9a --- /dev/null +++ b/cpp/test/Ice/background/Connector.h @@ -0,0 +1,38 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_CONNECTOR_H +#define TEST_CONNECTOR_H + +#include <Ice/Connector.h> +#include <Configuration.h> + +class Connector : public IceInternal::Connector +{ +public: + + IceInternal::TransceiverPtr connect(int); + + Ice::Short type() const; + std::string toString() const; + + virtual bool operator==(const IceInternal::Connector&) const; + virtual bool operator!=(const IceInternal::Connector&) const; + virtual bool operator<(const IceInternal::Connector&) const; + +private: + + Connector(const IceInternal::ConnectorPtr& connector); + friend class EndpointI; + + const IceInternal::ConnectorPtr _connector; + const ConfigurationPtr _configuration; +}; + +#endif diff --git a/cpp/test/Ice/background/EndpointFactory.cpp b/cpp/test/Ice/background/EndpointFactory.cpp new file mode 100644 index 00000000000..70af767492a --- /dev/null +++ b/cpp/test/Ice/background/EndpointFactory.cpp @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/Instance.h> +#include <Ice/EndpointFactoryManager.h> + +#include <EndpointFactory.h> +#include <EndpointI.h> + +using namespace std; + +EndpointFactory::EndpointFactory(const IceInternal::EndpointFactoryPtr& factory) : + _factory(factory) +{ +} + +Ice::Short +EndpointFactory::type() const +{ + return (Ice::Short)(EndpointI::TYPE_BASE + _factory->type()); +} + +string +EndpointFactory::protocol() const +{ + return "test-" + _factory->protocol(); +} + +IceInternal::EndpointIPtr +EndpointFactory::create(const string& str, bool server) const +{ + return new EndpointI(_factory->create(str, server)); +} + +IceInternal::EndpointIPtr +EndpointFactory::read(IceInternal::BasicStream* s) const +{ + short type; + s->read(type); + assert(type == _factory->type()); + return new EndpointI(_factory->read(s)); +} + +void +EndpointFactory::destroy() +{ +} diff --git a/cpp/test/Ice/background/EndpointFactory.h b/cpp/test/Ice/background/EndpointFactory.h new file mode 100644 index 00000000000..b3a817b238c --- /dev/null +++ b/cpp/test/Ice/background/EndpointFactory.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ENDPOINT_FACTORY_H +#define TEST_ENDPOINT_FACTORY_H + +#include <Ice/EndpointFactory.h> + +class EndpointFactory : public IceInternal::EndpointFactory +{ +public: + + virtual ~EndpointFactory() { } + + virtual ::Ice::Short type() const; + virtual ::std::string protocol() const; + virtual IceInternal::EndpointIPtr create(const std::string&, bool) const; + virtual IceInternal::EndpointIPtr read(IceInternal::BasicStream*) const; + virtual void destroy(); + +protected: + + EndpointFactory(const IceInternal::EndpointFactoryPtr&); + friend class TestPluginI; + + IceInternal::EndpointFactoryPtr _factory; +}; + +#endif diff --git a/cpp/test/Ice/background/EndpointI.cpp b/cpp/test/Ice/background/EndpointI.cpp new file mode 100644 index 00000000000..ab83f97b08e --- /dev/null +++ b/cpp/test/Ice/background/EndpointI.cpp @@ -0,0 +1,266 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <EndpointI.h> +#include <Transceiver.h> +#include <Connector.h> +#include <Acceptor.h> +#include <Ice/BasicStream.h> + +using namespace std; + +Ice::Short EndpointI::TYPE_BASE = 100; + +EndpointI::EndpointI(const IceInternal::EndpointIPtr& endpoint) : + _endpoint(endpoint), + _configuration(Configuration::getInstance()) +{ +} + +void +EndpointI::streamWrite(IceInternal::BasicStream* s) const +{ + s->write(type()); + _endpoint->streamWrite(s); +} + +Ice::Short +EndpointI::type() const +{ + return (Ice::Short)(TYPE_BASE + _endpoint->type()); +} + +int +EndpointI::timeout() const +{ + return _endpoint->timeout(); +} + +IceInternal::EndpointIPtr +EndpointI::timeout(int timeout) const +{ + IceInternal::EndpointIPtr endpoint = _endpoint->timeout(timeout); + if(endpoint == _endpoint) + { + return const_cast<EndpointI*>(this); + } + else + { + return new EndpointI(endpoint); + } +} + +IceInternal::EndpointIPtr +EndpointI::connectionId(const string& connectionId) const +{ + IceInternal::EndpointIPtr endpoint = _endpoint->connectionId(connectionId); + if(endpoint == _endpoint) + { + return const_cast<EndpointI*>(this); + } + else + { + return new EndpointI(endpoint); + } +} + +bool +EndpointI::compress() const +{ + return _endpoint->compress(); +} + +IceInternal::EndpointIPtr +EndpointI::compress(bool compress) const +{ + IceInternal::EndpointIPtr endpoint = _endpoint->compress(compress); + if(endpoint == _endpoint) + { + return const_cast<EndpointI*>(this); + } + else + { + return new EndpointI(endpoint); + } +} + +bool +EndpointI::datagram() const +{ + return _endpoint->datagram(); +} + +bool +EndpointI::secure() const +{ + return _endpoint->secure(); +} + +bool +EndpointI::unknown() const +{ + return _endpoint->unknown(); +} + +IceInternal::TransceiverPtr +EndpointI::transceiver(IceInternal::EndpointIPtr& endpoint) const +{ + IceInternal::EndpointIPtr endpt = _endpoint; + IceInternal::TransceiverPtr transceiver = _endpoint->transceiver(endpt); + if(endpt == _endpoint) + { + endpoint = const_cast<EndpointI*>(this); + } + else + { + endpoint = new EndpointI(endpoint); + } + + if(transceiver) + { + return new Transceiver(transceiver); + } + else + { + return 0; + } +} + +vector<IceInternal::ConnectorPtr> +EndpointI::connectors() const +{ + _configuration->checkConnectorsException(); + vector<IceInternal::ConnectorPtr> c = _endpoint->connectors(); + for(vector<IceInternal::ConnectorPtr>::iterator p = c.begin(); p != c.end(); ++p) + { + *p = new Connector(*p); + } + return c; +} + +void +EndpointI::connectors_async(const IceInternal::EndpointI_connectorsPtr& cb) const +{ + class Callback : public IceInternal::EndpointI_connectors + { + public: + + Callback(const IceInternal::EndpointI_connectorsPtr& callback) : _callback(callback) + { + } + + void + connectors(const vector<IceInternal::ConnectorPtr>& connectors) + { + vector<IceInternal::ConnectorPtr> c; + for(vector<IceInternal::ConnectorPtr>::const_iterator p = connectors.begin(); p != connectors.end(); ++p) + { + c.push_back(new Connector(*p)); + } + _callback->connectors(c); + } + + void + exception(const Ice::LocalException& ex) + { + _callback->exception(ex); + } + + private: + + IceInternal::EndpointI_connectorsPtr _callback; + }; + + try + { + _configuration->checkConnectorsException(); + _endpoint->connectors_async(new Callback(cb)); + } + catch(const Ice::LocalException& ex) + { + cb->exception(ex); + } +} + +IceInternal::AcceptorPtr +EndpointI::acceptor(IceInternal::EndpointIPtr& endpoint, const string& adapterName) const +{ + IceInternal::AcceptorPtr p = new Acceptor(_endpoint->acceptor(endpoint, adapterName)); + endpoint = new EndpointI(endpoint); + return p; +} + +vector<IceInternal::EndpointIPtr> +EndpointI::expand() const +{ + vector<IceInternal::EndpointIPtr> e = _endpoint->expand(); + for(vector<IceInternal::EndpointIPtr>::iterator p = e.begin(); p != e.end(); ++p) + { + *p = (*p == _endpoint) ? const_cast<EndpointI*>(this) : new EndpointI(*p); + } + return e; +} + +bool +EndpointI::equivalent(const IceInternal::EndpointIPtr& endpoint) const +{ + const EndpointI* testEndpointI = dynamic_cast<const EndpointI*>(endpoint.get()); + if(!testEndpointI) + { + return false; + } + return testEndpointI->_endpoint->equivalent(_endpoint); +} + +string +EndpointI::toString() const +{ + return "test-" + _endpoint->toString(); +} + +bool +EndpointI::operator==(const IceInternal::EndpointI& r) const +{ + const EndpointI* p = dynamic_cast<const EndpointI*>(&r); + if(!p) + { + return false; + } + + if(this == p) + { + return true; + } + + + return *p->_endpoint == *_endpoint; +} + +bool +EndpointI::operator!=(const IceInternal::EndpointI& r) const +{ + return !operator==(r); +} + +bool +EndpointI::operator<(const IceInternal::EndpointI& r) const +{ + const EndpointI* p = dynamic_cast<const EndpointI*>(&r); + if(!p) + { + return type() < r.type(); + } + + if(this == p) + { + return false; + } + + return *p->_endpoint < *_endpoint; +} diff --git a/cpp/test/Ice/background/EndpointI.h b/cpp/test/Ice/background/EndpointI.h new file mode 100644 index 00000000000..71d41c3e095 --- /dev/null +++ b/cpp/test/Ice/background/EndpointI.h @@ -0,0 +1,63 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ENDPOINT_I_H +#define TEST_ENDPOINT_I_H + +#include <Ice/EndpointI.h> +#include <Configuration.h> + +class EndpointI : public IceInternal::EndpointI +{ +public: + + static Ice::Short TYPE_BASE; + + virtual void streamWrite(IceInternal::BasicStream*) const; + virtual Ice::Short type() const; + virtual Ice::Int timeout() const; + virtual IceInternal::EndpointIPtr timeout(Ice::Int) const; + virtual IceInternal::EndpointIPtr connectionId(const ::std::string&) const; + virtual bool compress() const; + virtual IceInternal::EndpointIPtr compress(bool) const; + virtual bool datagram() const; + virtual bool secure() const; + virtual bool unknown() const; + virtual IceInternal::TransceiverPtr transceiver(IceInternal::EndpointIPtr&) const; + virtual std::vector<IceInternal::ConnectorPtr> connectors() const; + virtual void connectors_async(const IceInternal::EndpointI_connectorsPtr&) const; + virtual IceInternal::AcceptorPtr acceptor(IceInternal::EndpointIPtr&, const std::string&) const; + virtual std::vector<IceInternal::EndpointIPtr> expand() const; + virtual bool equivalent(const IceInternal::EndpointIPtr&) const; + + virtual std::string toString() const; + + virtual bool operator==(const IceInternal::EndpointI&) const; + virtual bool operator!=(const IceInternal::EndpointI&) const; + virtual bool operator<(const IceInternal::EndpointI&) const; + +private: + + EndpointI(const IceInternal::EndpointIPtr&); + friend class EndpointFactory; + +#if defined(__SUNPRO_CC) || defined(__HP_aCC) + // + // COMPILERFIX: prevent the compiler from emitting a warning about + // hidding these operators. + // + using LocalObject::operator==; + using LocalObject::operator<; +#endif + + const IceInternal::EndpointIPtr _endpoint; + const ConfigurationPtr _configuration; +}; + +#endif diff --git a/cpp/test/Ice/background/Makefile b/cpp/test/Ice/background/Makefile new file mode 100644 index 00000000000..e8626b27943 --- /dev/null +++ b/cpp/test/Ice/background/Makefile @@ -0,0 +1,70 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client +SERVER = server + +TSPFILENAME = $(call mklibfilename,TestTransport,$(VERSION)) +TSPSONAME = $(call mksoname,TestTransport,$(SOVERSION)) +TSPLIBNAME = $(call mklibname,TestTransport) + +TARGETS = $(CLIENT) $(SERVER) $(call mklibtargets,$(TSPFILENAME),$(TSPSONAME),$(TSPLIBNAME)) + +COBJS = Configuration.o \ + Test.o \ + Client.o \ + AllTests.o + +SOBJS = Configuration.o \ + Test.o \ + TestI.o \ + Server.o + +TRANSPORT_OBJS = Configuration.o \ + Connector.o \ + Acceptor.o \ + EndpointI.o \ + Transceiver.o \ + EndpointFactory.o \ + PluginI.o + +SRCS = $(TRANSPORT_OBJS:.o=.cpp) \ + $(COBJS:.o=.cpp) \ + $(SOBJS:.o=.cpp) + +SLICE_SRCS = Test.ice + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include -I../../../src $(CPPFLAGS) +LINKWITH := $(BZIP2_RPATH_LINK) -lIce -lIceUtil + +$(CLIENT): $(COBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(COBJS) $(LIBS) + +$(SERVER): $(SOBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(SOBJS) $(LIBS) + +$(TSPFILENAME): $(TRANSPORT_OBJS) + rm -f $@ + $(call mkshlib,$@,$(TSPSONAME),$(OBJS) $(TRANSPORT_OBJS),$(LINKWITH)) + +$(TSPSONAME): $(TSPFILENAME) + rm -f $@ + ln -s $(TSPFILENAME) $@ + +$(TSPLIBNAME): $(TSPSONAME) + rm -f $@ + ln -s $(TSPSONAME) $@ + +include .depend diff --git a/cpp/test/Ice/background/Makefile.mak b/cpp/test/Ice/background/Makefile.mak new file mode 100644 index 00000000000..53066a048dd --- /dev/null +++ b/cpp/test/Ice/background/Makefile.mak @@ -0,0 +1,73 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ..\..\.. + +CLIENT = client.exe +SERVER = server.exe +LIBNAME = testtransport$(LIBSUFFIX).lib +DLLNAME = testtransport$(SOVERSION)$(LIBSUFFIX).dll + +TARGETS = $(CLIENT) $(SERVER) $(LIBNAME) $(DLLNAME) + +COBJS = Configuration.obj \ + Test.obj \ + Client.obj \ + AllTests.obj + +SOBJS = Configuration.obj \ + Test.obj \ + TestI.obj \ + Server.obj + +TRANSPORT_OBJS = Configuration.obj \ + Connector.obj \ + Acceptor.obj \ + EndpointI.obj \ + Transceiver.obj \ + EndpointFactory.obj \ + PluginI.obj + +SRCS = $(TRANSPORT_OBJS:.obj=.cpp) \ + $(COBJS:.obj=.cpp) \ + $(SOBJS:.obj=.cpp) + +!include $(top_srcdir)/config/Make.rules.mak + +CPPFLAGS = -I. -I../../include -I../../../src $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN +LINKWITH = $(LIBS) + +!if "$(CPP_COMPILER)" != "BCC2006" && "$(OPTIMIZE)" != "yes" +TPDBFLAGS = /pdb:$(DLLNAME:.dll=.pdb) +CPDBFLAGS = /pdb:$(CLIENT:.exe=.pdb) +SPDBFLAGS = /pdb:$(SERVER:.exe=.pdb) +!endif + +$(CLIENT): $(COBJS) + $(LINK) $(LD_EXEFLAGS) $(CPDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +$(SERVER): $(SOBJS) + $(LINK) $(LD_EXEFLAGS) $(SPDBFLAGS) $(SETARGV) $(SOBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest + +$(LIBNAME) : $(DLLNAME) + +$(DLLNAME): $(OBJS) $(TRANSPORT_OBJS) + $(LINK) $(LD_DLLFLAGS) $(TPDBFLAGS) $(SETARGV) $(OBJS) $(TRANSPORT_OBJS) $(PREOUT)$(DLLNAME) $(PRELIBS)$(LINKWITH) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#2 && del /q $@.manifest + @if exist $(DLLNAME:.dll=.exp) del /q $(DLLNAME:.dll=.exp) + +clean:: + del /q Test.cpp Test.h + +!include .depend diff --git a/cpp/test/Ice/background/PluginI.cpp b/cpp/test/Ice/background/PluginI.cpp new file mode 100644 index 00000000000..a00c0208482 --- /dev/null +++ b/cpp/test/Ice/background/PluginI.cpp @@ -0,0 +1,86 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/Initialize.h> +#include <Ice/Instance.h> +#include <Ice/ProtocolPluginFacade.h> +#include <Ice/EndpointFactoryManager.h> + +#include <PluginI.h> +#include <EndpointFactory.h> + +#ifndef TEST_TRANSPORT_API +# define TEST_TRANSPORT_API ICE_DECLSPEC_EXPORT +#endif + +using namespace std; + +class TestPluginI : public PluginI +{ +public: + + TestPluginI(const Ice::CommunicatorPtr&); + + virtual void initialize(); + virtual void destroy(); + + virtual ConfigurationPtr getConfiguration(); + +private: + + const Ice::CommunicatorPtr _communicator; + const ConfigurationPtr _configuration; +}; + + +// +// Plugin factory function. +// +extern "C" +{ + +TEST_TRANSPORT_API Ice::Plugin* +createTestTransport(const Ice::CommunicatorPtr& communicator, const string& name, const Ice::StringSeq& args) +{ + return new TestPluginI(communicator); +} + +} + +TestPluginI::TestPluginI(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator), + _configuration(new Configuration()) +{ +} + +void +TestPluginI::initialize() +{ + IceInternal::ProtocolPluginFacadePtr facade = IceInternal::getProtocolPluginFacade(_communicator); + + for(Ice::Short s = 0; s < 100; ++s) + { + IceInternal::EndpointFactoryPtr factory = facade->getEndpointFactory(s); + if(factory) + { + facade->addEndpointFactory(new EndpointFactory(factory)); + } + } +} + +void +TestPluginI::destroy() +{ +} + +ConfigurationPtr +TestPluginI::getConfiguration() +{ + return _configuration; +} diff --git a/cpp/test/Ice/background/PluginI.h b/cpp/test/Ice/background/PluginI.h new file mode 100644 index 00000000000..fffc0f16d1e --- /dev/null +++ b/cpp/test/Ice/background/PluginI.h @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_PLUGIN_H +#define TEST_PLUGIN_H + +#include <Ice/Plugin.h> +#include <Configuration.h> + +class PluginI : public Ice::Plugin +{ +public: + + virtual ConfigurationPtr getConfiguration() = 0; +}; + +#endif diff --git a/cpp/test/Ice/background/Server.cpp b/cpp/test/Ice/background/Server.cpp new file mode 100644 index 00000000000..45358ed96c7 --- /dev/null +++ b/cpp/test/Ice/background/Server.cpp @@ -0,0 +1,171 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <IceUtil/DisableWarnings.h> +#include <Ice/Ice.h> +#include <TestI.h> +#include <Configuration.h> +#include <PluginI.h> + +#include <Ice/Locator.h> +#include <Ice/Router.h> + +using namespace std; + +class LocatorI : public Ice::Locator +{ +public: + + virtual void + findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& response, const string& adapter, + const Ice::Current& current) const + { + _controller->checkCallPause(current); + Ice::CommunicatorPtr communicator = current.adapter->getCommunicator(); + response->ice_response(current.adapter->createDirectProxy(communicator->stringToIdentity("dummy"))); + } + + virtual void + findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& response, const Ice::Identity& id, + const Ice::Current& current) const + { + _controller->checkCallPause(current); + Ice::CommunicatorPtr communicator = current.adapter->getCommunicator(); + response->ice_response(current.adapter->createDirectProxy(id)); + } + + virtual Ice::LocatorRegistryPrx + getRegistry(const Ice::Current&) const + { + return 0; + } + + LocatorI(const BackgroundControllerIPtr& controller) : _controller(controller) + { + } + +private: + + BackgroundControllerIPtr _controller; +}; + +class RouterI : public Ice::Router +{ +public: + + virtual Ice::ObjectPrx + getClientProxy(const Ice::Current& current) const + { + _controller->checkCallPause(current); + return 0; + } + + virtual Ice::ObjectPrx + getServerProxy(const Ice::Current& current) const + { + _controller->checkCallPause(current); + return 0; + } + + virtual void + addProxy(const Ice::ObjectPrx&, const Ice::Current&) + { + } + + virtual Ice::ObjectProxySeq + addProxies(const Ice::ObjectProxySeq&, const Ice::Current&) + { + return Ice::ObjectProxySeq(); + } + + RouterI(const BackgroundControllerIPtr& controller) + { + _controller = controller; + } + +private: + + BackgroundControllerIPtr _controller; +}; + + +int +run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator) +{ + communicator->getProperties()->setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); + communicator->getProperties()->setProperty("ControllerAdapter.Endpoints", "tcp -p 12011"); + communicator->getProperties()->setProperty("ControllerAdapter.ThreadPool.Size", "1"); + + Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter"); + Ice::ObjectAdapterPtr adapter2 = communicator->createObjectAdapter("ControllerAdapter"); + + PluginI* plugin = dynamic_cast<PluginI*>(communicator->getPluginManager()->getPlugin("Test").get()); + assert(plugin); + ConfigurationPtr configuration = plugin->getConfiguration(); + BackgroundControllerIPtr backgroundController = new BackgroundControllerI(adapter, configuration); + + adapter->add(new BackgroundI(backgroundController), communicator->stringToIdentity("background")); + adapter->add(new LocatorI(backgroundController), communicator->stringToIdentity("locator")); + adapter->add(new RouterI(backgroundController), communicator->stringToIdentity("router")); + adapter->activate(); + + adapter2->add(backgroundController, communicator->stringToIdentity("backgroundController")); + adapter2->activate(); + + communicator->waitForShutdown(); + return EXIT_SUCCESS; +} + +int +main(int argc, char* argv[]) +{ + int status; + Ice::CommunicatorPtr communicator; + + try + { + Ice::InitializationData initData; + initData.properties = Ice::createProperties(argc, argv); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties->setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + initData.properties->setProperty("Ice.Plugin.Test", "TestTransport:createTestTransport"); + string defaultProtocol = initData.properties->getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties->setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice::initialize(argc, argv, initData); + status = run(argc, argv, communicator); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + + if(communicator) + { + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + } + + return status; +} diff --git a/cpp/test/Ice/background/Test.ice b/cpp/test/Ice/background/Test.ice new file mode 100644 index 00000000000..f85b9ac0065 --- /dev/null +++ b/cpp/test/Ice/background/Test.ice @@ -0,0 +1,46 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Background +{ + ["ami"] void op(); + ["ami"] void opWithPayload(Ice::ByteSeq seq); + + void shutdown(); +}; + +interface BackgroundController +{ + void pauseCall(string call); + void resumeCall(string call); + + void holdAdapter(); + void resumeAdapter(); + + void initializeSocketStatus(int status); + void initializeException(bool enable); + + void readReady(bool enable); + void readException(bool enable); + + void writeReady(bool enable); + void writeException(bool enable); +}; + +}; + +#endif diff --git a/cpp/test/Ice/background/TestI.cpp b/cpp/test/Ice/background/TestI.cpp new file mode 100644 index 00000000000..4883931db1b --- /dev/null +++ b/cpp/test/Ice/background/TestI.cpp @@ -0,0 +1,117 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <TestI.h> +#include <Ice/Ice.h> + +using namespace std; +using namespace Ice; + +void +BackgroundI::op(const Ice::Current& current) +{ + _controller->checkCallPause(current); +} + +void +BackgroundI::opWithPayload(const Ice::ByteSeq&, const Ice::Current& current) +{ + _controller->checkCallPause(current); +} + +void +BackgroundI::shutdown(const Ice::Current& current) +{ + current.adapter->getCommunicator()->shutdown(); +} + +BackgroundI::BackgroundI(const BackgroundControllerIPtr& controller) : + _controller(controller) +{ +} + +void +BackgroundControllerI::pauseCall(const string& opName, const Ice::Current&) +{ + Lock sync(*this); + _pausedCalls.insert(opName); +} + +void +BackgroundControllerI::resumeCall(const string& opName, const Ice::Current&) +{ + Lock sync(*this); + _pausedCalls.erase(opName); + notifyAll(); +} + +void +BackgroundControllerI::checkCallPause(const Ice::Current& current) +{ + Lock sync(*this); + while(_pausedCalls.find(current.operation) != _pausedCalls.end()) + { + wait(); + } +} + +void +BackgroundControllerI::holdAdapter(const Ice::Current&) +{ + _adapter->hold(); +} + +void +BackgroundControllerI::resumeAdapter(const Ice::Current&) +{ + _adapter->activate(); +} + +void +BackgroundControllerI::initializeSocketStatus(int status, const Ice::Current&) +{ + _configuration->initializeSocketStatus(static_cast<IceInternal::SocketStatus>(status)); +} + +void +BackgroundControllerI::initializeException(bool enable, const Ice::Current&) +{ + _configuration->initializeException(enable ? new Ice::SocketException(__FILE__, __LINE__) : 0); +} + +void +BackgroundControllerI::readReady(bool enable, const Ice::Current&) +{ + _configuration->readReady(enable); +} + +void +BackgroundControllerI::readException(bool enable, const Ice::Current&) +{ + _configuration->readException(enable ? new Ice::SocketException(__FILE__, __LINE__) : 0); +} + +void +BackgroundControllerI::writeReady(bool enable, const Ice::Current&) +{ + _configuration->writeReady(enable); +} + +void +BackgroundControllerI::writeException(bool enable, const Ice::Current&) +{ + _configuration->writeException(enable ? new Ice::SocketException(__FILE__, __LINE__) : 0); +} + +BackgroundControllerI::BackgroundControllerI(const Ice::ObjectAdapterPtr& adapter, + const ConfigurationPtr& configuration) : + _adapter(adapter), + _configuration(configuration) +{ +} diff --git a/cpp/test/Ice/background/TestI.h b/cpp/test/Ice/background/TestI.h new file mode 100644 index 00000000000..2acedc0489c --- /dev/null +++ b/cpp/test/Ice/background/TestI.h @@ -0,0 +1,66 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_I_H +#define TEST_I_H + +#include <Test.h> +#include <Configuration.h> + +#include <set> + +class BackgroundControllerI; +typedef IceUtil::Handle<BackgroundControllerI> BackgroundControllerIPtr; + +class BackgroundI : virtual public Test::Background +{ +public: + + virtual void op(const Ice::Current&); + virtual void opWithPayload(const Ice::ByteSeq&, const Ice::Current&); + virtual void shutdown(const Ice::Current&); + + BackgroundI(const BackgroundControllerIPtr&); + +private: + + BackgroundControllerIPtr _controller; +}; + +class BackgroundControllerI : public Test::BackgroundController, IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + + virtual void pauseCall(const std::string&, const Ice::Current&); + virtual void resumeCall(const std::string&, const Ice::Current&); + virtual void checkCallPause(const Ice::Current&); + + virtual void holdAdapter(const Ice::Current&); + virtual void resumeAdapter(const Ice::Current&); + + virtual void initializeSocketStatus(int, const Ice::Current&); + virtual void initializeException(bool, const Ice::Current&); + + virtual void readReady(bool, const Ice::Current&); + virtual void readException(bool, const Ice::Current&); + + virtual void writeReady(bool, const Ice::Current&); + virtual void writeException(bool, const Ice::Current&); + + BackgroundControllerI(const Ice::ObjectAdapterPtr&, const ConfigurationPtr&); + +private: + + Ice::ObjectAdapterPtr _adapter; + std::set<std::string> _pausedCalls; + ConfigurationPtr _configuration; +}; + +#endif diff --git a/cpp/test/Ice/background/Transceiver.cpp b/cpp/test/Ice/background/Transceiver.cpp new file mode 100644 index 00000000000..ddee56e5d23 --- /dev/null +++ b/cpp/test/Ice/background/Transceiver.cpp @@ -0,0 +1,143 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Transceiver.h> + +using namespace std; + +SOCKET +Transceiver::fd() +{ + return _transceiver->fd(); +} + +IceInternal::SocketStatus +Transceiver::initialize(int timeout) +{ + if(timeout == 0) + { + IceInternal::SocketStatus status = _configuration->initializeSocketStatus(); + if(status == IceInternal::NeedConnect) + { + return status; + } + else if(status == IceInternal::NeedWrite) + { + if(!_initialized) + { + status = _transceiver->initialize(timeout); + if(status != IceInternal::Finished) + { + return status; + } + _initialized = true; + } + return IceInternal::NeedWrite; + } + else if(status == IceInternal::NeedRead) + { + return status; + } + } + _configuration->checkInitializeException(); + if(!_initialized) + { + IceInternal::SocketStatus status = _transceiver->initialize(timeout); + if(status != IceInternal::Finished) + { + return status; + } + _initialized = true; + } + return IceInternal::Finished; +} + +void +Transceiver::close() +{ + _transceiver->close(); +} + +void +Transceiver::shutdownWrite() +{ + _transceiver->shutdownWrite(); +} + +void +Transceiver::shutdownReadWrite() +{ + _transceiver->shutdownReadWrite(); +} + +bool +Transceiver::write(IceInternal::Buffer& buf, int timeout) +{ + if(!_initialized) + { + throw Ice::SocketException(__FILE__, __LINE__); + } + + if(timeout == 0) + { + if(!_configuration->writeReady()) + { + return false; + } + } + _configuration->checkWriteException(); + return _transceiver->write(buf, timeout); +} + +bool +Transceiver::read(IceInternal::Buffer& buf, int timeout) +{ + if(!_initialized) + { + throw Ice::SocketException(__FILE__, __LINE__); + } + + if(timeout == 0) + { + if(!_configuration->readReady()) + { + return false; + } + } + _configuration->checkReadException(); + return _transceiver->read(buf, timeout); +} + +string +Transceiver::type() const +{ + return "test-" + _transceiver->type(); +} + +string +Transceiver::toString() const +{ + return _transceiver->toString(); +} + +void +Transceiver::checkSendSize(const IceInternal::Buffer& buf, size_t messageSizeMax) +{ + _transceiver->checkSendSize(buf, messageSizeMax); +} + +// +// Only for use by Connector, Acceptor +// +Transceiver::Transceiver(const IceInternal::TransceiverPtr& transceiver) : + _transceiver(transceiver), + _configuration(Configuration::getInstance()), + _initialized(false) +{ +} diff --git a/cpp/test/Ice/background/Transceiver.h b/cpp/test/Ice/background/Transceiver.h new file mode 100644 index 00000000000..1872f86bfc1 --- /dev/null +++ b/cpp/test/Ice/background/Transceiver.h @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_TRANSCEIVER_H +#define TEST_TRANSCEIVER_H + +#include <Ice/Transceiver.h> +#include <Configuration.h> + +class Transceiver : public IceInternal::Transceiver +{ +public: + + virtual SOCKET fd(); + virtual void close(); + virtual void shutdownWrite(); + virtual void shutdownReadWrite(); + virtual bool write(IceInternal::Buffer&, int); + virtual bool read(IceInternal::Buffer&, int); + virtual std::string type() const; + virtual std::string toString() const; + virtual IceInternal::SocketStatus initialize(int); + virtual void checkSendSize(const IceInternal::Buffer&, size_t); + +private: + + Transceiver(const IceInternal::TransceiverPtr&); + friend class Connector; + friend class Acceptor; + friend class EndpointI; + + const IceInternal::TransceiverPtr _transceiver; + const ConfigurationPtr _configuration; + bool _initialized; +}; + +#endif diff --git a/cpp/test/Ice/background/run.py b/cpp/test/Ice/background/run.py new file mode 100755 index 00000000000..598f980ea26 --- /dev/null +++ b/cpp/test/Ice/background/run.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +import os, sys + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")): + break +else: + raise "can't find toplevel directory!" + +sys.path.append(os.path.join(toplevel, "config")) +import TestUtil + +name = os.path.join("Ice", "background") +testdir = os.path.join(toplevel, "test", name) + +TestUtil.addLdPath(testdir) + +TestUtil.clientServerTest(name) +sys.exit(0) diff --git a/cpp/test/Ice/operations/AllTests.cpp b/cpp/test/Ice/operations/AllTests.cpp index 799560a8d5d..1c89beb032e 100644 --- a/cpp/test/Ice/operations/AllTests.cpp +++ b/cpp/test/Ice/operations/AllTests.cpp @@ -29,6 +29,11 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) derived->opDerived(); cout << "ok" << endl; + cout << "testing oneway operations... " << flush; + void oneways(const Ice::CommunicatorPtr&, const Test::MyClassPrx&); + oneways(communicator, cl); + cout << "ok" << endl; + if(!collocated) { cout << "testing twoway operations with AMI... " << flush; @@ -37,6 +42,11 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated) twowaysAMI(communicator, derived); cout << "ok" << endl; + cout << "testing oneway operations with AMI... " << flush; + void onewaysAMI(const Ice::CommunicatorPtr&, const Test::MyClassPrx&); + onewaysAMI(communicator, cl); + cout << "ok" << endl; + cout << "testing batch oneway operations... " << flush; void batchOneways(const Test::MyClassPrx&); batchOneways(cl); diff --git a/cpp/test/Ice/operations/BatchOneways.cpp b/cpp/test/Ice/operations/BatchOneways.cpp index f5242c3dee4..f315b0c065d 100644 --- a/cpp/test/Ice/operations/BatchOneways.cpp +++ b/cpp/test/Ice/operations/BatchOneways.cpp @@ -19,7 +19,6 @@ batchOneways(const Test::MyClassPrx& p) const Test::ByteS bs1(10 * 1024); const Test::ByteS bs2(99 * 1024); const Test::ByteS bs3(100 * 1024); - try { p->opByteSOneway(bs1); diff --git a/cpp/test/Ice/operations/Makefile b/cpp/test/Ice/operations/Makefile index 9f6fcb227ba..7b435d3989a 100644 --- a/cpp/test/Ice/operations/Makefile +++ b/cpp/test/Ice/operations/Makefile @@ -20,7 +20,9 @@ COBJS = Test.o \ Client.o \ AllTests.o \ Twoways.o \ + Oneways.o \ TwowaysAMI.o \ + OnewaysAMI.o \ BatchOneways.o SOBJS = Test.o \ @@ -36,7 +38,9 @@ COLOBJS = Test.o \ Collocated.o \ AllTests.o \ Twoways.o \ + Oneways.o \ TwowaysAMI.o \ + OnewaysAMI.o \ BatchOneways.o SRCS = $(COBJS:.o=.cpp) \ diff --git a/cpp/test/Ice/operations/Makefile.mak b/cpp/test/Ice/operations/Makefile.mak index f646d70ae33..ca773b8661a 100644 --- a/cpp/test/Ice/operations/Makefile.mak +++ b/cpp/test/Ice/operations/Makefile.mak @@ -20,7 +20,9 @@ COBJS = Test.obj \ Client.obj \ AllTests.obj \ Twoways.obj \ + Oneways.obj \ TwowaysAMI.obj \ + OnewaysAMI.obj \ BatchOneways.obj SOBJS = Test.obj \ @@ -36,7 +38,9 @@ COLOBJS = Test.obj \ Collocated.obj \ AllTests.obj \ Twoways.obj \ + Oneways.obj \ TwowaysAMI.obj \ + OnewaysAMI.obj \ BatchOneways.obj SRCS = $(COBJS:.obj=.cpp) \ diff --git a/cpp/test/Ice/operations/Oneways.cpp b/cpp/test/Ice/operations/Oneways.cpp new file mode 100644 index 00000000000..fcf890b0e50 --- /dev/null +++ b/cpp/test/Ice/operations/Oneways.cpp @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> + +using namespace std; + +void +oneways(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& proxy) +{ + Test::MyClassPrx p = Test::MyClassPrx::uncheckedCast(proxy->ice_oneway()); + + { + p->opVoid(); + } + + { + Ice::Byte b; + Ice::Byte r; + + try + { + r = p->opByte(Ice::Byte(0xff), Ice::Byte(0x0f), b); + test(false); + } + catch(const Ice::TwowayOnlyException&) + { + } + } + +} diff --git a/cpp/test/Ice/operations/OnewaysAMI.cpp b/cpp/test/Ice/operations/OnewaysAMI.cpp new file mode 100644 index 00000000000..20a6445b839 --- /dev/null +++ b/cpp/test/Ice/operations/OnewaysAMI.cpp @@ -0,0 +1,145 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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 <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> +#include <limits> + +using namespace std; + +class CallbackBase : public IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + CallbackBase() : + _called(false) + { + } + + virtual ~CallbackBase() + { + } + + bool check() + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + while(!_called) + { + if(!timedWait(IceUtil::Time::seconds(5))) + { + return false; + } + } + _called = false; + return true; + } + +protected: + + void called() + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + assert(!_called); + _called = true; + notify(); + } + +private: + + bool _called; +}; + +class AMI_MyClass_onewayOpVoidI : public Test::AMI_MyClass_opVoid, public CallbackBase +{ +public: + + virtual void ice_response() + { + called(); + } + + virtual void ice_exception(const ::Ice::Exception&) + { + test(false); + } +}; + +typedef IceUtil::Handle<AMI_MyClass_onewayOpVoidI> AMI_MyClass_onewayOpVoidIPtr; + +class AMI_MyClass_onewayOpVoidExI : public Test::AMI_MyClass_opVoid, public CallbackBase +{ +public: + + virtual void ice_response() + { + test(false); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + test(dynamic_cast<const ::Ice::NoEndpointException*>(&ex)); + called(); + } +}; + +typedef IceUtil::Handle<AMI_MyClass_onewayOpVoidExI> AMI_MyClass_onewayOpVoidExIPtr; + +class AMI_MyClass_onewayOpByteExI : public Test::AMI_MyClass_opByte, public CallbackBase +{ +public: + + virtual void ice_response(::Ice::Byte r, ::Ice::Byte b) + { + test(false); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + test(dynamic_cast<const ::Ice::TwowayOnlyException*>(&ex)); + called(); + } +}; + +typedef IceUtil::Handle<AMI_MyClass_onewayOpByteExI> AMI_MyClass_onewayOpByteExIPtr; + +void +onewaysAMI(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& proxy) +{ + Test::MyClassPrx p = Test::MyClassPrx::uncheckedCast(proxy->ice_oneway()); + + { + AMI_MyClass_onewayOpVoidIPtr cb = new AMI_MyClass_onewayOpVoidI(); + p->opVoid_async(cb); + // Let's check if we can reuse the same callback object for another call. + p->opVoid_async(cb); + } + + { + // Check that a call to a void operation raises NoEndpointException + // in the ice_exception() callback instead of at the point of call. + Test::MyClassPrx indirect = Test::MyClassPrx::uncheckedCast(p->ice_adapterId("dummy")); + AMI_MyClass_onewayOpVoidExIPtr cb = new AMI_MyClass_onewayOpVoidExI(); + try + { + indirect->opVoid_async(cb); + } + catch(const Ice::Exception&) + { + test(false); + } + test(cb->check()); + } + + { + AMI_MyClass_onewayOpByteExIPtr cb = new AMI_MyClass_onewayOpByteExI(); + p->opByte_async(cb, 0, 0); + test(cb->check()); + } +} diff --git a/cpp/test/Ice/operations/TestAMDI.cpp b/cpp/test/Ice/operations/TestAMDI.cpp index 0227c30075f..f3baed1e676 100644 --- a/cpp/test/Ice/operations/TestAMDI.cpp +++ b/cpp/test/Ice/operations/TestAMDI.cpp @@ -37,10 +37,13 @@ private: void MyDerivedClassI::shutdown_async(const Test::AMD_MyClass_shutdownPtr& cb, const Ice::Current& current) { - if(_opVoidThread) { - _opVoidThread->getThreadControl().join(); - _opVoidThread = 0; + IceUtil::Mutex::Lock sync(_opVoidMutex); + if(_opVoidThread) + { + _opVoidThread->getThreadControl().join(); + _opVoidThread = 0; + } } current.adapter->getCommunicator()->shutdown(); @@ -50,6 +53,7 @@ MyDerivedClassI::shutdown_async(const Test::AMD_MyClass_shutdownPtr& cb, const I void MyDerivedClassI::opVoid_async(const Test::AMD_MyClass_opVoidPtr& cb, const Ice::Current&) { + IceUtil::Mutex::Lock sync(_opVoidMutex); if(_opVoidThread) { _opVoidThread->getThreadControl().join(); diff --git a/cpp/test/Ice/operations/TestAMDI.h b/cpp/test/Ice/operations/TestAMDI.h index 7931398b7e8..bad7823a570 100644 --- a/cpp/test/Ice/operations/TestAMDI.h +++ b/cpp/test/Ice/operations/TestAMDI.h @@ -135,6 +135,7 @@ public: private: IceUtil::ThreadPtr _opVoidThread; + IceUtil::Mutex _opVoidMutex; }; #endif diff --git a/cpp/test/Ice/operations/TwowaysAMI.cpp b/cpp/test/Ice/operations/TwowaysAMI.cpp index 158f0c6df25..fb81868048f 100644 --- a/cpp/test/Ice/operations/TwowaysAMI.cpp +++ b/cpp/test/Ice/operations/TwowaysAMI.cpp @@ -42,7 +42,7 @@ public: IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); while(!_called) { - if(!timedWait(IceUtil::Time::seconds(5))) + if(!timedWait(IceUtil::Time::seconds(50000))) { return false; } @@ -50,7 +50,7 @@ public: _called = false; return true; } - + protected: void called() @@ -94,7 +94,7 @@ public: virtual void ice_exception(const ::Ice::Exception& ex) { - test(dynamic_cast<const ::Ice::TwowayOnlyException*>(&ex)); + test(dynamic_cast<const ::Ice::NoEndpointException*>(&ex)); called(); } }; @@ -131,7 +131,7 @@ public: virtual void ice_exception(const ::Ice::Exception& ex) { - test(dynamic_cast<const ::Ice::TwowayOnlyException*>(&ex)); + test(dynamic_cast<const ::Ice::NoEndpointException*>(&ex)); called(); } }; @@ -875,12 +875,13 @@ void twowaysAMI(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& p) { { - // Check that a call to a void operation raises TwowayOnlyException + // Check that a call to a void operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test::MyClassPrx oneway = Test::MyClassPrx::uncheckedCast(p->ice_oneway()); + Test::MyClassPrx indirect = Test::MyClassPrx::uncheckedCast(p->ice_adapterId("dummy")); AMI_MyClass_opVoidExIPtr cb = new AMI_MyClass_opVoidExI; - try { - oneway->opVoid_async(cb); + try + { + indirect->opVoid_async(cb); } catch(const Ice::Exception&) { @@ -890,13 +891,13 @@ twowaysAMI(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& p) } { - // Check that a call to a twoway operation raises TwowayOnlyException + // Check that a call to a twoway operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test::MyClassPrx oneway = Test::MyClassPrx::uncheckedCast(p->ice_oneway()); + Test::MyClassPrx indirect = Test::MyClassPrx::uncheckedCast(p->ice_adapterId("dummy")); AMI_MyClass_opByteExIPtr cb = new AMI_MyClass_opByteExI; try { - oneway->opByte_async(cb, 0, 0); + indirect->opByte_async(cb, 0, 0); } catch(const Ice::Exception&) { @@ -1345,7 +1346,7 @@ twowaysAMI(const Ice::CommunicatorPtr& communicator, const Test::MyClassPrx& p) Test::MyClassPrx p = Test::MyClassPrx::uncheckedCast( - ic->stringToProxy("test:default -p 12010 -t 10000")); + ic->stringToProxy("test:default -p 12010")); ic->getImplicitContext()->setContext(ctx); diff --git a/cpp/test/Ice/timeout/AllTests.cpp b/cpp/test/Ice/timeout/AllTests.cpp index 694604304f9..78ac425ad95 100644 --- a/cpp/test/Ice/timeout/AllTests.cpp +++ b/cpp/test/Ice/timeout/AllTests.cpp @@ -242,9 +242,6 @@ allTests(const Ice::CommunicatorPtr& communicator) cout << "testing AMI read timeout... " << flush; { // - // The resolution of AMI timeouts is limited by the connection monitor - // thread. We set Ice.MonitorConnections=1 (one second) in main(). - // // Expect TimeoutException. // TimeoutPrx to = TimeoutPrx::uncheckedCast(obj->ice_timeout(500)); @@ -267,9 +264,6 @@ allTests(const Ice::CommunicatorPtr& communicator) cout << "testing AMI write timeout... " << flush; { // - // The resolution of AMI timeouts is limited by the connection monitor - // thread. We set Ice.MonitorConnections=1 (one second) in main(). - // // Expect TimeoutException. // TimeoutPrx to = TimeoutPrx::uncheckedCast(obj->ice_timeout(500)); diff --git a/cpp/test/Ice/timeout/Client.cpp b/cpp/test/Ice/timeout/Client.cpp index b3c9c744c72..9cdc8a39d76 100644 --- a/cpp/test/Ice/timeout/Client.cpp +++ b/cpp/test/Ice/timeout/Client.cpp @@ -44,11 +44,6 @@ main(int argc, char* argv[]) // initData.properties->setProperty("Ice.Warn.Connections", "0"); - // - // Check for AMI timeouts every second. - // - initData.properties->setProperty("Ice.MonitorConnections", "1"); - communicator = Ice::initialize(argc, argv, initData); status = run(argc, argv, communicator); } diff --git a/cpp/test/IceStorm/federation2/run.py b/cpp/test/IceStorm/federation2/run.py index 737b106fbac..a960fbbc95f 100755 --- a/cpp/test/IceStorm/federation2/run.py +++ b/cpp/test/IceStorm/federation2/run.py @@ -298,6 +298,11 @@ sys.stdout.flush() onewayStatus = doTest(0, iceStormReference) print "ok" +# +# Give some time for the error to be reported +# +time.sleep(2) + if onewayStatus or expectorThread.matches(index) != 1: TestUtil.killServers() sys.exit(1) diff --git a/cpp/test/IceUtil/timer/Client.cpp b/cpp/test/IceUtil/timer/Client.cpp index 382a95175d1..d1e4a2ed474 100644 --- a/cpp/test/IceUtil/timer/Client.cpp +++ b/cpp/test/IceUtil/timer/Client.cpp @@ -28,7 +28,7 @@ public: } virtual void - run() + runTimerTask() { Lock sync(*this); ++_count; @@ -83,6 +83,13 @@ public: } } + void + clear() + { + _run = IceUtil::Time(); + _count = 0; + } + private: IceUtil::Time _run; @@ -101,19 +108,20 @@ int main(int argc, char* argv[]) TestTaskPtr task = new TestTask(); timer->schedule(task, IceUtil::Time()); task->waitForRun(); + task->clear(); while(true) { - TestTaskPtr task = new TestTask(); - timer->schedule(task, IceUtil::Time::milliSeconds(-10)); try { + timer->schedule(task, IceUtil::Time::milliSeconds(-10)); timer->schedule(task, IceUtil::Time()); - test(task->hasRun()); } catch(const IceUtil::IllegalArgumentException&) { break; } + task->waitForRun(); + task->clear(); } } diff --git a/cs/allTests.py b/cs/allTests.py index a80c810e9e4..b84057a195f 100755 --- a/cs/allTests.py +++ b/cs/allTests.py @@ -47,14 +47,15 @@ tests = [ \ "Ice/interceptor", \ "Ice/dictMapping", \ "Ice/seqMapping", \ + "Ice/background", \ "Ice/threads", \ "Glacier2/router", \ "Glacier2/attack", \ "IceGrid/simple" \ ] -if not TestUtil.mono: - tests += ["IceSSL/configuration"] +#if not TestUtil.mono: +# tests += ["IceSSL/configuration"] if __name__ == "__main__": TestUtil.run(tests) diff --git a/cs/src/Ice/BasicStream.cs b/cs/src/Ice/BasicStream.cs index 1fabcf0e147..77792acc08e 100644 --- a/cs/src/Ice/BasicStream.cs +++ b/cs/src/Ice/BasicStream.cs @@ -36,45 +36,42 @@ namespace IceInternal { BZ2_bzlibVersion(); } - catch(System.DllNotFoundException) + catch(DllNotFoundException) { _bzlibInstalled = false; } - catch(System.EntryPointNotFoundException) + catch(EntryPointNotFoundException) { _bzlibInstalled = false; } } - public BasicStream(IceInternal.Instance instance) + public BasicStream(Instance instance) { initialize(instance, false); } - public BasicStream(IceInternal.Instance instance, bool unlimited) + public BasicStream(Instance instance, bool unlimited) { initialize(instance, unlimited); } - private void initialize(IceInternal.Instance instance, bool unlimited) + private void initialize(Instance instance, bool unlimited) { instance_ = instance; + _buf = new Buffer(instance_.messageSizeMax()); _closure = null; _unlimited = unlimited; - allocate(1500); - _capacity = _buf.capacity(); - _limit = 0; - Debug.Assert(_buf.limit() == _capacity); - + _readEncapsStack = null; _writeEncapsStack = null; _readEncapsCache = null; _writeEncapsCache = null; - + _traceSlicing = -1; - + _sliceObjects = true; - + _messageSizeMax = instance_.messageSizeMax(); // Cached for efficiency. _seqDataStack = null; @@ -87,10 +84,8 @@ namespace IceInternal // public virtual void reset() { - _limit = 0; - _buf.limit(_capacity); - _buf.position(0); - + _buf.reset(); + if(_readEncapsStack != null) { Debug.Assert(_readEncapsStack.next == null); @@ -106,7 +101,7 @@ namespace IceInternal } } - public virtual IceInternal.Instance instance() + public virtual Instance instance() { return instance_; } @@ -131,18 +126,10 @@ namespace IceInternal other._closure = _closure; _closure = tmpClosure; - ByteBuffer tmpBuf = other._buf; + Buffer tmpBuf = other._buf; other._buf = _buf; _buf = tmpBuf; - - int tmpCapacity = other._capacity; - other._capacity = _capacity; - _capacity = tmpCapacity; - - int tmpLimit = other._limit; - other._limit = _limit; - _limit = tmpLimit; - + ReadEncaps tmpRead = other._readEncapsStack; other._readEncapsStack = _readEncapsStack; _readEncapsStack = tmpRead; @@ -179,51 +166,33 @@ namespace IceInternal other._unlimited = _unlimited; _unlimited = tmpUnlimited; } - - public virtual void resize(int total, bool reading) + + public virtual void resize(int sz, bool reading) { - if(!_unlimited && total > _messageSizeMax) - { - throw new Ice.MemoryLimitException("Message size > Ice.MessageSizeMax"); - } - if(total > _capacity) - { - int cap2 = _capacity << 1; - int newCapacity = cap2 > total ? cap2 : total; - _buf.limit(_limit); - reallocate(newCapacity); - _capacity = _buf.capacity(); - } // - // If this stream is used for reading, then we want to set - // the buffer's limit to the new total size. If this - // buffer is used for writing, then we must set the - // buffer's limit to the buffer's capacity. + // Check memory limit if stream is not unlimited. // - if(reading) + if(!_unlimited && sz > _messageSizeMax) { - _buf.limit(total); - } - else - { - _buf.limit(_capacity); + throw new Ice.MemoryLimitException("Message size > Ice.MessageSizeMax"); } - _buf.position(total); - _limit = total; + + _buf.resize(sz, reading); + _buf.b.position(sz); } - - public virtual ByteBuffer prepareRead() + + public virtual Buffer prepareWrite() { + _buf.b.limit(_buf.size()); + _buf.b.position(0); return _buf; } - - public virtual ByteBuffer prepareWrite() + + public virtual Buffer getBuffer() { - _buf.limit(_limit); - _buf.position(0); return _buf; } - + // // startSeq() and endSeq() sanity-check sequence sizes during // unmarshaling and prevent malicious messages with incorrect @@ -289,7 +258,7 @@ namespace IceInternal sd.previous = _seqDataStack; _seqDataStack = sd; - int bytesLeft = _buf.remaining(); + int bytesLeft = _buf.b.remaining(); if(_seqDataStack.previous == null) // Outermost sequence { // @@ -314,7 +283,7 @@ namespace IceInternal // public void checkSeq() { - checkSeq(_buf.remaining()); + checkSeq(_buf.b.remaining()); } public void checkSeq(int bytesLeft) @@ -336,7 +305,7 @@ namespace IceInternal public void checkFixedSeq(int numElements, int elemSize) { - int bytesLeft = _buf.remaining(); + int bytesLeft = _buf.b.remaining(); if(_seqDataStack == null) // Outermost sequence { // @@ -390,27 +359,27 @@ namespace IceInternal curr.next = _writeEncapsStack; _writeEncapsStack = curr; } - - _writeEncapsStack.start = _buf.position(); + + _writeEncapsStack.start = _buf.b.position(); writeInt(0); // Placeholder for the encapsulation length. writeByte(Protocol.encodingMajor); writeByte(Protocol.encodingMinor); } - + public virtual void endWriteEncaps() { Debug.Assert(_writeEncapsStack != null); int start = _writeEncapsStack.start; - int sz = _buf.position() - start; // Size includes size and version. - _buf.putInt(start, sz); - + int sz = _buf.size() - start; // Size includes size and version. + _buf.b.putInt(start, sz); + WriteEncaps curr = _writeEncapsStack; _writeEncapsStack = curr.next; curr.next = _writeEncapsCache; _writeEncapsCache = curr; _writeEncapsCache.reset(); } - + public virtual void startReadEncaps() { { @@ -427,9 +396,9 @@ namespace IceInternal curr.next = _readEncapsStack; _readEncapsStack = curr; } - - _readEncapsStack.start = _buf.position(); - + + _readEncapsStack.start = _buf.b.position(); + // // I don't use readSize() and writeSize() for // encapsulations, because when creating an encapsulation, @@ -444,12 +413,12 @@ namespace IceInternal throw new Ice.NegativeSizeException(); } - if(sz - 4 > _buf.limit()) + if(sz - 4 > _buf.b.limit()) { throw new Ice.UnmarshalOutOfBoundsException(); } _readEncapsStack.sz = sz; - + byte eMajor = readByte(); byte eMinor = readByte(); if(eMajor != Protocol.encodingMajor || eMinor > Protocol.encodingMinor) @@ -464,7 +433,7 @@ namespace IceInternal _readEncapsStack.encodingMajor = eMajor; _readEncapsStack.encodingMinor = eMinor; } - + public virtual void endReadEncaps() { Debug.Assert(_readEncapsStack != null); @@ -472,37 +441,37 @@ namespace IceInternal int sz = _readEncapsStack.sz; try { - _buf.position(start + sz); + _buf.b.position(start + sz); } catch(ArgumentOutOfRangeException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } - + ReadEncaps curr = _readEncapsStack; _readEncapsStack = curr.next; curr.next = _readEncapsCache; _readEncapsCache = curr; _readEncapsCache.reset(); } - + public virtual void checkReadEncaps() { Debug.Assert(_readEncapsStack != null); int start = _readEncapsStack.start; int sz = _readEncapsStack.sz; - if(_buf.position() != start + sz) + if(_buf.b.position() != start + sz) { throw new Ice.EncapsulationException(); } } - + public virtual int getReadEncapsSize() { Debug.Assert(_readEncapsStack != null); return _readEncapsStack.sz - 6; } - + public virtual void skipEncaps() { int sz = readInt(); @@ -512,26 +481,26 @@ namespace IceInternal } try { - _buf.position(_buf.position() + sz - 4); + _buf.b.position(_buf.b.position() + sz - 4); } catch(ArgumentOutOfRangeException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual void startWriteSlice() { writeInt(0); // Placeholder for the slice length. - _writeSlice = _buf.position(); + _writeSlice = _buf.size(); } - + public virtual void endWriteSlice() { - int sz = _buf.position() - _writeSlice + 4; - _buf.putInt(_writeSlice - 4, sz); + int sz = _buf.size() - _writeSlice + 4; + _buf.b.putInt(_writeSlice - 4, sz); } - + public virtual void startReadSlice() { int sz = readInt(); @@ -539,13 +508,13 @@ namespace IceInternal { throw new Ice.NegativeSizeException(); } - _readSlice = _buf.position(); + _readSlice = _buf.b.position(); } - + public virtual void endReadSlice() { } - + public virtual void skipSlice() { int sz = readInt(); @@ -555,29 +524,29 @@ namespace IceInternal } try { - _buf.position(_buf.position() + sz - 4); + _buf.b.position(_buf.b.position() + sz - 4); } catch(ArgumentOutOfRangeException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual void writeSize(int v) { if(v > 254) { expand(5); - _buf.put((byte)255); - _buf.putInt(v); + _buf.b.put((byte)255); + _buf.b.putInt(v); } else { expand(1); - _buf.put((byte)v); + _buf.b.put((byte)v); } } - + public virtual int readSize() { try @@ -585,11 +554,11 @@ namespace IceInternal // // COMPILERFIX: for some reasons _buf.get() doesn't work here on MacOS X with Mono; // - //byte b = _buf.get(); + //byte b = _buf.b.get(); byte b = readByte(); if(b == 255) { - int v = _buf.getInt(); + int v = _buf.b.getInt(); if(v < 0) { throw new Ice.NegativeSizeException(); @@ -606,7 +575,7 @@ namespace IceInternal throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual void writeTypeId(string id) { object o = _writeEncapsStack.typeIdMap[id]; @@ -623,7 +592,7 @@ namespace IceInternal writeString(id); } } - + public virtual string readTypeId() { string id; @@ -646,7 +615,7 @@ namespace IceInternal } return id; } - + public virtual void writeBlob(byte[] v) { if(v == null) @@ -654,14 +623,14 @@ namespace IceInternal return; } expand(v.Length); - _buf.put(v); + _buf.b.put(v); } - + public virtual void readBlob(byte[] v) { try { - _buf.get(v); + _buf.b.get(v); } catch(InvalidOperationException ex) { @@ -674,7 +643,7 @@ namespace IceInternal byte[] v = new byte[sz]; try { - _buf.get(v); + _buf.b.get(v); return v; } catch(InvalidOperationException ex) @@ -682,11 +651,11 @@ namespace IceInternal throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual void writeByte(byte v) { expand(1); - _buf.put(v); + _buf.b.put(v); } public virtual void writeByte(byte v, int end) @@ -697,7 +666,7 @@ namespace IceInternal } writeByte(v); } - + public virtual void writeByteSeq(byte[] v) { if(v == null) @@ -708,7 +677,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length); - _buf.put(v); + _buf.b.put(v); } } @@ -731,7 +700,7 @@ namespace IceInternal IEnumerator<byte> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.put(i.Current); + _buf.b.put(i.Current); } } else if(v is Queue<byte>) @@ -748,7 +717,7 @@ namespace IceInternal expand(count); foreach(byte b in v) { - _buf.put(b); + _buf.b.put(b); } } } @@ -757,7 +726,7 @@ namespace IceInternal { try { - return _buf.get(); + return _buf.b.get(); } catch(InvalidOperationException ex) { @@ -782,7 +751,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 1); byte[] v = new byte[sz]; - _buf.get(v); + _buf.b.get(v); return v; } catch(InvalidOperationException ex) @@ -838,7 +807,7 @@ namespace IceInternal public virtual void writeBool(bool v) { expand(1); - _buf.put(v ? (byte)1 : (byte)0); + _buf.b.put(v ? (byte)1 : (byte)0); } public virtual void writeBoolSeq(bool[] v) @@ -851,7 +820,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length); - _buf.putBoolSeq(v); + _buf.b.putBoolSeq(v); } } @@ -874,7 +843,7 @@ namespace IceInternal IEnumerator<bool> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.put(i.Current ? (byte)1 : (byte)0); + _buf.b.putBool(i.Current); } } else if(v is Queue<bool>) @@ -891,7 +860,7 @@ namespace IceInternal expand(count); foreach(bool b in v) { - _buf.put(b ? (byte)1 : (byte)0); + _buf.b.putBool(b); } } } @@ -900,14 +869,14 @@ namespace IceInternal { try { - return _buf.get() == 1; + return _buf.b.get() == 1; } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual bool[] readBoolSeq() { try @@ -915,7 +884,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 1); bool[] v = new bool[sz]; - _buf.getBoolSeq(v); + _buf.b.getBoolSeq(v); return v; } catch(InvalidOperationException ex) @@ -967,13 +936,13 @@ namespace IceInternal l.Push(array[i]); } } - + public virtual void writeShort(short v) { expand(2); - _buf.putShort(v); + _buf.b.putShort(v); } - + public virtual void writeShortSeq(short[] v) { if(v == null) @@ -984,7 +953,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length * 2); - _buf.putShortSeq(v); + _buf.b.putShortSeq(v); } } @@ -1007,7 +976,7 @@ namespace IceInternal IEnumerator<short> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.putShort(i.Current); + _buf.b.putShort(i.Current); } } else if(v is Queue<short>) @@ -1024,7 +993,7 @@ namespace IceInternal expand(count * 2); foreach(short s in v) { - writeShort(s); + _buf.b.putShort(s); } } } @@ -1033,14 +1002,14 @@ namespace IceInternal { try { - return _buf.getShort(); + return _buf.b.getShort(); } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual short[] readShortSeq() { try @@ -1048,7 +1017,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 2); short[] v = new short[sz]; - _buf.getShortSeq(v); + _buf.b.getShortSeq(v); return v; } catch(InvalidOperationException ex) @@ -1100,13 +1069,13 @@ namespace IceInternal l.Push(array[i]); } } - + public virtual void writeInt(int v) { expand(4); - _buf.putInt(v); + _buf.b.putInt(v); } - + public virtual void writeIntSeq(int[] v) { if(v == null) @@ -1117,7 +1086,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length * 4); - _buf.putIntSeq(v); + _buf.b.putIntSeq(v); } } @@ -1140,7 +1109,7 @@ namespace IceInternal IEnumerator<int> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.putInt(i.Current); + _buf.b.putInt(i.Current); } } else if(v is Queue<int>) @@ -1157,23 +1126,23 @@ namespace IceInternal expand(count * 4); foreach(int i in v) { - _buf.putInt(i); + _buf.b.putInt(i); } } } - + public virtual int readInt() { try { - return _buf.getInt(); + return _buf.b.getInt(); } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual int[] readIntSeq() { try @@ -1181,7 +1150,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 4); int[] v = new int[sz]; - _buf.getIntSeq(v); + _buf.b.getIntSeq(v); return v; } catch(InvalidOperationException ex) @@ -1209,7 +1178,7 @@ namespace IceInternal l = new LinkedList<int>(); for(int i = 0; i < sz; ++i) { - l.AddLast(_buf.getInt()); + l.AddLast(_buf.b.getInt()); } } catch(InvalidOperationException ex) @@ -1233,7 +1202,7 @@ namespace IceInternal l = new Queue<int>(sz); for(int i = 0; i < sz; ++i) { - l.Enqueue(_buf.getInt()); + l.Enqueue(_buf.b.getInt()); } } catch(InvalidOperationException ex) @@ -1255,13 +1224,13 @@ namespace IceInternal l.Push(array[i]); } } - + public virtual void writeLong(long v) { expand(8); - _buf.putLong(v); + _buf.b.putLong(v); } - + public virtual void writeLongSeq(long[] v) { if(v == null) @@ -1272,7 +1241,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length * 8); - _buf.putLongSeq(v); + _buf.b.putLongSeq(v); } } @@ -1295,7 +1264,7 @@ namespace IceInternal IEnumerator<long> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.putLong(i.Current); + _buf.b.putLong(i.Current); } } else if(v is Queue<long>) @@ -1312,7 +1281,7 @@ namespace IceInternal expand(count * 8); foreach(long l in v) { - _buf.putLong(l); + _buf.b.putLong(l); } } } @@ -1321,14 +1290,14 @@ namespace IceInternal { try { - return _buf.getLong(); + return _buf.b.getLong(); } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual long[] readLongSeq() { try @@ -1336,7 +1305,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 8); long[] v = new long[sz]; - _buf.getLongSeq(v); + _buf.b.getLongSeq(v); return v; } catch(InvalidOperationException ex) @@ -1344,7 +1313,7 @@ namespace IceInternal throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual void readLongSeq(out List<long> l) { // @@ -1364,7 +1333,7 @@ namespace IceInternal l = new LinkedList<long>(); for(int i = 0; i < sz; ++i) { - l.AddLast(_buf.getLong()); + l.AddLast(_buf.b.getLong()); } } catch(InvalidOperationException ex) @@ -1388,7 +1357,7 @@ namespace IceInternal l = new Queue<long>(sz); for(int i = 0; i < sz; ++i) { - l.Enqueue(_buf.getLong()); + l.Enqueue(_buf.b.getLong()); } } catch(InvalidOperationException ex) @@ -1414,9 +1383,9 @@ namespace IceInternal public virtual void writeFloat(float v) { expand(4); - _buf.putFloat(v); + _buf.b.putFloat(v); } - + public virtual void writeFloatSeq(float[] v) { if(v == null) @@ -1427,7 +1396,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length * 4); - _buf.putFloatSeq(v); + _buf.b.putFloatSeq(v); } } @@ -1450,7 +1419,7 @@ namespace IceInternal IEnumerator<float> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.putFloat(i.Current); + _buf.b.putFloat(i.Current); } } else if(v is Queue<float>) @@ -1467,7 +1436,7 @@ namespace IceInternal expand(count * 4); foreach(float f in v) { - _buf.putFloat(f); + _buf.b.putFloat(f); } } } @@ -1476,14 +1445,14 @@ namespace IceInternal { try { - return _buf.getFloat(); + return _buf.b.getFloat(); } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual float[] readFloatSeq() { try @@ -1491,7 +1460,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 4); float[] v = new float[sz]; - _buf.getFloatSeq(v); + _buf.b.getFloatSeq(v); return v; } catch(InvalidOperationException ex) @@ -1519,7 +1488,7 @@ namespace IceInternal l = new LinkedList<float>(); for(int i = 0; i < sz; ++i) { - l.AddLast(_buf.getFloat()); + l.AddLast(_buf.b.getFloat()); } } catch(InvalidOperationException ex) @@ -1543,7 +1512,7 @@ namespace IceInternal l = new Queue<float>(sz); for(int i = 0; i < sz; ++i) { - l.Enqueue(_buf.getFloat()); + l.Enqueue(_buf.b.getFloat()); } } catch(InvalidOperationException ex) @@ -1565,13 +1534,13 @@ namespace IceInternal l.Push(array[i]); } } - + public virtual void writeDouble(double v) { expand(8); - _buf.putDouble(v); + _buf.b.putDouble(v); } - + public virtual void writeDoubleSeq(double[] v) { if(v == null) @@ -1582,7 +1551,7 @@ namespace IceInternal { writeSize(v.Length); expand(v.Length * 8); - _buf.putDoubleSeq(v); + _buf.b.putDoubleSeq(v); } } @@ -1605,7 +1574,7 @@ namespace IceInternal IEnumerator<double> i = v.GetEnumerator(); while(i.MoveNext()) { - _buf.putDouble(i.Current); + _buf.b.putDouble(i.Current); } } else if(v is Queue<double>) @@ -1622,23 +1591,23 @@ namespace IceInternal expand(count * 8); foreach(double d in v) { - _buf.putDouble(d); + _buf.b.putDouble(d); } } } - + public virtual double readDouble() { try { - return _buf.getDouble(); + return _buf.b.getDouble(); } catch(InvalidOperationException ex) { throw new Ice.UnmarshalOutOfBoundsException(ex); } } - + public virtual double[] readDoubleSeq() { try @@ -1646,7 +1615,7 @@ namespace IceInternal int sz = readSize(); checkFixedSeq(sz, 8); double[] v = new double[sz]; - _buf.getDoubleSeq(v); + _buf.b.getDoubleSeq(v); return v; } catch(InvalidOperationException ex) @@ -1674,7 +1643,7 @@ namespace IceInternal l = new LinkedList<double>(); for(int i = 0; i < sz; ++i) { - l.AddLast(_buf.getDouble()); + l.AddLast(_buf.b.getDouble()); } } catch(InvalidOperationException ex) @@ -1698,7 +1667,7 @@ namespace IceInternal l = new Queue<double>(sz); for(int i = 0; i < sz; ++i) { - l.Enqueue(_buf.getDouble()); + l.Enqueue(_buf.b.getDouble()); } } catch(InvalidOperationException ex) @@ -1722,7 +1691,7 @@ namespace IceInternal } private static System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(false, true); - + public virtual void writeString(string v) { if(v == null || v.Length == 0) @@ -1733,9 +1702,9 @@ namespace IceInternal byte[] arr = utf8.GetBytes(v); writeSize(arr.Length); expand(arr.Length); - _buf.put(arr); + _buf.b.put(arr); } - + public virtual void writeStringSeq(string[] v) { if(v == null) @@ -1767,12 +1736,12 @@ namespace IceInternal public virtual string readString() { int len = readSize(); - + if(len == 0) { return ""; } - + try { // @@ -1783,7 +1752,7 @@ namespace IceInternal { _stringBytes = new byte[len]; } - _buf.get(_stringBytes, 0, len); + _buf.b.get(_stringBytes, 0, len); return utf8.GetString(_stringBytes, 0, len); } catch(InvalidOperationException ex) @@ -1800,7 +1769,7 @@ namespace IceInternal return ""; } } - + public virtual string[] readStringSeq() { int sz = readSize(); @@ -1891,12 +1860,12 @@ namespace IceInternal { instance_.proxyFactory().proxyToStream(v, this); } - + public virtual Ice.ObjectPrx readProxy() { return instance_.proxyFactory().streamToProxy(this); } - + public virtual void writeObject(Ice.Object v) { if(_writeEncapsStack == null) // Lazy initialization @@ -1911,7 +1880,7 @@ namespace IceInternal _writeEncapsStack = new WriteEncaps(); } } - + if(_writeEncapsStack.toBeMarshaledMap == null) // Lazy initialization { _writeEncapsStack.toBeMarshaledMap = new Hashtable(); @@ -1949,11 +1918,11 @@ namespace IceInternal writeInt(0); // Write null reference } } - - public virtual void readObject(IceInternal.IPatcher patcher) + + public virtual void readObject(IPatcher patcher) { Ice.Object v = null; - + if(_readEncapsStack == null) // Lazy initialization { _readEncapsStack = _readEncapsCache; @@ -1966,22 +1935,22 @@ namespace IceInternal _readEncapsStack = new ReadEncaps(); } } - + if(_readEncapsStack.patchMap == null) // Lazy initialization { _readEncapsStack.patchMap = new Hashtable(); _readEncapsStack.unmarshaledMap = new Hashtable(); _readEncapsStack.typeIdMap = new Hashtable(); } - + int index = readInt(); - + if(index == 0) { patcher.patch(null); return; } - + if(index < 0 && patcher != null) { int i = -index; @@ -2005,7 +1974,7 @@ namespace IceInternal patchReferences(null, i); return; } - + string mostDerivedId = readTypeId(); string id = string.Copy(mostDerivedId); @@ -2022,7 +1991,7 @@ namespace IceInternal ex.type = mostDerivedId; throw ex; } - + // // Try to find a factory registered for the specific // type. @@ -2032,7 +2001,7 @@ namespace IceInternal { v = userFactory.create(id); } - + // // If that fails, invoke the default factory if one // has been registered. @@ -2045,7 +2014,7 @@ namespace IceInternal v = userFactory.create(id); } } - + // // Last chance: check whether the class is // non-abstract and dynamically instantiate it using @@ -2059,7 +2028,7 @@ namespace IceInternal v = userFactory.create(id); } } - + if(v == null) { if(_sliceObjects) @@ -2088,7 +2057,7 @@ namespace IceInternal throw ex; } } - + int i = index; _readEncapsStack.unmarshaledMap[i] = v; @@ -2108,7 +2077,7 @@ namespace IceInternal return; } } - + public virtual void writeUserException(Ice.UserException v) { writeBool(v.usesClasses__()); @@ -2118,20 +2087,20 @@ namespace IceInternal writePendingObjects(); } } - + public virtual void throwException() { bool usesClasses = readBool(); - + string id = readString(); - + for(;;) { // // Look for a factory for this ID. // UserExceptionFactory factory = getUserExceptionFactory(id); - + if(factory != null) { // @@ -2182,7 +2151,7 @@ namespace IceInternal // a MarshalException. // } - + public virtual void writePendingObjects() { if(_writeEncapsStack != null && _writeEncapsStack.toBeMarshaledMap != null) @@ -2204,7 +2173,7 @@ namespace IceInternal _writeEncapsStack.marshaledMap[e.Key] = e.Value; writeInstance((Ice.Object)e.Key, (int)e.Value); } - + // // We have marshaled all the instances for this // pass, substract what we have marshaled from the @@ -2218,7 +2187,7 @@ namespace IceInternal } writeSize(0); // Zero marker indicates end of sequence of sequences of instances. } - + public virtual void readPendingObjects() { int num; @@ -2249,18 +2218,19 @@ namespace IceInternal } catch(System.Exception ex) { - instance_.initializationData().logger.warning("exception raised by ice_postUnmarshal::\n" + ex); + instance_.initializationData().logger.warning("exception raised by ice_postUnmarshal::\n" + + ex); } } } } - + public void sliceObjects(bool b) { _sliceObjects = b; } - + internal virtual void writeInstance(Ice.Object v, int index) { writeInt(index); @@ -2274,7 +2244,7 @@ namespace IceInternal } v.write__(this); } - + internal virtual void patchReferences(object instanceIndex, object patchIndex) { // @@ -2287,7 +2257,7 @@ namespace IceInternal // Debug.Assert( ((object)instanceIndex != null && (object)patchIndex == null) || ((object)instanceIndex == null && (object)patchIndex != null)); - + IceUtil.LinkedList patchlist; Ice.Object v; if((object)instanceIndex != null) @@ -2319,11 +2289,11 @@ namespace IceInternal } Debug.Assert(patchlist != null && patchlist.Count > 0); Debug.Assert(v != null); - + // // Patch all references that refer to the instance. // - foreach(IceInternal.IPatcher patcher in patchlist) + foreach(IPatcher patcher in patchlist) { try { @@ -2343,7 +2313,7 @@ namespace IceInternal throw nof; } } - + // // Clear out the patch map for that index -- there is // nothing left to patch for that index for the time @@ -2438,7 +2408,7 @@ namespace IceInternal // Compress the message body, but not the header. // int uncompressedLen = size() - headerSize; - byte[] uncompressed = _buf.rawBytes(headerSize, uncompressedLen); + byte[] uncompressed = _buf.b.rawBytes(headerSize, uncompressedLen); int compressedLen = (int)(uncompressedLen * 1.01 + 600); byte[] compressed = new byte[compressedLen]; @@ -2455,7 +2425,7 @@ namespace IceInternal ex.reason = getBZ2Error(rc); throw ex; } - + // // Don't bother if the compressed data is larger than the // uncompressed data. @@ -2468,12 +2438,12 @@ namespace IceInternal cstream = new BasicStream(instance_); cstream.resize(headerSize + 4 + compressedLen, false); cstream.pos(0); - + // // Copy the header from the uncompressed stream to the // compressed one. // - cstream._buf.put(_buf.rawBytes(0, headerSize)); + cstream._buf.b.put(_buf.b.rawBytes(0, headerSize)); // // Add the size of the uncompressed stream before the @@ -2484,7 +2454,7 @@ namespace IceInternal // // Add the compressed message body. // - cstream._buf.put(compressed, 0, compressedLen); + cstream._buf.b.put(compressed, 0, compressedLen); return true; } @@ -2512,7 +2482,7 @@ namespace IceInternal } int compressedLen = size() - headerSize - 4; - byte[] compressed = _buf.rawBytes(headerSize + 4, compressedLen); + byte[] compressed = _buf.b.rawBytes(headerSize + 4, compressedLen); int uncompressedLen = uncompressedSize - headerSize; byte[] uncompressed = new byte[uncompressedLen]; int rc = BZ2_bzBuffToBuffDecompress(uncompressed, ref uncompressedLen, compressed, compressedLen, 0, 0); @@ -2525,62 +2495,47 @@ namespace IceInternal BasicStream ucStream = new BasicStream(instance_); ucStream.resize(uncompressedSize, false); ucStream.pos(0); - ucStream._buf.put(_buf.rawBytes(0, headerSize)); - ucStream._buf.put(uncompressed, 0, uncompressedLen); + ucStream._buf.b.put(_buf.b.rawBytes(0, headerSize)); + ucStream._buf.b.put(uncompressed, 0, uncompressedLen); return ucStream; } - + internal virtual int pos() { - return _buf.position(); + return _buf.b.position(); } - + internal virtual void pos(int n) { - _buf.position(n); + _buf.b.position(n); } - + public virtual int size() { - return _limit; + return _buf.size(); } virtual internal bool isEmpty() { - return _limit == 0; + return _buf.empty(); } - - private void expand(int size) + + private void expand(int n) { - if(_buf.position() == _limit) - { - int oldLimit = _limit; - _limit += size; - if(!_unlimited && _limit > _messageSizeMax) - { - throw new Ice.MemoryLimitException("Message larger than Ice.MessageSizeMax"); - } - if(_limit > _capacity) - { - int cap2 = _capacity << 1; - int newCapacity = cap2 > _limit ? cap2 : _limit; - _buf.limit(oldLimit); - int pos = _buf.position(); - reallocate(newCapacity); - _capacity = _buf.capacity(); - _buf.limit(_capacity); - _buf.position(pos); - } + if(!_unlimited && _buf.b != null && _buf.b.position() + n > _messageSizeMax) + { + throw new Ice.MemoryLimitException("Message larger than Ice.MessageSizeMax"); } + _buf.expand(n); } - + private sealed class DynamicObjectFactory : Ice.ObjectFactory { internal DynamicObjectFactory(Type c) { _class = c; } - + public Ice.Object create(string type) { try @@ -2592,18 +2547,18 @@ namespace IceInternal throw new Ice.SyscallException(ex); } } - + public void destroy() { } - + private Type _class; } private Ice.ObjectFactory loadObjectFactory(string id) { Ice.ObjectFactory factory = null; - + try { Type c = AssemblyUtil.findType(typeToClass(id)); @@ -2650,17 +2605,17 @@ namespace IceInternal e.type = id; throw e; } - + return factory; } - + private sealed class DynamicUserExceptionFactory : UserExceptionFactory { internal DynamicUserExceptionFactory(Type c) { _class = c; } - + public void createAndThrow() { try @@ -2676,14 +2631,14 @@ namespace IceInternal throw new Ice.SyscallException(ex); } } - + public void destroy() { } - + private Type _class; } - + private UserExceptionFactory getUserExceptionFactory(string id) { UserExceptionFactory factory = null; @@ -2715,7 +2670,7 @@ namespace IceInternal } return factory; } - + private static string typeToClass(string id) { if(!id.StartsWith("::")) @@ -2725,58 +2680,19 @@ namespace IceInternal return id.Substring(2).Replace("::", "."); } - private void allocate(int size) - { - ByteBuffer buf = null; - try - { - buf = ByteBuffer.allocate(size); - } - catch(System.OutOfMemoryException ex) - { - Ice.MarshalException e = new Ice.MarshalException(ex); - e.reason = "OutOfMemoryException occurred while allocating a ByteBuffer"; - throw e; - } - buf.order(ByteBuffer.ByteOrder.LITTLE_ENDIAN); - _buf = buf; - } - - private void reallocate(int size) - { - // - // Limit the buffer size to MessageSizeMax - // - if(!_unlimited) - { - size = size > _messageSizeMax ? _messageSizeMax : size; - } - - ByteBuffer old = _buf; - Debug.Assert(old != null); - - allocate(size); - Debug.Assert(_buf != null); - - old.position(0); - _buf.put(old); - } - - private IceInternal.Instance instance_; + private Instance instance_; + private Buffer _buf; private object _closure; - private ByteBuffer _buf; - private int _capacity; // Cache capacity to avoid excessive method calls. - private int _limit; // Cache limit to avoid excessive method calls. private byte[] _stringBytes; // Reusable array for reading strings. - + private sealed class ReadEncaps { internal int start; internal int sz; - + internal byte encodingMajor; internal byte encodingMinor; - + internal Hashtable patchMap; internal Hashtable unmarshaledMap; internal int typeIdIndex; @@ -2794,11 +2710,11 @@ namespace IceInternal } } } - + private sealed class WriteEncaps { internal int start; - + internal int writeIndex; internal Hashtable toBeMarshaledMap; internal Hashtable marshaledMap; @@ -2818,20 +2734,20 @@ namespace IceInternal } } } - + private ReadEncaps _readEncapsStack; private WriteEncaps _writeEncapsStack; private ReadEncaps _readEncapsCache; private WriteEncaps _writeEncapsCache; - + private int _readSlice; private int _writeSlice; - + private int _traceSlicing; private string _slicingCat; - + private bool _sliceObjects; - + private int _messageSizeMax; private bool _unlimited; diff --git a/cs/src/Ice/Buffer.cs b/cs/src/Ice/Buffer.cs new file mode 100644 index 00000000000..26f3c3bbda6 --- /dev/null +++ b/cs/src/Ice/Buffer.cs @@ -0,0 +1,161 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +namespace IceInternal +{ + + // + // An instance of ByteBuffer cannot grow beyond its initial capacity. + // This class wraps a ByteBuffer and supports reallocation. + // + public class Buffer + { + public Buffer(int maxCapacity) + { + b = null; + _size = 0; + _capacity = 0; + _maxCapacity = maxCapacity; + } + + public int size() + { + return _size; + } + + public bool empty() + { + return _size == 0; + } + + public void clear() + { + b = null; + _size = 0; + _capacity = 0; + } + + // + // Call expand(n) to add room for n additional bytes. Note that expand() + // examines the current position of the buffer first; we don't want to + // expand the buffer if the caller is writing to a location that is + // already in the buffer. + // + public void expand(int n) + { + int sz = b == null ? n : b.position() + n; + if(sz > _size) + { + resize(sz, false); + } + } + + public void resize(int n, bool reading) + { + if(n == 0) + { + clear(); + } + else if(n > _capacity) + { + reserve(n); + } + _size = n; + + // + // When used for reading, we want to set the buffer's limit to the new size. + // + if(reading) + { + b.limit(_size); + } + } + + public void reset() + { + if(_size > 0 && _size * 2 < _capacity) + { + // + // If the current buffer size is smaller than the + // buffer capacity, we shrink the buffer memory to the + // current size. This is to avoid holding on to too much + // memory if it's not needed anymore. + // + if(++_shrinkCounter > 2) + { + reserve(_size); + _shrinkCounter = 0; + } + } + else + { + _shrinkCounter = 0; + } + _size = 0; + if(b != null) + { + b.limit(b.capacity()); + b.position(0); + } + } + + private void reserve(int n) + { + if(n > _capacity) + { + _capacity = System.Math.Max(n, System.Math.Min(2 * _capacity, _maxCapacity)); + _capacity = System.Math.Max(240, _capacity); + } + else if(n < _capacity) + { + _capacity = n; + } + else + { + return; + } + + try + { + ByteBuffer buf = ByteBuffer.allocate(_capacity); + + if(b == null) + { + b = buf; + } + else + { + int pos = b.position(); + b.position(0); + b.limit(System.Math.Min(_capacity, b.capacity())); + buf.put(b); + b = buf; + b.limit(b.capacity()); + b.position(pos); + } + + b.order(ByteBuffer.ByteOrder.LITTLE_ENDIAN); + } + catch(System.OutOfMemoryException ex) + { + Ice.MarshalException e = new Ice.MarshalException(ex); + e.reason = "OutOfMemoryException occurred while allocating a ByteBuffer"; + throw e; + } + } + + public ByteBuffer b; + + private int _size; + private int _capacity; // Cache capacity to avoid excessive method calls. + private int _maxCapacity; + private int _shrinkCounter; + } + +} diff --git a/cs/src/Ice/ByteBuffer.cs b/cs/src/Ice/ByteBuffer.cs index e173b2e9657..4d252fa9adf 100644 --- a/cs/src/Ice/ByteBuffer.cs +++ b/cs/src/Ice/ByteBuffer.cs @@ -114,7 +114,7 @@ namespace IceInternal { int len = remaining(); byte[] rc = new byte[len]; - Buffer.BlockCopy(_bytes, 0, rc, 0, len); + System.Buffer.BlockCopy(_bytes, 0, rc, 0, len); return rc; } @@ -138,7 +138,7 @@ namespace IceInternal throw new ArgumentException("startIndex + length must not exceed end mark of buffer"); } byte[] rc = new byte[length]; - Buffer.BlockCopy(_bytes, startIndex, rc, 0, length); + System.Buffer.BlockCopy(_bytes, startIndex, rc, 0, length); return rc; } @@ -146,7 +146,7 @@ namespace IceInternal { int len = buf.remaining(); checkOverflow(len); - Buffer.BlockCopy(buf._bytes, buf._position, _bytes, _position, len); + System.Buffer.BlockCopy(buf._bytes, buf._position, _bytes, _position, len); _position += len; return this; } @@ -154,12 +154,12 @@ namespace IceInternal public byte get() { checkUnderflow(1); - return Buffer.GetByte(_bytes, _position++); + return System.Buffer.GetByte(_bytes, _position++); } public ByteBuffer get(byte[] b) { - return get(b, 0, Buffer.ByteLength(b)); + return get(b, 0, System.Buffer.ByteLength(b)); } public ByteBuffer get(byte[] b, int offset, int length) @@ -168,13 +168,13 @@ namespace IceInternal { throw new ArgumentOutOfRangeException("offset", offset, "offset must be non-negative"); } - if(offset + length > Buffer.ByteLength(b)) + if(offset + length > System.Buffer.ByteLength(b)) { throw new ArgumentOutOfRangeException("length", length, "insufficient room beyond given offset in destination array"); } checkUnderflow(length); - Buffer.BlockCopy(_bytes, _position, b, offset, length); + System.Buffer.BlockCopy(_bytes, _position, b, offset, length); _position += length; return this; } @@ -182,13 +182,13 @@ namespace IceInternal public ByteBuffer put(byte b) { checkOverflow(1); - Buffer.SetByte(_bytes, _position++, b); + System.Buffer.SetByte(_bytes, _position++, b); return this; } public ByteBuffer put(byte[] b) { - return put(b, 0, Buffer.ByteLength(b)); + return put(b, 0, System.Buffer.ByteLength(b)); } public ByteBuffer put(byte[]b, int offset, int length) @@ -197,13 +197,13 @@ namespace IceInternal { throw new ArgumentOutOfRangeException("offset", offset, "offset must be non-negative"); } - if(offset + length > Buffer.ByteLength(b)) + if(offset + length > System.Buffer.ByteLength(b)) { throw new ArgumentOutOfRangeException("length", length, "insufficient data beyond given offset in source array"); } checkOverflow(length); - Buffer.BlockCopy(b, offset, _bytes, _position, length); + System.Buffer.BlockCopy(b, offset, _bytes, _position, length); _position += length; return this; } @@ -215,9 +215,9 @@ namespace IceInternal public void getBoolSeq(bool[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); _position += len; } @@ -228,9 +228,9 @@ namespace IceInternal public ByteBuffer putBoolSeq(bool[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; return this; } @@ -249,8 +249,8 @@ namespace IceInternal else { byte* p = (byte*)&ret; - *p++ = Buffer.GetByte(_bytes, _position + 1); - *p = Buffer.GetByte(_bytes, _position); + *p++ = System.Buffer.GetByte(_bytes, _position + 1); + *p = System.Buffer.GetByte(_bytes, _position); } _position += 2; return ret; @@ -258,11 +258,11 @@ namespace IceInternal public unsafe void getShortSeq(short[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); if(NO._o == _order) { - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); } else { @@ -272,8 +272,8 @@ namespace IceInternal { int index = i * 2; byte* q = (byte*)p; - *q++ = Buffer.GetByte(_bytes, _position + index + 1); - *q = Buffer.GetByte(_bytes, _position + index); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 1); + *q = System.Buffer.GetByte(_bytes, _position + index); } }; } @@ -294,19 +294,19 @@ namespace IceInternal else { byte* p = (byte*)&val; - Buffer.SetByte(_bytes, _position++, *(p + 1)); - Buffer.SetByte(_bytes, _position++, *p); + System.Buffer.SetByte(_bytes, _position++, *(p + 1)); + System.Buffer.SetByte(_bytes, _position++, *p); } return this; } public ByteBuffer putShortSeq(short[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); if(NO._o == _order) { - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; } else @@ -314,8 +314,8 @@ namespace IceInternal for(int i = 0; i < seq.Length; ++i) { int index = i * 2; - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 1)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 1)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index)); } } return this; @@ -335,10 +335,10 @@ namespace IceInternal else { byte* p = (byte*)&ret; - *p++ = Buffer.GetByte(_bytes, _position + 3); - *p++ = Buffer.GetByte(_bytes, _position + 2); - *p++ = Buffer.GetByte(_bytes, _position + 1); - *p = Buffer.GetByte(_bytes, _position); + *p++ = System.Buffer.GetByte(_bytes, _position + 3); + *p++ = System.Buffer.GetByte(_bytes, _position + 2); + *p++ = System.Buffer.GetByte(_bytes, _position + 1); + *p = System.Buffer.GetByte(_bytes, _position); } _position += 4; return ret; @@ -346,11 +346,11 @@ namespace IceInternal public unsafe void getIntSeq(int[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); if(NO._o == _order) { - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); } else { @@ -360,10 +360,10 @@ namespace IceInternal { int index = i * 4; byte* q = (byte*)p; - *q++ = Buffer.GetByte(_bytes, _position + index + 3); - *q++ = Buffer.GetByte(_bytes, _position + index + 2); - *q++ = Buffer.GetByte(_bytes, _position + index + 1); - *q = Buffer.GetByte(_bytes, _position + index); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 3); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 2); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 1); + *q = System.Buffer.GetByte(_bytes, _position + index); } } } @@ -397,21 +397,21 @@ namespace IceInternal else { byte* p = (byte*)&val; - Buffer.SetByte(_bytes, pos, *(p + 3)); - Buffer.SetByte(_bytes, pos + 1, *(p + 2)); - Buffer.SetByte(_bytes, pos + 2, *(p + 1)); - Buffer.SetByte(_bytes, pos + 3, *p); + System.Buffer.SetByte(_bytes, pos, *(p + 3)); + System.Buffer.SetByte(_bytes, pos + 1, *(p + 2)); + System.Buffer.SetByte(_bytes, pos + 2, *(p + 1)); + System.Buffer.SetByte(_bytes, pos + 3, *p); } return this; } public ByteBuffer putIntSeq(int[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); if(NO._o == _order) { - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; } else @@ -419,10 +419,10 @@ namespace IceInternal for(int i = 0; i < seq.Length; ++i) { int index = i * 4; - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 3)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 2)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 1)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 3)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 2)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 1)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index)); } } return this; @@ -442,14 +442,14 @@ namespace IceInternal else { byte* p = (byte*)&ret; - *p++ = Buffer.GetByte(_bytes, _position + 7); - *p++ = Buffer.GetByte(_bytes, _position + 6); - *p++ = Buffer.GetByte(_bytes, _position + 5); - *p++ = Buffer.GetByte(_bytes, _position + 4); - *p++ = Buffer.GetByte(_bytes, _position + 3); - *p++ = Buffer.GetByte(_bytes, _position + 2); - *p++ = Buffer.GetByte(_bytes, _position + 1); - *p = Buffer.GetByte(_bytes, _position); + *p++ = System.Buffer.GetByte(_bytes, _position + 7); + *p++ = System.Buffer.GetByte(_bytes, _position + 6); + *p++ = System.Buffer.GetByte(_bytes, _position + 5); + *p++ = System.Buffer.GetByte(_bytes, _position + 4); + *p++ = System.Buffer.GetByte(_bytes, _position + 3); + *p++ = System.Buffer.GetByte(_bytes, _position + 2); + *p++ = System.Buffer.GetByte(_bytes, _position + 1); + *p = System.Buffer.GetByte(_bytes, _position); } _position += 8; return ret; @@ -457,11 +457,11 @@ namespace IceInternal public unsafe void getLongSeq(long[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); if(NO._o == _order) { - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); } else { @@ -471,14 +471,14 @@ namespace IceInternal { int index = i * 8; byte* q = (byte*)p; - *q++ = Buffer.GetByte(_bytes, _position + index + 7); - *q++ = Buffer.GetByte(_bytes, _position + index + 6); - *q++ = Buffer.GetByte(_bytes, _position + index + 5); - *q++ = Buffer.GetByte(_bytes, _position + index + 4); - *q++ = Buffer.GetByte(_bytes, _position + index + 3); - *q++ = Buffer.GetByte(_bytes, _position + index + 2); - *q++ = Buffer.GetByte(_bytes, _position + index + 1); - *q = Buffer.GetByte(_bytes, _position + index); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 7); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 6); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 5); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 4); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 3); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 2); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 1); + *q = System.Buffer.GetByte(_bytes, _position + index); } } } @@ -499,25 +499,25 @@ namespace IceInternal else { byte* p = (byte*)&val; - Buffer.SetByte(_bytes, _position++, *(p + 7)); - Buffer.SetByte(_bytes, _position++, *(p + 6)); - Buffer.SetByte(_bytes, _position++, *(p + 5)); - Buffer.SetByte(_bytes, _position++, *(p + 4)); - Buffer.SetByte(_bytes, _position++, *(p + 3)); - Buffer.SetByte(_bytes, _position++, *(p + 2)); - Buffer.SetByte(_bytes, _position++, *(p + 1)); - Buffer.SetByte(_bytes, _position++, *p); + System.Buffer.SetByte(_bytes, _position++, *(p + 7)); + System.Buffer.SetByte(_bytes, _position++, *(p + 6)); + System.Buffer.SetByte(_bytes, _position++, *(p + 5)); + System.Buffer.SetByte(_bytes, _position++, *(p + 4)); + System.Buffer.SetByte(_bytes, _position++, *(p + 3)); + System.Buffer.SetByte(_bytes, _position++, *(p + 2)); + System.Buffer.SetByte(_bytes, _position++, *(p + 1)); + System.Buffer.SetByte(_bytes, _position++, *p); } return this; } public ByteBuffer putLongSeq(long[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); if(NO._o == _order) { - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; } else @@ -525,14 +525,14 @@ namespace IceInternal for(int i = 0; i < seq.Length; ++i) { int index = i * 8; - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 7)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 6)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 5)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 4)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 3)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 2)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 1)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 7)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 6)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 5)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 4)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 3)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 2)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 1)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index)); } } return this; @@ -552,10 +552,10 @@ namespace IceInternal else { byte* p = (byte*)&ret; - *p++ = Buffer.GetByte(_bytes, _position + 3); - *p++ = Buffer.GetByte(_bytes, _position + 2); - *p++ = Buffer.GetByte(_bytes, _position + 1); - *p = Buffer.GetByte(_bytes, _position); + *p++ = System.Buffer.GetByte(_bytes, _position + 3); + *p++ = System.Buffer.GetByte(_bytes, _position + 2); + *p++ = System.Buffer.GetByte(_bytes, _position + 1); + *p = System.Buffer.GetByte(_bytes, _position); } _position += 4; return ret; @@ -563,11 +563,11 @@ namespace IceInternal public unsafe void getFloatSeq(float[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); if(NO._o == _order) { - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); } else { @@ -577,10 +577,10 @@ namespace IceInternal { int index = i * 4; byte* q = (byte*)p; - *q++ = Buffer.GetByte(_bytes, _position + index + 3); - *q++ = Buffer.GetByte(_bytes, _position + index + 2); - *q++ = Buffer.GetByte(_bytes, _position + index + 1); - *q = Buffer.GetByte(_bytes, _position + index); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 3); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 2); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 1); + *q = System.Buffer.GetByte(_bytes, _position + index); } } } @@ -601,21 +601,21 @@ namespace IceInternal else { byte* p = (byte*)&val; - Buffer.SetByte(_bytes, _position++, *(p + 3)); - Buffer.SetByte(_bytes, _position++, *(p + 2)); - Buffer.SetByte(_bytes, _position++, *(p + 1)); - Buffer.SetByte(_bytes, _position++, *p); + System.Buffer.SetByte(_bytes, _position++, *(p + 3)); + System.Buffer.SetByte(_bytes, _position++, *(p + 2)); + System.Buffer.SetByte(_bytes, _position++, *(p + 1)); + System.Buffer.SetByte(_bytes, _position++, *p); } return this; } public ByteBuffer putFloatSeq(float[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); if(NO._o == _order) { - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; } else @@ -623,10 +623,10 @@ namespace IceInternal for(int i = 0; i < seq.Length; ++i) { int index = i * 4; - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 3)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 2)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 1)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 3)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 2)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 1)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index)); } } return this; @@ -646,14 +646,14 @@ namespace IceInternal else { byte* p = (byte*)&ret; - *p++ = Buffer.GetByte(_bytes, _position + 7); - *p++ = Buffer.GetByte(_bytes, _position + 6); - *p++ = Buffer.GetByte(_bytes, _position + 5); - *p++ = Buffer.GetByte(_bytes, _position + 4); - *p++ = Buffer.GetByte(_bytes, _position + 3); - *p++ = Buffer.GetByte(_bytes, _position + 2); - *p++ = Buffer.GetByte(_bytes, _position + 1); - *p = Buffer.GetByte(_bytes, _position); + *p++ = System.Buffer.GetByte(_bytes, _position + 7); + *p++ = System.Buffer.GetByte(_bytes, _position + 6); + *p++ = System.Buffer.GetByte(_bytes, _position + 5); + *p++ = System.Buffer.GetByte(_bytes, _position + 4); + *p++ = System.Buffer.GetByte(_bytes, _position + 3); + *p++ = System.Buffer.GetByte(_bytes, _position + 2); + *p++ = System.Buffer.GetByte(_bytes, _position + 1); + *p = System.Buffer.GetByte(_bytes, _position); } _position += 8; return ret; @@ -661,11 +661,11 @@ namespace IceInternal public unsafe void getDoubleSeq(double[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkUnderflow(len); if(NO._o == _order) { - Buffer.BlockCopy(_bytes, _position, seq, 0, len); + System.Buffer.BlockCopy(_bytes, _position, seq, 0, len); } else { @@ -675,14 +675,14 @@ namespace IceInternal { int index = i * 8; byte* q = (byte*)p; - *q++ = Buffer.GetByte(_bytes, _position + index + 7); - *q++ = Buffer.GetByte(_bytes, _position + index + 6); - *q++ = Buffer.GetByte(_bytes, _position + index + 5); - *q++ = Buffer.GetByte(_bytes, _position + index + 4); - *q++ = Buffer.GetByte(_bytes, _position + index + 3); - *q++ = Buffer.GetByte(_bytes, _position + index + 2); - *q++ = Buffer.GetByte(_bytes, _position + index + 1); - *q = Buffer.GetByte(_bytes, _position + index); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 7); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 6); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 5); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 4); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 3); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 2); + *q++ = System.Buffer.GetByte(_bytes, _position + index + 1); + *q = System.Buffer.GetByte(_bytes, _position + index); } } } @@ -703,25 +703,25 @@ namespace IceInternal else { byte* p = (byte*)&val; - Buffer.SetByte(_bytes, _position++, *(p + 7)); - Buffer.SetByte(_bytes, _position++, *(p + 6)); - Buffer.SetByte(_bytes, _position++, *(p + 5)); - Buffer.SetByte(_bytes, _position++, *(p + 4)); - Buffer.SetByte(_bytes, _position++, *(p + 3)); - Buffer.SetByte(_bytes, _position++, *(p + 2)); - Buffer.SetByte(_bytes, _position++, *(p + 1)); - Buffer.SetByte(_bytes, _position++, *p); + System.Buffer.SetByte(_bytes, _position++, *(p + 7)); + System.Buffer.SetByte(_bytes, _position++, *(p + 6)); + System.Buffer.SetByte(_bytes, _position++, *(p + 5)); + System.Buffer.SetByte(_bytes, _position++, *(p + 4)); + System.Buffer.SetByte(_bytes, _position++, *(p + 3)); + System.Buffer.SetByte(_bytes, _position++, *(p + 2)); + System.Buffer.SetByte(_bytes, _position++, *(p + 1)); + System.Buffer.SetByte(_bytes, _position++, *p); } return this; } public ByteBuffer putDoubleSeq(double[] seq) { - int len = Buffer.ByteLength(seq); + int len = System.Buffer.ByteLength(seq); checkOverflow(len); if(NO._o == _order) { - Buffer.BlockCopy(seq, 0, _bytes, _position, len); + System.Buffer.BlockCopy(seq, 0, _bytes, _position, len); _position += len; } else @@ -729,14 +729,14 @@ namespace IceInternal for(int i = 0; i < seq.Length; ++i) { int index = i * 8; - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 7)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 6)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 5)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 4)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 3)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 2)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index + 1)); - Buffer.SetByte(_bytes, _position++, Buffer.GetByte(seq, index)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 7)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 6)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 5)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 4)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 3)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 2)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index + 1)); + System.Buffer.SetByte(_bytes, _position++, System.Buffer.GetByte(seq, index)); } } return this; diff --git a/cs/src/Ice/ConnectRequestHandler.cs b/cs/src/Ice/ConnectRequestHandler.cs new file mode 100755 index 00000000000..e32cfa53113 --- /dev/null +++ b/cs/src/Ice/ConnectRequestHandler.cs @@ -0,0 +1,440 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace IceInternal +{ + public class ConnectRequestHandler : RequestHandler, Reference.GetConnectionCallback, RouterInfo.AddProxyCallback + { + private class Request + { + internal Request(BasicStream os) + { + this.os = new BasicStream(os.instance()); + this.os.swap(os); + } + + internal Request(OutgoingAsync @out) + { + this.@out = @out; + } + + internal Request(BatchOutgoingAsync @out) + { + this.batchOut = @out; + } + + internal OutgoingAsync @out = null; + internal BatchOutgoingAsync batchOut = null; + internal BasicStream os = null; + } + + public void prepareBatchRequest(BasicStream os) + { + lock(this) + { + while(_batchRequestInProgress) + { + Monitor.Wait(this); + } + + if(!initialized()) + { + _batchStream.swap(os); + _batchRequestInProgress = true; + return; + } + } + + _connection.prepareBatchRequest(os); + } + + public void finishBatchRequest(BasicStream os) + { + lock(this) + { + if(!initialized()) + { + Debug.Assert(_batchRequestInProgress); + _batchRequestInProgress = false; + Monitor.PulseAll(this); + + _batchStream.swap(os); + + if(!_batchAutoFlush && + _batchStream.size() + _batchRequestsSize > _reference.getInstance().messageSizeMax()) + { + throw new Ice.MemoryLimitException(); + } + _requests.Add(new Request(_batchStream)); + return; + } + } + + _connection.finishBatchRequest(os, _compress); + } + + public void abortBatchRequest() + { + lock(this) + { + if(!initialized()) + { + Debug.Assert(_batchRequestInProgress); + _batchRequestInProgress = false; + Monitor.PulseAll(this); + + BasicStream dummy = new BasicStream(_reference.getInstance(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestsSize = Protocol.requestBatchHdr.Length; + return; + } + } + + _connection.abortBatchRequest(); + } + + public Ice.ConnectionI sendRequest(Outgoing @out) + { + return (!getConnection(true).sendRequest(@out, _compress, _response) || _response) ? _connection : null; + } + + public void sendAsyncRequest(OutgoingAsync @out) + { + try + { + lock(this) + { + if(!initialized()) + { + _requests.Add(new Request(@out)); + return; + } + } + + _connection.sendAsyncRequest(@out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + @out.finished__(ex); + } + catch(Ice.LocalException ex) + { + @out.finished__(ex); + } + } + + public bool flushBatchRequests(BatchOutgoing @out) + { + return getConnection(true).flushBatchRequests(@out); + } + + public void flushAsyncBatchRequests(BatchOutgoingAsync @out) + { + try + { + lock(this) + { + if(!initialized()) + { + _requests.Add(new Request(@out)); + return; + } + } + + _connection.flushAsyncBatchRequests(@out); + } + catch(Ice.LocalException ex) + { + @out.finished__(ex); + } + } + + public Outgoing getOutgoing(string operation, Ice.OperationMode mode, Dictionary<string, string> context) + { + lock(this) + { + if(!initialized()) + { + return new IceInternal.Outgoing(this, operation, mode, context); + } + } + + return _connection.getOutgoing(this, operation, mode, context); + } + + public void reclaimOutgoing(Outgoing og) + { + lock(this) + { + if(_connection == null) + { + return; + } + } + + _connection.reclaimOutgoing(og); + } + + public Reference getReference() + { + return _reference; + } + + public Ice.ConnectionI getConnection(bool wait) + { + lock(this) + { + if(wait) + { + // + // Wait for the connection establishment to complete or fail. + // + while(!_initialized && _exception == null) + { + Monitor.Wait(this); + } + } + + if(_exception != null) + { + throw _exception; + } + else + { + Debug.Assert(!wait || _initialized); + return _connection; + } + } + } + + // + // Implementation of Reference.GetConnectionCallback + // + + public void setConnection(Ice.ConnectionI connection, bool compress) + { + lock(this) + { + _connection = connection; + _compress = compress; + } + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + RouterInfo ri = _reference.getRouterInfo(); + if(ri != null) + { + if(!ri.addProxy(_proxy, this)) + { + return; // The request handler will be initialized once addProxy returns. + } + } + + flushRequests(); + } + + public void setException(Ice.LocalException ex) + { + lock(this) + { + _exception = ex; + _proxy = null; // Break cyclic reference count. + _delegate = null; // Break cyclic reference count. + Monitor.PulseAll(this); + } + + foreach(Request request in _requests) + { + if(request.@out != null) + { + request.@out.finished__(ex); + } + else if(request.batchOut != null) + { + request.batchOut.finished__(ex); + } + } + _requests.Clear(); + } + + // + // Implementation of RouterInfo.AddProxyCallback + // + public void addedProxy() + { + flushRequests(); + } + + public ConnectRequestHandler(Reference @ref, Ice.ObjectPrx proxy, Ice.ObjectDelM_ del) + { + _reference = @ref; + _response = _reference.getMode() == Reference.Mode.ModeTwoway; + _proxy = (Ice.ObjectPrxHelperBase)proxy; + _delegate = del; + _batchAutoFlush = @ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault( + "Ice.BatchAutoFlush", 1) > 0 ? true : false; + _batchStream = new BasicStream(@ref.getInstance(), _batchAutoFlush); + _batchRequestInProgress = false; + _batchRequestsSize = Protocol.requestBatchHdr.Length; + _updateRequestHandler = false; + } + + public RequestHandler connect() + { + _reference.getConnection(this); + + lock(this) + { + if(_connection != null) + { + return new ConnectionRequestHandler(_reference, _connection, _compress); + } + else + { + _updateRequestHandler = true; + return this; + } + } + } + + private bool initialized() + { + if(_initialized) + { + Debug.Assert(_connection != null); + return true; + } + else + { + while(_flushing) + { + Monitor.Wait(this); + } + + if(_exception != null) + { + throw _exception; + } + else + { + return _initialized; + } + } + } + + private void flushRequests() + { + lock(this) + { + Debug.Assert(_connection != null); + + if(_batchRequestInProgress) + { + Monitor.Wait(this); + } + + // + // We set the _flushing flag to true to prevent any additional queuing. Callers + // might block for a little while as the queued requests are being sent but this + // shouldn't be an issue as the request sends are non-blocking. + // + _flushing = true; + } + + foreach(Request request in _requests) // _requests is immutable when _flushing = true + { + if(request.@out != null) + { + try + { + _connection.sendAsyncRequest(request.@out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + request.@out.finished__(ex); + } + catch(Ice.LocalException ex) + { + request.@out.finished__(ex); + } + } + else if(request.batchOut != null) + { + try + { + _connection.flushAsyncBatchRequests(request.batchOut); + } + catch(Ice.LocalException ex) + { + request.batchOut.finished__(ex); + } + } + else + { + // + // TODO: Add sendBatchRequest() method to ConnectionI? + // + try + { + BasicStream os = new BasicStream(request.os.instance()); + _connection.prepareBatchRequest(os); + request.os.pos(0); + os.writeBlob(request.os.readBlob(request.os.size())); + _connection.finishBatchRequest(os, _compress); + } + catch(Ice.LocalException) + { + _connection.abortBatchRequest(); + throw; + } + } + } + _requests.Clear(); + + lock(this) + { + _initialized = true; + _flushing = false; + Monitor.PulseAll(this); + } + + if(_updateRequestHandler && _exception == null) + { + _proxy.setRequestHandler__(_delegate, new ConnectionRequestHandler(_reference, _connection, _compress)); + } + _proxy = null; // Break cyclic reference count. + _delegate = null; // Break cyclic reference count. + } + + private Reference _reference; + private bool _batchAutoFlush; + private Ice.ObjectPrxHelperBase _proxy; + private Ice.ObjectDelM_ _delegate; + private bool _initialized = false; + private bool _flushing = false; + private Ice.ConnectionI _connection = null; + private bool _compress = false; + private bool _response; + private Ice.LocalException _exception = null; + + private List<Request> _requests = new List<Request>(); + private bool _batchRequestInProgress; + private int _batchRequestsSize; + private BasicStream _batchStream; + private bool _updateRequestHandler; + } +} diff --git a/cs/src/Ice/ConnectionFactory.cs b/cs/src/Ice/ConnectionFactory.cs index 8dcf5a6c0f3..0d50c6f488b 100644 --- a/cs/src/Ice/ConnectionFactory.cs +++ b/cs/src/Ice/ConnectionFactory.cs @@ -11,12 +11,20 @@ namespace IceInternal { using System.Collections; + using System.Collections.Generic; using System.Diagnostics; + using System.Net.Sockets; using System.Threading; using IceUtil; public sealed class OutgoingConnectionFactory { + public interface CreateConnectionCallback + { + void setConnection(Ice.ConnectionI connection, bool compress); + void setException(Ice.LocalException ex); + } + public void destroy() { lock(this) @@ -25,7 +33,7 @@ namespace IceInternal { return; } - + foreach(LinkedList connections in _connections.Values) { foreach(Ice.ConnectionI c in connections) @@ -35,14 +43,14 @@ namespace IceInternal } _destroyed = true; - System.Threading.Monitor.PulseAll(this); + Monitor.PulseAll(this); } } - + public void waitUntilFinished() { - Hashtable connections; - + Dictionary<ConnectorInfo, LinkedList> connections = null; + lock(this) { // @@ -51,25 +59,23 @@ namespace IceInternal // anymore. Only then we can be sure the _connections // contains all connections. // - while(!_destroyed || _pending.Count != 0) + while(!_destroyed || _pending.Count > 0 || _pendingEndpoints.Count > 0) { - System.Threading.Monitor.Wait(this); + Monitor.Wait(this); } - - // - // We want to wait until all connections are finished - // outside the thread synchronization. + // - // We set _connections to null because our destructor must not - // invoke methods on member objects. + // We want to wait until all connections are finished outside the + // thread synchronization. // - connections = _connections; - _connections = null; + if(_connections != null) + { + connections = new Dictionary<ConnectorInfo, LinkedList>(_connections); + } } - + // - // Now we wait for the destruction of each connection to be - // finished. + // Now we wait until the destruction of each connection is finished. // foreach(LinkedList cl in connections.Values) { @@ -78,95 +84,66 @@ namespace IceInternal c.waitUntilFinished(); } } - } - - private class ConnectorEndpointPair - { - public ConnectorEndpointPair(Connector c, EndpointI e) + + lock(this) { - connector = c; - endpoint = e; + _connections = null; } - - public Connector connector; - public EndpointI endpoint; } - public Ice.ConnectionI create(EndpointI[] endpts, bool hasMore, bool threadPerConnection, - Ice.EndpointSelectionType selType, out bool compress) + public Ice.ConnectionI create(EndpointI[] endpts, bool hasMore, bool tpc, Ice.EndpointSelectionType selType, + out bool compress) { Debug.Assert(endpts.Length > 0); - ArrayList connectors = new ArrayList(); - DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); - - compress = false; - - lock(this) + // + // TODO: Remove when no transports require thread-per-connection. + // + for(int i = 0; i < endpts.Length; i++) { - if(_destroyed) + if(!tpc && endpts[i].requiresThreadPerConnection()) { - throw new Ice.CommunicatorDestroyedException(); + Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); + ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].ToString(); + throw ex; } + } - for(int i = 0; i < endpts.Length; i++) - { - if(!threadPerConnection && endpts[i].requiresThreadPerConnection()) - { - Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); - ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].ToString(); - throw ex; - } - } + // + // Apply the overrides. + // + List<EndpointI> endpoints = applyOverrides(endpts); - // - // Reap connections for which destruction has completed. - // - ArrayList removeList = new ArrayList(); - foreach(DictionaryEntry e in _connections) - { - LinkedList cl = (LinkedList)e.Value; - LinkedList.Enumerator q = (LinkedList.Enumerator)cl.GetEnumerator(); - while(q.MoveNext()) - { - if(((Ice.ConnectionI)q.Current).isFinished()) - { - q.Remove(); - } - } - if(cl.Count == 0) - { - removeList.Add(e.Key); - } - } - foreach(object o in removeList) - { - _connections.Remove(o); - } + // + // Try to find a connection to one of the given endpoints. + // + Ice.ConnectionI connection = findConnection(endpoints, tpc, out compress); + if(connection != null) + { + return connection; + } - // - // Modify endpoints with overrides. - // - EndpointI[] endpoints = new EndpointI[endpts.Length]; - for(int i = 0; i < endpoints.Length; ++i) - { - endpoints[i] = endpts[i]; - } - for(int i = 0; i < endpoints.Length; i++) - { - if(defaultsAndOverrides.overrideTimeout) - { - endpoints[i] = endpoints[i].timeout(defaultsAndOverrides.overrideTimeoutValue); - } + Ice.LocalException exception = null; + // + // If we didn't find a connection with the endpoints, we create the connectors + // for the endpoints. + // + List<ConnectorInfo> connectors = new List<ConnectorInfo>(); + for(int i = 0; i < endpoints.Count; ++i) + { + EndpointI endpoint = endpoints[i]; + + try + { // // Create connectors for the endpoint. // - ArrayList cons = endpoints[i].connectors(); + List<Connector> cons = endpoint.connectors(); Debug.Assert(cons.Count > 0); // - // Shuffle connectors is endpoint selection type is Random. + // Shuffle connectors if endpoint selection type is Random. // if(selType == Ice.EndpointSelectionType.Random) { @@ -176,163 +153,68 @@ namespace IceInternal Debug.Assert(r >= j && r < cons.Count); if(r != j) { - object tmp = cons[j]; + Connector tmp = cons[j]; cons[j] = cons[r]; cons[r] = tmp; } } } - foreach(Connector con in cons) - { - connectors.Add(new ConnectorEndpointPair(con, endpoints[i])); - } - } - - // - // Search for existing connections. - // - foreach(ConnectorEndpointPair cep in connectors) - { - LinkedList connectionList = (LinkedList)_connections[cep.connector]; - if(connectionList != null) + foreach(Connector conn in cons) { - foreach(Ice.ConnectionI conn in connectionList) - { - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!conn.isDestroyed() && conn.threadPerConnection() == threadPerConnection) - { - if(defaultsAndOverrides.overrideCompress) - { - compress = defaultsAndOverrides.overrideCompressValue; - } - else - { - compress = cep.endpoint.compress(); - } - return conn; - } - } + connectors.Add(new ConnectorInfo(conn, endpoint, tpc)); } } - - // - // If some other thread is currently trying to establish a - // connection to any of our endpoints, we wait until this - // thread is finished. - // - bool searchAgain = false; - while(!_destroyed) - { - bool found = false; - foreach(ConnectorEndpointPair cep in connectors) - { - if(_pending.Contains(cep.connector)) - { - found = true; - break; - } - } - - if(!found) - { - break; - } - - searchAgain = true; - - System.Threading.Monitor.Wait(this); - } - - if(_destroyed) - { - throw new Ice.CommunicatorDestroyedException(); - } - - // - // Search for existing connections again if we waited - // above, as new connections might have been added in the - // meantime. - // - if(searchAgain) - { - foreach(ConnectorEndpointPair cep in connectors) - { - LinkedList connectionList = (LinkedList)_connections[cep.connector]; - if(connectionList != null) - { - foreach(Ice.ConnectionI conn in connectionList) - { - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!conn.isDestroyed() && conn.threadPerConnection() == threadPerConnection) - { - if(defaultsAndOverrides.overrideCompress) - { - compress = defaultsAndOverrides.overrideCompressValue; - } - else - { - compress = cep.endpoint.compress(); - } - return conn; - } - } - } - } - } - - // - // No connection to any of our endpoints exists yet, - // so we will try to create one. To avoid that other - // threads try to create connections to the same - // endpoints, we add our endpoints to _pending. - // - foreach(ConnectorEndpointPair cep in connectors) + catch(Ice.LocalException ex) { - _pending.Add(cep.connector); + exception = ex; + handleException(exception, hasMore || i < endpoints.Count - 1); } } - - Connector connector = null; - Ice.ConnectionI connection = null; - Ice.LocalException exception = null; - + + if(connectors.Count == 0) + { + Debug.Assert(exception != null); + throw exception; + } + + // + // Try to get a connection to one of the connectors. A null result indicates that no + // connection was found and that we should try to establish the connection (and that + // the connectors were added to _pending to prevent other threads from establishing + // the connection). + // + connection = getConnection(connectors, null, out compress); + if(connection != null) + { + return connection; + } + + // + // Try to establish the connection to the connectors. + // + DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); for(int i = 0; i < connectors.Count; ++i) { - ConnectorEndpointPair cep = (ConnectorEndpointPair)connectors[i]; - connector = cep.connector; - EndpointI endpoint = cep.endpoint; - + ConnectorInfo ci = connectors[i]; try { - int timeout = -1; + int timeout; if(defaultsAndOverrides.overrideConnectTimeout) { timeout = defaultsAndOverrides.overrideConnectTimeoutValue; } - // It is not necessary to check for overrideTimeout, - // the endpoint has already been modified with this - // override, if set. else { - timeout = endpoint.timeout(); + // + // It is not necessary to check for overrideTimeout, the endpoint has already + // been modified with this override, if set. + // + timeout = ci.endpoint.timeout(); } - Transceiver transceiver = connector.connect(timeout); - Debug.Assert(transceiver != null); - - connection = new Ice.ConnectionI(instance_, transceiver, endpoint.compress(false), null, - threadPerConnection); - connection.start(); - connection.validate(); + connection = createConnection(ci.connector.connect(timeout), ci); + connection.start(null); if(defaultsAndOverrides.overrideCompress) { @@ -340,86 +222,79 @@ namespace IceInternal } else { - compress = endpoint.compress(); + compress = ci.endpoint.compress(); } + break; } - catch(Ice.LocalException ex) + catch(Ice.CommunicatorDestroyedException ex) { exception = ex; - - // - // If a connection object was constructed, then validate() - // must have raised the exception. - // - if(connection != null) - { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - connection = null; - } + handleException(exception, ci, connection, hasMore || i < connectors.Count - 1); + connection = null; + break; // No need to continue } - - TraceLevels traceLevels = instance_.traceLevels(); - if(traceLevels.retry >= 2) + catch(Ice.LocalException ex) { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("connection to endpoint failed"); - if(hasMore || i < connectors.Count - 1) - { - s.Append(", trying next endpoint\n"); - } - else - { - s.Append(" and no more endpoints to try\n"); - } - s.Append(exception); - instance_.initializationData().logger.trace(traceLevels.retryCat, s.ToString()); + exception = ex; + handleException(exception, ci, connection, hasMore || i < connectors.Count - 1); + connection = null; } } - - lock(this) + + // + // Finish creating the connection (this removes the connectors from the _pending + // list and notifies any waiting threads). + // + finishGetConnection(connectors, null, connection); + + if(connection == null) { - // - // Signal other threads that we are done with trying to - // establish connections to our endpoints. - // - foreach(ConnectorEndpointPair cep in connectors) - { - _pending.Remove(cep.connector); - } - System.Threading.Monitor.PulseAll(this); - - if(connection == null) - { - Debug.Assert(exception != null); - throw exception; - } - else + Debug.Assert(exception != null); + throw exception; + } + + return connection; + } + + public void create(EndpointI[] endpts, bool hasMore, bool tpc, Ice.EndpointSelectionType selType, + CreateConnectionCallback callback) + { + Debug.Assert(endpts.Length > 0); + + // + // TODO: Remove when no transports require thread-per-connection. + // + for(int i = 0; i < endpts.Length; i++) + { + if(!tpc && endpts[i].requiresThreadPerConnection()) { - LinkedList connectionList = (LinkedList)_connections[connector]; - if(connectionList == null) - { - connectionList = new LinkedList(); - _connections[connector] = connectionList; - } - connectionList.Add(connection); - - if(_destroyed) - { - connection.destroy(Ice.ConnectionI.CommunicatorDestroyed); - throw new Ice.CommunicatorDestroyedException(); - } - else - { - connection.activate(); - } + Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); + ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].ToString(); + throw ex; } } - - Debug.Assert(connection != null); - return connection; + + // + // Apply the overrides. + // + List<EndpointI> endpoints = applyOverrides(endpts); + + // + // Try to find a connection to one of the given endpoints. + // + bool compress; + Ice.ConnectionI connection = findConnection(endpoints, tpc, out compress); + if(connection != null) + { + callback.setConnection(connection, compress); + return; + } + + ConnectCallback cb = new ConnectCallback(this, endpoints, hasMore, callback, selType, tpc); + cb.getConnection(); } - + public void setRouterInfo(IceInternal.RouterInfo routerInfo) { lock(this) @@ -428,8 +303,9 @@ namespace IceInternal { throw new Ice.CommunicatorDestroyedException(); } - + Debug.Assert(routerInfo != null); + // // Search for connections to the router's client proxy // endpoints, and update the object adapter for such @@ -461,7 +337,7 @@ namespace IceInternal // this connection factory. // endpoint = endpoint.compress(false); - + foreach(LinkedList connections in _connections.Values) { foreach(Ice.ConnectionI connection in connections) @@ -493,7 +369,7 @@ namespace IceInternal { return; } - + foreach(LinkedList connectionList in _connections.Values) { foreach(Ice.ConnectionI connection in connectionList) @@ -515,11 +391,11 @@ namespace IceInternal } } } - + public void flushBatchRequests() { LinkedList c = new LinkedList(); - + lock(this) { foreach(LinkedList connectionList in _connections.Values) @@ -530,7 +406,7 @@ namespace IceInternal } } } - + foreach(Ice.ConnectionI conn in c) { try @@ -543,7 +419,7 @@ namespace IceInternal } } } - + // // Only for use by Instance. // @@ -551,18 +427,751 @@ namespace IceInternal { instance_ = instance; _destroyed = false; - _connections = new Hashtable(); - _pending = new Set(); } - + + private List<EndpointI> applyOverrides(EndpointI[] endpts) + { + DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); + List<EndpointI> endpoints = new List<EndpointI>(); + for(int i = 0; i < endpts.Length; i++) + { + // + // Modify endpoints with overrides. + // + if(defaultsAndOverrides.overrideTimeout) + { + endpoints.Add(endpts[i].timeout(defaultsAndOverrides.overrideTimeoutValue)); + } + else + { + endpoints.Add(endpts[i]); + } + } + + return endpoints; + } + + private Ice.ConnectionI findConnection(List<EndpointI> endpoints, bool tpc, out bool compress) + { + lock(this) + { + DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); + Debug.Assert(endpoints.Count > 0); + + foreach(EndpointI endpoint in endpoints) + { + LinkedList connectionList = null; + if(!_connectionsByEndpoint.TryGetValue(endpoint, out connectionList)) + { + continue; + } + + foreach(Ice.ConnectionI connection in connectionList) + { + if(connection.isActiveOrHolding() && + connection.threadPerConnection() == tpc) // Don't return destroyed or unvalidated connections + { + if(defaultsAndOverrides.overrideCompress) + { + compress = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress = endpoint.compress(); + } + return connection; + } + } + } + + compress = false; // Satisfy the compiler + return null; + } + } + + // + // Must be called while synchronized. + // + private Ice.ConnectionI findConnection(List<ConnectorInfo> connectors, out bool compress) + { + DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); + foreach(ConnectorInfo ci in connectors) + { + LinkedList connectionList = null; + if(!_connections.TryGetValue(ci, out connectionList)) + { + continue; + } + + foreach(Ice.ConnectionI connection in connectionList) + { + if(connection.isActiveOrHolding()) // Don't return destroyed or un-validated connections + { + if(connection.endpoint().Equals(ci.endpoint)) + { + LinkedList conList = null; + if(!_connectionsByEndpoint.TryGetValue(ci.endpoint, out conList)) + { + conList = new LinkedList(); + _connectionsByEndpoint.Add(ci.endpoint, conList); + } + conList.Add(connection); + } + + if(defaultsAndOverrides.overrideCompress) + { + compress = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress = ci.endpoint.compress(); + } + return connection; + } + } + } + + compress = false; // Satisfy the compiler + return null; + } + + internal void addPendingEndpoints(List<EndpointI> endpoints) + { + lock(this) + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + foreach(EndpointI endpoint in endpoints) + { + _pendingEndpoints.AddLast(endpoint); + } + } + } + + internal void removePendingEndpoints(List<EndpointI> endpoints) + { + lock(this) + { + foreach(EndpointI endpoint in endpoints) + { + _pendingEndpoints.Remove(endpoint); + } + } + } + + private Ice.ConnectionI getConnection(List<ConnectorInfo> connectors, ConnectCallback cb, out bool compress) + { + lock(this) + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + // + // Reap connections for which destruction has completed. + // + List<ConnectorInfo> removedConnections = new List<ConnectorInfo>(); + foreach(KeyValuePair<ConnectorInfo, LinkedList> e in _connections) + { + LinkedList.Enumerator q = (LinkedList.Enumerator)e.Value.GetEnumerator(); + while(q.MoveNext()) + { + Ice.ConnectionI con = (Ice.ConnectionI)q.Current; + if(con.isFinished()) + { + q.Remove(); + } + } + + if(e.Value.Count == 0) + { + removedConnections.Add(e.Key); + } + } + foreach(ConnectorInfo ci in removedConnections) + { + _connections.Remove(ci); + } + + List<EndpointI> removedEndpoints = new List<EndpointI>(); + foreach(KeyValuePair<EndpointI, LinkedList> e in _connectionsByEndpoint) + { + LinkedList.Enumerator q = (LinkedList.Enumerator)e.Value.GetEnumerator(); + while(q.MoveNext()) + { + Ice.ConnectionI con = (Ice.ConnectionI)q.Current; + if(con.isFinished()) + { + q.Remove(); + } + } + + if(e.Value.Count == 0) + { + removedEndpoints.Add(e.Key); + } + } + foreach(EndpointI endpoint in removedEndpoints) + { + _connectionsByEndpoint.Remove(endpoint); + } + + // + // Try to get the connection. We may need to wait for other threads to + // finish if one of them is currently establishing a connection to one + // of our connectors. + // + while(!_destroyed) + { + // + // Search for a matching connection. If we find one, we're done. + // + Ice.ConnectionI connection = findConnection(connectors, out compress); + if(connection != null) + { + if(cb != null) + { + // + // This might not be the first getConnection call for the callback. We need + // to ensure that the callback isn't registered with any other pending + // connectors since we just found a connection and therefore don't need to + // wait anymore for other pending connectors. + // + foreach(ConnectorInfo ci in connectors) + { + Set cbs = null; + if(_pending.TryGetValue(ci, out cbs)) + { + cbs.Remove(cb); + } + } + } + return connection; + } + + // + // Determine whether another thread is currently attempting to connect to one of our endpoints; + // if so we wait until it's done. + // + bool found = false; + foreach(ConnectorInfo ci in connectors) + { + Set cbs = null; + if(_pending.TryGetValue(ci, out cbs)) + { + found = true; + if(cb != null) + { + cbs.Add(cb); // Add the callback to each pending connector. + } + } + } + + if(!found) + { + // + // If no thread is currently establishing a connection to one of our connectors, + // we get out of this loop and start the connection establishment to one of the + // given connectors. + // + break; + } + else + { + // + // If a callback is not specified we wait until another thread notifies us about a + // change to the pending list. Otherwise, if a callback is provided we're done: + // when the pending list changes the callback will be notified and will try to + // get the connection again. + // + if(cb == null) + { + Monitor.Wait(this); + } + else + { + return null; + } + } + } + + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + // + // No connection to any of our endpoints exists yet; we add the given connectors to + // the _pending set to indicate that we're attempting connection establishment to + // these connectors. + // + foreach(ConnectorInfo ci in connectors) + { + _pending.Add(ci, new Set()); + } + } + + // + // At this point, we're responsible for establishing the connection to one of + // the given connectors. If it's a non-blocking connect, calling nextConnector + // will start the connection establishment. Otherwise, we return null to get + // the caller to establish the connection. + // + if(cb != null) + { + cb.nextConnector(); + } + + compress = false; // Satisfy the compiler + return null; + } + + private Ice.ConnectionI createConnection(Transceiver transceiver, ConnectorInfo ci) + { + lock(this) + { + Debug.Assert(_pending.ContainsKey(ci) && transceiver != null); + + // + // Create and add the connection to the connection map. Adding the connection to the map + // is necessary to support the interruption of the connection initialization and validation + // in case the communicator is destroyed. + // + try + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + Ice.ConnectionI connection = new Ice.ConnectionI(instance_, transceiver, + ci.endpoint.compress(false), + null, ci.threadPerConnection); + + LinkedList connectionList = null; + if(!_connections.TryGetValue(ci, out connectionList)) + { + connectionList = new LinkedList(); + _connections.Add(ci, connectionList); + } + connectionList.Add(connection); + return connection; + } + catch(Ice.LocalException) + { + try + { + transceiver.close(); + } + catch(Ice.LocalException) + { + // Ignore + } + throw; + } + } + } + + private void finishGetConnection(List<ConnectorInfo> connectors, ConnectCallback cb, Ice.ConnectionI connection) + { + List<ConnectCallback> callbacks = new List<ConnectCallback>(); + + lock(this) + { + // + // We're done trying to connect to the given connectors so we remove the + // connectors from the pending list and notify waiting threads. We also + // notify the pending connect callbacks (outside the synchronization). + // + + foreach(ConnectorInfo ci in connectors) + { + Set s = _pending[ci]; + foreach(ConnectCallback c in s) + { + callbacks.Add(c); + } + _pending.Remove(ci); + } + Monitor.PulseAll(this); + + // + // If the connect attempt succeeded and the communicator is not destroyed, + // activate the connection! + // + if(connection != null && !_destroyed) + { + connection.activate(); + } + } + + // + // Notify any waiting callbacks. + // + foreach(ConnectCallback cc in callbacks) + { + cc.getConnection(); + } + } + + private void handleException(Ice.LocalException ex, ConnectorInfo ci, Ice.ConnectionI connection, + bool hasMore) + { + TraceLevels traceLevels = instance_.traceLevels(); + if(traceLevels.retry >= 2) + { + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("connection to endpoint failed"); + if(ex is Ice.CommunicatorDestroyedException) + { + s.Append("\n"); + } + else + { + if(hasMore) + { + s.Append(", trying next endpoint\n"); + } + else + { + s.Append(" and no more endpoints to try\n"); + } + } + s.Append(ex); + instance_.initializationData().logger.trace(traceLevels.retryCat, s.ToString()); + } + + if(connection != null && connection.isFinished()) + { + // + // If the connection is finished, we remove it right away instead of + // waiting for the reaping. + // + // NOTE: it's possible for the connection to not be finished yet. That's + // for instance the case when using thread per connection and if it's the + // thread which is calling back the outgoing connection factory to notify + // it of the failure. + // + lock(this) + { + LinkedList connectionList = null; + if(_connections.TryGetValue(ci, out connectionList)) // It might have already been reaped! + { + connectionList.Remove(connection); + if(connectionList.Count == 0) + { + _connections.Remove(ci); + } + } + } + } + } + + internal void handleException(Ice.LocalException ex, bool hasMore) + { + TraceLevels traceLevels = instance_.traceLevels(); + if(traceLevels.retry >= 2) + { + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("couldn't resolve endpoint host"); + if(ex is Ice.CommunicatorDestroyedException) + { + s.Append("\n"); + } + else + { + if(hasMore) + { + s.Append(", trying next endpoint\n"); + } + else + { + s.Append(" and no more endpoints to try\n"); + } + } + s.Append(ex); + instance_.initializationData().logger.trace(traceLevels.retryCat, s.ToString()); + } + } + + private class ConnectorInfo + { + internal ConnectorInfo(Connector c, EndpointI e, bool t) + { + connector = c; + endpoint = e; + threadPerConnection = t; + } + + public override bool Equals(object obj) + { + ConnectorInfo r = (ConnectorInfo)obj; + if(threadPerConnection != r.threadPerConnection) + { + return false; + } + + return connector.Equals(r.connector); + } + + public override int GetHashCode() + { + return 2 * connector.GetHashCode() + (threadPerConnection ? 0 : 1); + } + + public Connector connector; + public EndpointI endpoint; + public bool threadPerConnection; + } + + private class ConnectCallback : Ice.ConnectionI.StartCallback, EndpointI_connectors, ThreadPoolWorkItem + { + internal ConnectCallback(OutgoingConnectionFactory f, List<EndpointI> endpoints, bool more, + CreateConnectionCallback cb, Ice.EndpointSelectionType selType, + bool threadPerConnection) + { + _factory = f; + _endpoints = endpoints; + _hasMore = more; + _callback = cb; + _selType = selType; + _threadPerConnection = threadPerConnection; + _endpointsIter = 0; + } + + // + // Methods from ConnectionI.StartCallback + // + public void connectionStartCompleted(Ice.ConnectionI connection) + { + lock(this) + { + Debug.Assert(_exception == null && connection == _connection); + + bool compress; + DefaultsAndOverrides defaultsAndOverrides = _factory.instance_.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideCompress) + { + compress = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress = _current.endpoint.compress(); + } + + _factory.finishGetConnection(_connectors, this, connection); + _factory.removePendingEndpoints(_endpoints); + _callback.setConnection(connection, compress); + } + } + + public void connectionStartFailed(Ice.ConnectionI connection, Ice.LocalException ex) + { + lock(this) + { + Debug.Assert(_exception == null && connection == _connection); + + _exception = ex; + handleException(); + } + } + + // + // Methods from EndpointI_connectors + // + public void connectors(List<Connector> cons) + { + // + // Shuffle connectors if endpoint selection type is Random. + // + if(_selType == Ice.EndpointSelectionType.Random) + { + for(int j = 0; j < cons.Count - 2; ++j) + { + int r = OutgoingConnectionFactory.rand_.Next(cons.Count - j) + j; + Debug.Assert(r >= j && r < cons.Count); + if(r != j) + { + Connector tmp = cons[j]; + cons[j] = cons[r]; + cons[r] = tmp; + } + } + } + + foreach(Connector connector in cons) + { + _connectors.Add(new ConnectorInfo(connector, _currentEndpoint, _threadPerConnection)); + } + + if(_endpointsIter < _endpoints.Count) + { + _currentEndpoint = _endpoints[_endpointsIter++]; + _currentEndpoint.connectors_async(this); + } + else + { + Debug.Assert(_connectors.Count > 0); + + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = 0; + getConnection(); + } + } + + public void exception(Ice.LocalException ex) + { + _factory.handleException(ex, _hasMore || _endpointsIter < _endpoints.Count); + if(_endpointsIter < _endpoints.Count) + { + _currentEndpoint = _endpoints[_endpointsIter++]; + _currentEndpoint.connectors_async(this); + } + else if(_connectors.Count > 0) + { + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = 0; + getConnection(); + } + else + { + _exception = ex; + _factory.instance_.clientThreadPool().execute(this); + } + } + + // + // Methods from ThreadPoolWorkItem + // + public void execute(ThreadPool threadPool) + { + threadPool.promoteFollower(); + Debug.Assert(_exception != null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + + internal void getConnection() + { + // + // First, get the connectors for all the endpoints. + // + if(_endpointsIter < _endpoints.Count) + { + try + { + _factory.addPendingEndpoints(_endpoints); + _currentEndpoint = _endpoints[_endpointsIter++]; + _currentEndpoint.connectors_async(this); + } + catch(Ice.LocalException ex) + { + _callback.setException(ex); + } + return; + } + + try + { + bool compress; + Ice.ConnectionI connection = _factory.getConnection(_connectors, this, out compress); + if(connection == null) + { + // + // A null return value from getConnection indicates that the connection + // is being established and that everthing has been done to ensure that + // the callback will be notified when the connection establishment is + // done. + // + return; + } + + _factory.removePendingEndpoints(_endpoints); + _callback.setConnection(connection, compress); + } + catch(Ice.LocalException ex) + { + _exception = ex; + _factory.instance_.clientThreadPool().execute(this); + } + } + + internal void nextConnector() + { + _current = _connectors[_iter++]; + try + { + _exception = null; + _connection = _factory.createConnection(_current.connector.connect(0), _current); + _connection.start(this); + } + catch(Ice.LocalException ex) + { + _exception = ex; + handleException(); + } + } + + private void handleException() + { + Debug.Assert(_current != null && _exception != null); + + _factory.handleException(_exception, _current, _connection, _hasMore || _iter < _connectors.Count); + if(_exception is Ice.CommunicatorDestroyedException) // No need to continue. + { + _factory.finishGetConnection(_connectors, this, null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + else if(_iter < _connectors.Count) // Try the next connector. + { + nextConnector(); + } + else + { + _factory.finishGetConnection(_connectors, this, null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + } + + private OutgoingConnectionFactory _factory; + private bool _hasMore; + private CreateConnectionCallback _callback; + private List<EndpointI> _endpoints; + private Ice.EndpointSelectionType _selType; + private bool _threadPerConnection; + private int _endpointsIter; + private EndpointI _currentEndpoint; + private List<ConnectorInfo> _connectors = new List<ConnectorInfo>(); + private int _iter; + private ConnectorInfo _current; + private Ice.LocalException _exception; + private Ice.ConnectionI _connection; + } + private readonly Instance instance_; private bool _destroyed; - private Hashtable _connections; - private Set _pending; + + private Dictionary<ConnectorInfo, LinkedList> _connections = new Dictionary<ConnectorInfo, LinkedList>(); + private Dictionary<ConnectorInfo, Set> _pending = new Dictionary<ConnectorInfo, Set>(); + + private Dictionary<EndpointI, LinkedList> _connectionsByEndpoint = new Dictionary<EndpointI, LinkedList>(); + private LinkedList<EndpointI> _pendingEndpoints = new LinkedList<EndpointI>(); + private static System.Random rand_ = new System.Random(unchecked((int)System.DateTime.Now.Ticks)); } - public sealed class IncomingConnectionFactory : EventHandler + public sealed class IncomingConnectionFactory : EventHandler, Ice.ConnectionI.StartCallback { public void activate() { @@ -571,7 +1180,7 @@ namespace IceInternal setState(StateActive); } } - + public void hold() { lock(this) @@ -579,7 +1188,7 @@ namespace IceInternal setState(StateHolding); } } - + public void destroy() { lock(this) @@ -587,11 +1196,11 @@ namespace IceInternal setState(StateClosed); } } - + public void waitUntilHolding() { LinkedList connections; - + lock(this) { // @@ -600,16 +1209,16 @@ namespace IceInternal // while(_state < StateHolding) { - System.Threading.Monitor.Wait(this); + Monitor.Wait(this); } - + // // We want to wait until all connections are in holding state // outside the thread synchronization. // connections = (LinkedList)_connections.Clone(); } - + // // Now we wait until each connection is in holding state. // @@ -618,12 +1227,12 @@ namespace IceInternal connection.waitUntilHolding(); } } - + public void waitUntilFinished() { Thread threadPerIncomingConnectionFactory = null; - LinkedList connections; - + LinkedList connections = null; + lock(this) { // @@ -632,7 +1241,7 @@ namespace IceInternal // while(_state != StateClosed || _acceptor != null) { - System.Threading.Monitor.Wait(this); + Monitor.Wait(this); } threadPerIncomingConnectionFactory = _threadPerIncomingConnectionFactory; @@ -644,14 +1253,13 @@ namespace IceInternal _adapter = null; // - // We want to wait until all connections are finished - // outside the thread synchronization. - // - // We set _connections to null because our destructor must not - // invoke methods on member objects. + // We want to wait until all connections are finished outside the + // thread synchronization. // - connections = _connections; - _connections = null; + if(_connections != null) + { + connections = new LinkedList(_connections); + } } if(threadPerIncomingConnectionFactory != null) @@ -659,9 +1267,6 @@ namespace IceInternal threadPerIncomingConnectionFactory.Join(); } - // - // Now we wait until the destruction of each connection is finished. - // if(connections != null) { foreach(Ice.ConnectionI connection in connections) @@ -669,43 +1274,44 @@ namespace IceInternal connection.waitUntilFinished(); } } + + lock(this) + { + _connections = null; + } } - + public EndpointI endpoint() { // No mutex protection necessary, _endpoint is immutable. return _endpoint; } - - public Ice.ConnectionI[] connections() + + public LinkedList connections() { lock(this) { LinkedList connections = new LinkedList(); - + // // Only copy connections which have not been destroyed. // foreach(Ice.ConnectionI connection in _connections) { - if(!connection.isDestroyed()) + if(connection.isActiveOrHolding()) { connections.Add(connection); } } - Ice.ConnectionI[] arr = new Ice.ConnectionI[connections.Count]; - if(arr.Length != 0) - { - connections.CopyTo(arr, 0); - } - return arr; + + return connections; } } - + public void flushBatchRequests() { // - // connections() is synchronized, so no need to synchronize here. + // connections() is synchronized, no need to synchronize here. // foreach(Ice.ConnectionI connection in connections()) { @@ -719,45 +1325,46 @@ namespace IceInternal } } } - + // // Operations from EventHandler. // - + public override bool datagram() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. return _endpoint.datagram(); } - + public override bool readable() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. return false; } - - public override void read(BasicStream unused) + + public override bool read(BasicStream unused) { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. Debug.Assert(false); // Must not be called. + return false; } - + public override void message(BasicStream unused, ThreadPool threadPool) { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. Ice.ConnectionI connection = null; - - lock(this) + + try { - try + lock(this) { if(_state != StateActive) { Thread.Sleep(0); return; } - + // // Reap connections for which destruction has completed. // @@ -770,11 +1377,11 @@ namespace IceInternal p.Remove(); } } - + // // Now accept a new connection. // - Transceiver transceiver; + Transceiver transceiver = null; try { transceiver = _acceptor.accept(0); @@ -798,64 +1405,47 @@ namespace IceInternal } return; } - + Debug.Assert(transceiver != null); try { Debug.Assert(!_threadPerConnection); connection = new Ice.ConnectionI(instance_, transceiver, _endpoint, _adapter, false); - connection.start(); } - catch(Ice.LocalException) + catch(Ice.LocalException ex) { + try + { + transceiver.close(); + } + catch(Ice.LocalException) + { + // Ignore + } + + if(_warn) + { + warning(ex); + } return; } - + _connections.Add(connection); } - finally - { - // - // This makes sure that we promote a follower before - // we leave the scope of the mutex above, but after we - // call accept() (if we call it). - // - threadPool.promoteFollower(); - } - } - - Debug.Assert(connection != null); - - // - // We validate and activate outside the thread - // synchronization, to not block the factory. - // - try - { - connection.validate(); } - catch(Ice.LocalException) + finally { - lock(this) - { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - LinkedList.Enumerator p = (LinkedList.Enumerator)_connections.GetEnumerator(); - while(p.MoveNext()) - { - if((Ice.ConnectionI)p.Current == connection) - { - p.Remove(); - break; - } - } - return; - } + // + // This makes sure that we promote a follower before we leave the scope of the mutex + // above, but after we call accept() (if we call it). + // + threadPool.promoteFollower(); } - - connection.activate(); + + connection.start(this); } - + public override void finished(ThreadPool threadPool) { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. @@ -864,34 +1454,78 @@ namespace IceInternal { threadPool.promoteFollower(); Debug.Assert(threadPool == ((Ice.ObjectAdapterI)_adapter).getThreadPool()); - + --_finishedCount; if(_finishedCount == 0 && _state == StateClosed) { _acceptor.close(); _acceptor = null; - System.Threading.Monitor.PulseAll(this); + Monitor.PulseAll(this); } } } - + public override void exception(Ice.LocalException ex) { Debug.Assert(false); // Must not be called. } - + public override string ToString() { if(_transceiver != null) { return _transceiver.ToString(); } - + Debug.Assert(_acceptor != null); return _acceptor.ToString(); } - + + // + // Operations from ConnectionI.StartCallback + // + public void connectionStartCompleted(Ice.ConnectionI connection) + { + lock(this) + { + // + // Initially, connections are in the holding state. If the factory is active + // we activate the connection. + // + if(_state == StateActive) + { + connection.activate(); + } + } + } + + public void connectionStartFailed(Ice.ConnectionI connection, Ice.LocalException ex) + { + lock(this) + { + if(_state == StateClosed) + { + return; + } + + if(_warn) + { + warning(ex); + } + + // + // If the connection is finished, remove it right away from + // the connection map. Otherwise, we keep it in the map, it + // will eventually be reaped. + // + if(connection.isFinished()) + { + _connections.Remove(connection); + } + } + } + public IncomingConnectionFactory(Instance instance, EndpointI endpoint, Ice.ObjectAdapter adapter, string adapterName) : base(instance) @@ -904,7 +1538,7 @@ namespace IceInternal instance_.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0 ? true : false; _connections = new LinkedList(); _state = StateHolding; - + DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); if(defaultsAndOverrides.overrideTimeout) @@ -928,30 +1562,27 @@ namespace IceInternal if(_transceiver != null) { _endpoint = h; - + Ice.ConnectionI connection = null; - try { connection = new Ice.ConnectionI(instance_, _transceiver, _endpoint, _adapter, _threadPerConnection); - connection.start(); - connection.validate(); } catch(Ice.LocalException) { - // - // If a connection object was constructed, then - // validate() must have raised the exception. - // - if(connection != null) + try { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. + _transceiver.close(); } - - return; + catch(Ice.LocalException) + { + // Ignore + } + throw; } - + connection.start(null); + _connections.Add(connection); } else @@ -985,12 +1616,12 @@ namespace IceInternal } } } - catch(Ice.LocalException) + catch(System.Exception ex) { // - // Clean up for finalizer. + // Clean up. // - + if(_acceptor != null) { try @@ -1011,49 +1642,28 @@ namespace IceInternal _threadPerIncomingConnectionFactory = null; } - throw; - } - catch(System.Exception ex) - { - // - // Clean up for finalizer. - // - - if(_acceptor != null) + if(ex is Ice.LocalException) { - try - { - _acceptor.close(); - } - catch(Ice.LocalException) - { - // Here we ignore any exceptions in close(). - } + throw; } - - lock(this) + else { - _state = StateClosed; - _acceptor = null; - _connections = null; - _threadPerIncomingConnectionFactory = null; + throw new Ice.SyscallException(ex); } - - throw new Ice.SyscallException(ex); } } - + private const int StateActive = 0; private const int StateHolding = 1; private const int StateClosed = 2; - + private void setState(int state) { if(_state == state) // Don't switch twice. { return; } - + switch (state) { case StateActive: @@ -1066,14 +1676,14 @@ namespace IceInternal { registerWithPool(); } - + foreach(Ice.ConnectionI connection in _connections) { connection.activate(); } break; } - + case StateHolding: { if(_state != StateActive) // Can only switch from active to holding. @@ -1084,14 +1694,14 @@ namespace IceInternal { unregisterWithPool(); } - + foreach(Ice.ConnectionI connection in _connections) { connection.hold(); } break; } - + case StateClosed: { if(_acceptor != null) @@ -1116,7 +1726,7 @@ namespace IceInternal unregisterWithPool(); } } - + foreach(Ice.ConnectionI connection in _connections) { connection.destroy(Ice.ConnectionI.ObjectAdapterDeactivated); @@ -1124,9 +1734,9 @@ namespace IceInternal break; } } - + _state = state; - System.Threading.Monitor.PulseAll(this); + Monitor.PulseAll(this); } private void registerWithPool() @@ -1140,7 +1750,7 @@ namespace IceInternal _registeredWithPool = true; } } - + private void unregisterWithPool() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. @@ -1153,10 +1763,11 @@ namespace IceInternal ++_finishedCount; // For each unregistration, finished() is called once. } } - + private void warning(Ice.LocalException ex) { - instance_.initializationData().logger.warning("connection exception:\n" + ex + '\n' + _acceptor.ToString()); + instance_.initializationData().logger.warning("connection exception:\n" + ex + '\n' + + _acceptor.ToString()); } private void run() @@ -1177,7 +1788,6 @@ namespace IceInternal catch(Ice.SocketException) { // Ignore socket exceptions. - return; } catch(Ice.TimeoutException) { @@ -1193,7 +1803,6 @@ namespace IceInternal } Ice.ConnectionI connection = null; - lock(this) { while(_state == StateHolding) @@ -1246,37 +1855,43 @@ namespace IceInternal } } - // - // Create a connection object for the connection. - // - if(transceiver != null) + if(transceiver == null) + { + continue; + } + + try + { + connection = new Ice.ConnectionI(instance_, transceiver, _endpoint, _adapter, + _threadPerConnection); + } + catch(Ice.LocalException ex) { try { - connection = new Ice.ConnectionI(instance_, transceiver, _endpoint, _adapter, - _threadPerConnection); - connection.start(); + transceiver.close(); } catch(Ice.LocalException) { - return; + // Ignore } - _connections.Add(connection); + if(_warn) + { + warning(ex); + } + continue; } + _connections.Add(connection); } // - // In thread per connection mode, the connection's thread - // will take care of connection validation and activation - // (for non-datagram connections). We don't want to block - // this thread waiting until validation is complete, - // because in contrast to thread pool mode, it is the only - // thread that can accept connections with this factory's - // acceptor. Therefore we don't call validate() and - // activate() from the connection factory in thread per - // connection mode. + // In thread-per-connection mode and regardless of the background mode, + // start() doesn't block. The connection thread is started and takes + // care of the connection validation and notifies the factory through + // the callback when it's done. // + connection.start(this); } } @@ -1304,16 +1919,16 @@ namespace IceInternal private Acceptor _acceptor; private readonly Transceiver _transceiver; private EndpointI _endpoint; - + private Ice.ObjectAdapter _adapter; - + private bool _registeredWithPool; private int _finishedCount; - + private readonly bool _warn; - + private LinkedList _connections; - + private int _state; private bool _threadPerConnection; diff --git a/cs/src/Ice/ConnectionI.cs b/cs/src/Ice/ConnectionI.cs index 2011efde71b..db975deb0a8 100644 --- a/cs/src/Ice/ConnectionI.cs +++ b/cs/src/Ice/ConnectionI.cs @@ -15,57 +15,106 @@ namespace Ice using System.Diagnostics; using System.Threading; - public sealed class ConnectionI : IceInternal.EventHandler, Connection + public sealed class ConnectionI : IceInternal.EventHandler, Connection, + IceInternal.SelectorThread.SocketReadyCallback { - public void validate() + public interface StartCallback { - if(!endpoint().datagram()) // Datagram connections are always implicitly validated. - { - bool active; + void connectionStartCompleted(ConnectionI connection); + void connectionStartFailed(ConnectionI connection, LocalException ex); + } + public void start(StartCallback callback) + { + try + { lock(this) { - if(_thread != null && _thread != Thread.CurrentThread) + _startCallback = callback; + + // + // The connection might already be closed if the communicator was destroyed. + // + if(_state == StateClosed) { - // - // In thread per connection mode, this connection's thread - // will take care of connection validation. Therefore all we - // have to do here is to wait until this thread has completed - // validation. - // - while(_state == StateNotValidated) + Debug.Assert(_exception != null); + throw _exception; + } + + // + // In thread per connection mode, we create the thread for the connection. The + // intialization and validation of the connection is taken care of by the thread + // per connection. If a callback is given, no need to wait, the thread will notify + // the callback, otherwise wait until the connection is validated. + // + if(_threadPerConnection) + { + try { - Monitor.Wait(this); + _thread = new Thread(new ThreadStart(RunThreadPerConnection)); + _thread.IsBackground = true; + _thread.Start(); } - - if(_state >= StateClosing) + catch(System.Exception ex) { - Debug.Assert(_exception != null); - throw _exception; + _logger.error("cannot create thread for connection:\n" + ex); + + // + // Clean up. + // + _thread = null; + _state = StateClosed; + + throw new SyscallException(ex); } - return; + if(callback == null) // Wait for the connection to be validated. + { + while(_state <= StateNotValidated) + { + Monitor.Wait(this); + } + + if(_state >= StateClosing) + { + Debug.Assert(_exception != null); + throw _exception; + } + } + return; // We're done. } + } - Debug.Assert(_state == StateNotValidated || _state == StateClosed); + Debug.Assert(!_threadPerConnection); + + // + // Initialize the connection transceiver and then validate the connection. + // + IceInternal.SocketStatus status = initialize(); + if(status == IceInternal.SocketStatus.Finished) + { + status = validate(); + } + + if(status == IceInternal.SocketStatus.Finished) + { + finishStart(null); + return; // We're done! + } + + // + // If the initialization or validation couldn't be completed without potentially + // blocking, we register the connection with the selector thread and return. + // + + lock(this) + { if(_state == StateClosed) { Debug.Assert(_exception != null); throw _exception; } - if(_adapter != null) - { - active = true; // The server side has the active role for connection validation. - } - else - { - active = false; // The client side has the passive role for connection validation. - } - } - - try - { int timeout; IceInternal.DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); if(defaultsAndOverrides.overrideConnectTimeout) @@ -76,176 +125,126 @@ namespace Ice { timeout = _endpoint.timeout(); } - - if(active) + + _sendInProgress = true; + _selectorThread.register(_transceiver.fd(), this, status, timeout); + } + } + catch(LocalException ex) + { + lock(this) + { + setState(StateClosed, ex); + + // + // If start is called with a callback, the callback is notified either by the + // thread per conncetion or the thread pool. + // + if(callback != null) { - lock(_sendMutex) + if(!_threadPerConnection) { - if(_transceiver == null) // Has the transceiver already been closed? - { - Debug.Assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } - - IceInternal.BasicStream os = new IceInternal.BasicStream(instance_); - os.writeBlob(IceInternal.Protocol.magic); - os.writeByte(IceInternal.Protocol.protocolMajor); - os.writeByte(IceInternal.Protocol.protocolMinor); - os.writeByte(IceInternal.Protocol.encodingMajor); - os.writeByte(IceInternal.Protocol.encodingMinor); - os.writeByte(IceInternal.Protocol.validateConnectionMsg); - os.writeByte((byte)0); // Compression status (always zero for validate connection). - os.writeInt(IceInternal.Protocol.headerSize); // Message size. - IceInternal.TraceUtil.traceHeader("sending validate connection", os, _logger, _traceLevels); - try - { - _transceiver.initialize(timeout); - _transceiver.write(os, timeout); - } - catch(TimeoutException) - { - throw new ConnectTimeoutException(); - } + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. } + return; } - else + + // + // Close the transceiver if there's no thread per connection. Otherwise, wait + // for the thread per connection to take care of it. + // + if(_thread == null && _transceiver != null) { - IceInternal.BasicStream ins = new IceInternal.BasicStream(instance_); - ins.resize(IceInternal.Protocol.headerSize, true); - ins.pos(0); try { - _transceiver.initialize(timeout); - _transceiver.read(ins, timeout); - } - catch(TimeoutException) - { - throw new ConnectTimeoutException(); - } - Debug.Assert(ins.pos() == IceInternal.Protocol.headerSize); - ins.pos(0); - byte[] m = ins.readBlob(4); - if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || - m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) - { - BadMagicException ex = new BadMagicException(); - ex.badMagic = m; - throw ex; - } - byte pMajor = ins.readByte(); - byte pMinor = ins.readByte(); - if(pMajor != IceInternal.Protocol.protocolMajor) - { - UnsupportedProtocolException e = new UnsupportedProtocolException(); - e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; - e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; - e.major = IceInternal.Protocol.protocolMajor; - e.minor = IceInternal.Protocol.protocolMinor; - throw e; - } - byte eMajor = ins.readByte(); - byte eMinor = ins.readByte(); - if(eMajor != IceInternal.Protocol.encodingMajor) - { - UnsupportedEncodingException e = new UnsupportedEncodingException(); - e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; - e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; - e.major = IceInternal.Protocol.encodingMajor; - e.minor = IceInternal.Protocol.encodingMinor; - throw e; - } - byte messageType = ins.readByte(); - if(messageType != IceInternal.Protocol.validateConnectionMsg) - { - throw new ConnectionNotValidatedException(); + _transceiver.close(); } - ins.readByte(); // Ignore compression status for validate connection. - int size = ins.readInt(); - if(size != IceInternal.Protocol.headerSize) + catch(LocalException) { - throw new IllegalMessageSizeException(); + // Here we ignore any exceptions in close(). } - IceInternal.TraceUtil.traceHeader("received validate connection", ins, _logger, _traceLevels); - } - } - catch(LocalException ex) - { - lock(this) - { - setState(StateClosed, ex); - Debug.Assert(_exception != null); - throw _exception; + _transceiver = null; } } - } - - lock(this) - { - if(_acmTimeout > 0) - { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; - } - - // - // We start out in holding state. - // - setState(StateHolding); + + waitUntilFinished(); + throw ex; } } - + public void activate() { lock(this) { - while(_state == StateNotValidated) + if(_state <= StateNotValidated) { - Monitor.Wait(this); + return; + } + + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; } setState(StateActive); } } - + public void hold() { lock(this) { - while(_state == StateNotValidated) + if(_state <= StateNotValidated) { - Monitor.Wait(this); + return; } setState(StateHolding); } } - + // DestructionReason. public const int ObjectAdapterDeactivated = 0; public const int CommunicatorDestroyed = 1; - + public void destroy(int reason) { + bool send = false; lock(this) { switch(reason) { - case ObjectAdapterDeactivated: + case ObjectAdapterDeactivated: { - setState(StateClosing, new ObjectAdapterDeactivatedException()); + send = setState(StateClosing, new ObjectAdapterDeactivatedException()); break; } - - case CommunicatorDestroyed: + + case CommunicatorDestroyed: { - setState(StateClosing, new CommunicatorDestroyedException()); + send = setState(StateClosing, new CommunicatorDestroyedException()); break; } } } + + if(send) + { + try + { + finishSendMessage(); + } + catch(LocalException) + { + // Ignore. + } + } } - + public void close(bool force) { + bool send = false; lock(this) { if(force) @@ -265,17 +264,29 @@ namespace Ice { Monitor.Wait(this); } - - setState(StateClosing, new CloseConnectionException()); + + send = setState(StateClosing, new CloseConnectionException()); + } + } + + if(send) + { + try + { + finishSendMessage(); + } + catch(LocalException) + { + // Ignore. } } } - public bool isDestroyed() + public bool isActiveOrHolding() { lock(this) { - return _state >= StateClosing; + return _state > StateNotValidated && _state < StateClosing; } } @@ -340,7 +351,7 @@ namespace Ice } } } - + public void waitUntilFinished() { Thread threadPerConnection; @@ -358,7 +369,7 @@ namespace Ice { Monitor.Wait(this); } - + // // Now we must wait until close() has been called on the // transceiver. @@ -369,12 +380,12 @@ namespace Ice { long absoluteWaitTime = _stateTime + _endpoint.timeout(); int waitTime = (int)(absoluteWaitTime - IceInternal.Time.currentMonotonicTimeMillis()); - + if(waitTime > 0) { // - // We must wait a bit longer until we close - // this connection. + // We must wait a bit longer until we close this + // connection. // Monitor.Wait(this, waitTime); if(IceInternal.Time.currentMonotonicTimeMillis() >= absoluteWaitTime) @@ -385,8 +396,8 @@ namespace Ice else { // - // We already waited long enough, so let's - // close this connection! + // We already waited long enough, so let's close this + // connection! // setState(StateClosed, new CloseTimeoutException()); } @@ -418,9 +429,11 @@ namespace Ice threadPerConnection.Join(); } } - + public void monitor() { + bool send = false; + if(!Monitor.TryEnter(this)) { return; @@ -432,118 +445,50 @@ namespace Ice { return; } - - // - // Check for timed out async requests. - // - foreach(IceInternal.OutgoingAsync og in _asyncRequests.Values) - { - if(og.timedOut__()) - { - setState(StateClosed, new TimeoutException()); - return; - } - } - + // // Active connection management for idle connections. // // - if(_acmTimeout > 0 && - _requests.Count == 0 && _asyncRequests.Count == 0 && - !_batchStreamInUse && _batchStream.isEmpty() && - _dispatchCount == 0) + if(_acmTimeout <= 0 || + _requests.Count > 0 || _asyncRequests.Count > 0 || + _batchStreamInUse || !_batchStream.isEmpty() || + _sendInProgress || _dispatchCount > 0) { - if(IceInternal.Time.currentMonotonicTimeMillis() >= _acmAbsoluteTimeoutMillis) - { - setState(StateClosing, new ConnectionTimeoutException()); - return; - } + return; + } + + if(IceInternal.Time.currentMonotonicTimeMillis() >= _acmAbsoluteTimeoutMillis) + { + send = setState(StateClosing, new ConnectionTimeoutException()); } } finally { Monitor.Exit(this); } - } - - private IceInternal.BasicStream doCompress(IceInternal.BasicStream uncompressed, bool compress) - { - if(_compressionSupported) + + if(send) { - if(compress && uncompressed.size() >= 100) + try { - // - // Do compression. - // - IceInternal.BasicStream cstream = null; - if(uncompressed.compress(ref cstream, IceInternal.Protocol.headerSize, _compressionLevel)) - { - // - // Set compression status. - // - cstream.pos(9); - cstream.writeByte((byte)2); - - // - // Write the size of the compressed stream into the header. - // - cstream.pos(10); - cstream.writeInt(cstream.size()); - - // - // Write the compression status and size of the compressed stream into the header of the - // uncompressed stream -- we need this to trace requests correctly. - // - uncompressed.pos(9); - uncompressed.writeByte((byte)2); - uncompressed.writeInt(cstream.size()); - - return cstream; - } + finishSendMessage(); + } + catch(LocalException) + { + // Ignore. } } - - uncompressed.pos(9); - uncompressed.writeByte((byte)((_compressionSupported && compress) ? 1 : 0)); - - // - // Not compressed, fill in the message size. - // - uncompressed.pos(10); - uncompressed.writeInt(uncompressed.size()); - - return uncompressed; - } - - /* - private class MessageInfo - { - MessageInfo(IceInternal.BasicStream stream) - { - this.stream = stream; - } - - IceInternal.BasicStream stream; - bool destroyStream; - int invokeNum; - int requestId; - byte compress; - IceInternal.ServantManager servantManager; - ObjectAdapter adapter; - IceInternal.OutgoingAsync outAsync; } - */ - public void sendRequest(IceInternal.BasicStream os, IceInternal.Outgoing og, bool compress) + public bool sendRequest(IceInternal.Outgoing og, bool compress, bool response) { int requestId = 0; - IceInternal.BasicStream stream = null; + IceInternal.BasicStream os = og.ostr(); + bool send = false; lock(this) { - Debug.Assert(!(og != null && _endpoint.datagram())); // Twoway requests cannot be datagrams. - if(_exception != null) { // @@ -557,10 +502,7 @@ namespace Ice Debug.Assert(_state > StateNotValidated); Debug.Assert(_state < StateClosing); - // - // Only add to the request map if this is a twoway call. - // - if(og != null) + if(response) { // // Create a new unique request ID. @@ -571,94 +513,71 @@ namespace Ice _nextRequestId = 1; requestId = _nextRequestId++; } - + // // Fill in the request ID. // os.pos(IceInternal.Protocol.headerSize); os.writeInt(requestId); + } + // + // Send the message. If it can't be sent without blocking the message is added + // to _sendStreams and it will be sent by the selector thread or by this thread + // if flush is true. + // + try + { + send = sendMessage(new OutgoingMessage(og, og.ostr(), compress, response), false); + } + catch(LocalException ex) + { + setState(StateClosed, ex); + Debug.Assert(_exception != null); + throw _exception; + } + + if(response) + { // // Add to the requests map. // _requests[requestId] = og; } - stream = doCompress(os, _overrideCompress ? _overrideCompressValue : compress); - - if(_acmTimeout > 0) + if(!send) { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + return !_sendInProgress && _queuedStreams.Count == 0; // The request was sent if it's not queued! } } - - try + + if(send) { - lock(_sendMutex) + try { - if(_transceiver == null) // Has the transceiver already been closed? - { - Debug.Assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } - - // - // Send the request. - // - IceInternal.TraceUtil.traceRequest("sending request", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + finishSendMessage(); } - } - catch(LocalException ex) - { - lock(this) + catch(LocalException) { - setState(StateClosed, ex); Debug.Assert(_exception != null); - - if(og != null) + if(!response) // Twoway calls are notified through finished() { - // - // If the request has already been removed from - // the request map, we are out of luck. It would - // mean that finished() has been called already, - // and therefore the exception has been set using - // the Outgoing::finished() callback. In this - // case, we cannot throw the exception here, - // because we must not both raise an exception and - // have Outgoing::finished() called with an - // exception. This means that in some rare cases, - // a request will not be retried even though it - // could. But I honestly don't know how I could - // avoid this, without a very elaborate and - // complex design, which would be bad for - // performance. - // - IceInternal.Outgoing o = (IceInternal.Outgoing)_requests[requestId]; - _requests.Remove(requestId); - if(o != null) - { - Debug.Assert(o == og); - throw _exception; - } - } - else - { - throw _exception; + throw; } } } + + return true; // The request was sent. } - - public void sendAsyncRequest(IceInternal.BasicStream os, IceInternal.OutgoingAsync og, bool compress) + + public void sendAsyncRequest(IceInternal.OutgoingAsync og, bool compress, bool response) { int requestId = 0; - IceInternal.BasicStream stream = null; + IceInternal.BasicStream os = og.ostr__(); + bool send = false; lock(this) { - Debug.Assert(!_endpoint.datagram()); // Twoway requests cannot be datagrams, and async implies twoway. - if(_exception != null) { // @@ -672,85 +591,62 @@ namespace Ice Debug.Assert(_state > StateNotValidated); Debug.Assert(_state < StateClosing); - // - // Create a new unique request ID. - // - requestId = _nextRequestId++; - if(requestId <= 0) + if(response) { - _nextRequestId = 1; + // + // Create a new unique request ID. + // requestId = _nextRequestId++; - } - - // - // Fill in the request ID. - // - os.pos(IceInternal.Protocol.headerSize); - os.writeInt(requestId); + if(requestId <= 0) + { + _nextRequestId = 1; + requestId = _nextRequestId++; + } - // - // Add to the async requests map. - // - _asyncRequests[requestId] = og; - - stream = doCompress(os, _overrideCompress ? _overrideCompressValue : compress); + // + // Fill in the request ID. + // + os.pos(IceInternal.Protocol.headerSize); + os.writeInt(requestId); + } - if(_acmTimeout > 0) + try { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + send = sendMessage(new OutgoingMessage(og, og.ostr__(), compress, response), false); } - } - - try - { - lock(_sendMutex) + catch(LocalException ex) { - if(_transceiver == null) // Has the transceiver already been closed? - { - Debug.Assert(_exception != null); - throw _exception; // The exception is imuutable at this point. - } + setState(StateClosed, ex); + Debug.Assert(_exception != null); + throw _exception; + } + if(response) + { // - // Send the request. + // Add to the async requests map. // - IceInternal.TraceUtil.traceRequest("sending asynchronous request", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + _asyncRequests[requestId] = og; } } - catch(LocalException ex) + + if(send) { - lock(this) + try + { + finishSendMessage(); + } + catch(LocalException) { - setState(StateClosed, ex); Debug.Assert(_exception != null); - - // - // If the request has already been removed from the - // async request map, we are out of luck. It would - // mean that finished() has been called already, and - // therefore the exception has been set using the - // OutgoingAsync::finished__() callback. In this case, - // we cannot throw the exception here, because we must - // not both raise an exception and have - // OutgoingAsync::finished__() called with an - // exception. This means that in some rare cases, a - // request will not be retried even though it - // could. But I honestly don't know how I could avoid - // this, without a very elaborate and complex design, - // which would be bad for performance. - // - IceInternal.OutgoingAsync o = (IceInternal.OutgoingAsync)_asyncRequests[requestId]; - _asyncRequests.Remove(requestId); - if(o != null) + if(!response) // Twoway calls are notified through finished() { - Debug.Assert(o == og); - throw _exception; + throw; } } } } - + public void prepareBatchRequest(IceInternal.BasicStream os) { lock(this) @@ -762,7 +658,7 @@ namespace Ice { Monitor.Wait(this); } - + if(_exception != null) { throw _exception; @@ -770,7 +666,7 @@ namespace Ice Debug.Assert(_state > StateNotValidated); Debug.Assert(_state < StateClosing); - + if(_batchStream.isEmpty()) { try @@ -783,76 +679,129 @@ namespace Ice throw; } } - + _batchStreamInUse = true; _batchMarker = _batchStream.size(); _batchStream.swap(os); - + // // The batch stream now belongs to the caller, until // finishBatchRequest() or abortBatchRequest() is called. // } } - + public void finishBatchRequest(IceInternal.BasicStream os, bool compress) { - bool autoflush = false; - byte[] lastRequest = null; - - lock(this) + bool send = false; + try { - // - // Get the batch stream back. - // - _batchStream.swap(os); - - if(_batchAutoFlush) + lock(this) { - lock(_sendMutex) + // + // Get the batch stream back. + // + _batchStream.swap(os); + + if(_exception != null) { - if(_transceiver == null) + throw _exception; + } + + bool flush = false; + if(_batchAutoFlush) + { + // + // Throw memory limit exception if the first message added causes us to go over + // limit. Otherwise put aside the marshalled message that caused limit to be + // exceeded and rollback stream to the marker. + // + try { - Debug.Assert(_exception != null); - throw _exception; // The exception is immutable at this point. + _transceiver.checkSendSize(_batchStream.getBuffer(), instance_.messageSizeMax()); + } + catch(LocalException) + { + if(_batchRequestNum > 0) + { + flush = true; + } + else + { + throw; + } } + } + + if(flush) + { // - // Throw memory limit exception if the first - // message added causes us to go over - // limit. Otherwise put aside the marshalled - // message that caused limit to be exceeded and - // rollback stream to the marker. + // Temporarily save the last request. // + int requestSize = _batchStream.size() - _batchMarker; + byte[] lastRequest = new byte[requestSize]; + Buffer.BlockCopy(_batchStream.getBuffer().b.rawBytes(), _batchMarker, lastRequest, 0, + requestSize); + _batchStream.resize(_batchMarker, false); + try { - _transceiver.checkSendSize(_batchStream, instance_.messageSizeMax()); + // + // Fill in the number of requests in the batch. + // + _batchStream.pos(IceInternal.Protocol.headerSize); + _batchStream.writeInt(_batchRequestNum); + + OutgoingMessage message = new OutgoingMessage(_batchStream, _batchRequestCompress, true); + send = sendMessage(message, false); + if(send) + { + // + // If the request can't be sent immediately and this is a foreground send, + // we adopt the stream to be able to re-use _batchStream immediately. + // + message.adopt(); + } } catch(Ice.LocalException ex) { - if(_batchRequestNum == 0) - { - resetBatch(true); - throw ex; - } - int requestSize = _batchStream.size() - _batchMarker; - lastRequest = new byte[requestSize]; - Buffer.BlockCopy(_batchStream.prepareRead().rawBytes(), _batchMarker, lastRequest, 0, - requestSize); - _batchStream.resize(_batchMarker, false); - autoflush = true; + setState(StateClosed, ex); + Debug.Assert(_exception != null); + throw _exception; + } + + // + // Reset the batch stream. + // + _batchStream = new IceInternal.BasicStream(instance_, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + // + // Check again if the last request doesn't exceed the maximum message size. + // + if(IceInternal.Protocol.requestBatchHdr.Length + lastRequest.Length > + instance_.messageSizeMax()) + { + throw new MemoryLimitException(); } + + // + // Start a new batch with the last message that caused us to go over the limit. + // + _batchStream.writeBlob(IceInternal.Protocol.requestBatchHdr); + _batchStream.writeBlob(lastRequest); } - } - if(!autoflush) - { - // + + // // Increment the number of requests in the batch. // ++_batchRequestNum; // - // We compress the whole batch if there is at least - // one compressed message. + // We compress the whole batch if there is at least one compressed + // message. // if(compress) { @@ -867,218 +816,163 @@ namespace Ice Monitor.PulseAll(this); } } - - if(autoflush) + catch(LocalException) { - // - // We have to keep _batchStreamInUse set until after we insert the - // saved marshalled data into a new stream. - // - flushBatchRequestsInternal(true); - - lock(this) + abortBatchRequest(); + if(send) { - // - // Throw memory limit exception if the message that caused us to go over - // limit causes us to exceed the limit by itself. - // - if(IceInternal.Protocol.requestBatchHdr.Length + lastRequest.Length > instance_.messageSizeMax()) - { - resetBatch(true); - throw new MemoryLimitException(); - } - - // - // Start a new batch with the last message that caused us to - // go over the limit. - // - try - { - _batchStream.writeBlob(IceInternal.Protocol.requestBatchHdr); - _batchStream.writeBlob(lastRequest); - } - catch(LocalException ex) - { - setState(StateClosed, ex); - throw; - } - - if(compress) - { - _batchRequestCompress = true; - } - - // - // Notify that the batch stream not in use anymore. - // - ++_batchRequestNum; - _batchStreamInUse = false; - Monitor.PulseAll(this); + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. } + throw; + } + + if(send) + { + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. } } - + public void abortBatchRequest() { lock(this) { - // - // Reset the batch stream. We cannot save old requests - // in the batch stream, as they might be corrupted due to - // incomplete marshaling. - // - resetBatch(true); + _batchStream = new IceInternal.BasicStream(instance_, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + Debug.Assert(_batchStreamInUse); + _batchStreamInUse = false; + Monitor.PulseAll(this); } } public void flushBatchRequests() { - flushBatchRequestsInternal(false); + IceInternal.BatchOutgoing @out = new IceInternal.BatchOutgoing(this, instance_); + @out.invoke(); } - private void flushBatchRequestsInternal(bool ignoreInUse) + public bool flushBatchRequests(IceInternal.BatchOutgoing @out) { - IceInternal.BasicStream stream = null; - + bool send = false; lock(this) { - if(!ignoreInUse) + while(_batchStreamInUse && _exception == null) { - while(_batchStreamInUse && _exception == null) - { - Monitor.Wait(this); - } + Monitor.Wait(this); } - + if(_exception != null) { throw _exception; } - if(_batchStream.isEmpty()) + if(_batchRequestNum == 0) { - return; // Nothing to do. + return true; } - Debug.Assert(_state > StateNotValidated); - Debug.Assert(_state < StateClosing); - - // - // Fill in the message size. - // - _batchStream.pos(10); - _batchStream.writeInt(_batchStream.size()); - // // Fill in the number of requests in the batch. // + _batchStream.pos(IceInternal.Protocol.headerSize); _batchStream.writeInt(_batchRequestNum); - stream = doCompress(_batchStream, _overrideCompress ? _overrideCompressValue : _batchRequestCompress); - - if(_acmTimeout > 0) - { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; - } + _batchStream.swap(@out.ostr()); - // - // Prevent that new batch requests are added while we are - // flushing. - // - _batchStreamInUse = true; - } - - try - { - lock(_sendMutex) + try { - if(_transceiver == null) // Has the transceiver already been closed? - { - Debug.Assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } - - // - // Send the batch request. - // - IceInternal.TraceUtil.traceBatchRequest("sending batch request", _batchStream, _logger, - _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + OutgoingMessage message = new OutgoingMessage(@out, @out.ostr(), _batchRequestCompress, false); + send = sendMessage(message, false); } - } - catch(LocalException ex) - { - lock(this) + catch(Ice.LocalException ex) { setState(StateClosed, ex); Debug.Assert(_exception != null); - - // - // Since batch requests area all oneways (or datarams), we - // must report the exception to the caller. - // throw _exception; } - } - lock(this) - { // - // Reset the batch stream, and notify that flushing is over. + // Reset the batch stream. // - resetBatch(!ignoreInUse); - } - } + _batchStream = new IceInternal.BasicStream(instance_, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + if(!send) + { + return !_sendInProgress && _queuedStreams.Count == 0; // The request was sent if it's not queued! + } + } - private void resetBatch(bool resetInUse) - { - _batchStream = new IceInternal.BasicStream(instance_, _batchAutoFlush); - _batchRequestNum = 0; - _batchRequestCompress = false; - - // - // Notify about the batch stream not being in use - // anymore. - // - if(resetInUse) + if(send) { - Debug.Assert(_batchStreamInUse); - _batchStreamInUse = false; - Monitor.PulseAll(this); + finishSendMessage(); } + return true; } - public void sendResponse(IceInternal.BasicStream os, byte compress) + public void flushAsyncBatchRequests(IceInternal.BatchOutgoingAsync outAsync) { - IceInternal.BasicStream stream = null; - try + bool send = false; + lock(this) { - lock(_sendMutex) + while(_batchStreamInUse && _exception == null) { - if(_transceiver == null) // Has the transceiver already been closed? - { - Debug.Assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } + Monitor.Wait(this); + } - stream = doCompress(os, compress != 0); + if(_exception != null) + { + throw _exception; + } - // - // Send the reply. - // - IceInternal.TraceUtil.traceReply("sending reply", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + if(_batchRequestNum == 0) + { + return; } - } - catch(LocalException ex) - { - lock(this) + + // + // Fill in the number of requests in the batch. + // + _batchStream.pos(IceInternal.Protocol.headerSize); + _batchStream.writeInt(_batchRequestNum); + + _batchStream.swap(outAsync.ostr__()); + + try + { + OutgoingMessage message = new OutgoingMessage(outAsync, outAsync.ostr__(), _batchRequestCompress, + false); + send = sendMessage(message, false); + } + catch(Ice.LocalException ex) { setState(StateClosed, ex); + Debug.Assert(_exception != null); + throw _exception; } + + // + // Reset the batch stream. + // + _batchStream = new IceInternal.BasicStream(instance_, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; } + if(send) + { + finishSendMessage(); + } + } + + public void sendResponse(IceInternal.BasicStream os, byte compressFlag) + { + bool send = false; lock(this) { Debug.Assert(_state > StateNotValidated); @@ -1090,11 +984,19 @@ namespace Ice Monitor.PulseAll(this); } + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } + + send = sendMessage(new OutgoingMessage(os, compressFlag != 0, true), false); + if(_state == StateClosing && _dispatchCount == 0) { - initiateShutdown(); + initiateShutdown(true); } - + if(_acmTimeout > 0) { _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; @@ -1105,10 +1007,23 @@ namespace Ice setState(StateClosed, ex); } } + + if(send) + { + try + { + finishSendMessage(); + } + catch(LocalException) + { + // Ignore. + } + } } - + public void sendNoResponse() { + bool send = false; lock(this) { Debug.Assert(_state > StateNotValidated); @@ -1119,10 +1034,21 @@ namespace Ice { Monitor.PulseAll(this); } - + + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } + if(_state == StateClosing && _dispatchCount == 0) { - initiateShutdown(); + send = initiateShutdown(false); + } + + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; } } catch(LocalException ex) @@ -1130,12 +1056,23 @@ namespace Ice setState(StateClosed, ex); } } + + if(send) + { + try + { + finishSendMessage(); + } + catch(LocalException) + { + // Ignore. + } + } } - + public IceInternal.EndpointI endpoint() { - // No mutex protection necessary, _endpoint is immutable. - return _endpoint; + return _endpoint; // No mutex protection necessary, _endpoint is immutable. } public bool threadPerConnection() @@ -1147,11 +1084,15 @@ namespace Ice { lock(this) { - if(_exception != null) + if(_state == StateClosing || _state == StateClosed) { + Debug.Assert(_exception != null); throw _exception; } - + else if(_state <= StateNotValidated) + { + return; + } Debug.Assert(_state < StateClosing); _adapter = adapter; @@ -1198,28 +1139,28 @@ namespace Ice connections); return instance_.proxyFactory().referenceToProxy(@ref); } - + // // Operations from EventHandler // - + public override bool datagram() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. return _endpoint.datagram(); // No mutex protection necessary, _endpoint is immutable. } - + public override bool readable() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. return true; } - - public override void read(IceInternal.BasicStream stream) + + public override bool read(IceInternal.BasicStream stream) { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. - _transceiver.read(stream, 0); + return _transceiver.read(stream.getBuffer(), 0); // // Updating _acmAbsoluteTimeoutMillis is too expensive here, @@ -1228,7 +1169,7 @@ namespace Ice // message(). // } - + public override void message(IceInternal.BasicStream stream, IceInternal.ThreadPool threadPool) { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. @@ -1243,12 +1184,12 @@ namespace Ice lock(this) { // - // We must promote with the synchronization, otherwise + // We must promote within the synchronization, otherwise // there could be various race conditions with close // connection messages and other messages. // threadPool.promoteFollower(); - + if(_state != StateClosed) { parseMessage(ref stream, ref invokeNum, ref requestId, ref compress, ref servantManager, @@ -1287,69 +1228,56 @@ namespace Ice Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. threadPool.promoteFollower(); - - LocalException exception = null; - Hashtable requests = null; - Hashtable asyncRequests = null; + LocalException localEx = null; lock(this) { --_finishedCount; - if(_finishedCount == 0 && _state == StateClosed) + if(_finishedCount > 0 || _state != StateClosed || _sendInProgress) { - // - // We must make sure that nobody is sending when we - // close the transeiver. - // - lock(_sendMutex) - { - try - { - _transceiver.close(); - } - catch(LocalException ex) - { - exception = ex; - } - - _transceiver = null; - Monitor.PulseAll(this); - } + return; } - if(_state == StateClosed || _state == StateClosing) + try { - requests = _requests; - _requests = new Hashtable(); - - asyncRequests = _asyncRequests; - _asyncRequests = new Hashtable(); + _transceiver.close(); } + catch(LocalException ex) + { + localEx = ex; + } + + _transceiver = null; + Monitor.PulseAll(this); } - if(requests != null) + finishStart(_exception); + + foreach(OutgoingMessage message in _queuedStreams) { - foreach(IceInternal.Outgoing og in requests.Values) - { - og.finished(_exception); // The exception is immutable at this point. - } + message.finished(_exception); } + _queuedStreams.Clear(); - if(asyncRequests != null) + foreach(IceInternal.Outgoing o in _requests.Values) // _requests is immutable at this point. { - foreach(IceInternal.OutgoingAsync og in asyncRequests.Values) - { - og.finished__(_exception); // The exception is immutable at this point. - } + o.finished(_exception); // The exception is immutable at this point. } + _requests.Clear(); - if(exception != null) + foreach(IceInternal.OutgoingAsync o in _asyncRequests.Values) // _asyncRequests is immutable at this point. { - throw exception; + o.finished__(_exception); // The exception is immutable at this point. + } + _asyncRequests.Clear(); + + if(localEx != null) + { + throw localEx; } } - + public override void exception(LocalException ex) { lock(this) @@ -1391,7 +1319,7 @@ namespace Ice { return _endpoint.timeout(); // No mutex protection necessary, _endpoint is immutable. } - + public string ice_toString_() { return ToString(); @@ -1403,6 +1331,150 @@ namespace Ice } // + // Operations from SocketReadyCallback + // + public IceInternal.SocketStatus socketReady(bool finished) + { + if(!finished) + { + try + { + // + // First, we check if there's something to send. If that's the case, the connection + // must be active and the only thing to do is send the queued streams. + // + if(_sendStreams.Count > 0) + { + if(!send(0)) + { + return IceInternal.SocketStatus.NeedWrite; + } + Debug.Assert(_sendStreams.Count == 0); + } + else + { + // + // If there's nothing to send, we're still validating the connection. + // + int state; + lock(this) + { + Debug.Assert(_state == StateClosed || _state <= StateNotValidated); + + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } + + state = _state; + } + + if(state == StateNotInitialized) + { + IceInternal.SocketStatus status = initialize(); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + } + + if(state <= StateNotValidated) + { + IceInternal.SocketStatus status = validate(); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + } + + finishStart(null); + } + } + catch(Ice.LocalException ex) + { + lock(this) + { + setState(StateClosed, ex); + } + } + } + + // + // If there's no more data to send or if connection validation is finished, we checkout + // the connection state to figure out whether or not it's time to unregister with the + // selector thread. + // + + lock(this) + { + Debug.Assert(_sendInProgress); + if(_state == StateClosed) + { + Debug.Assert(_startCallback == null || (!_threadPerConnection && !_registeredWithPool)); + + LinkedListNode<OutgoingMessage> node = _sendStreams.Last; + while(node != null) + { + _queuedStreams.AddFirst(node.Value); + node = node.Previous; + } + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + Monitor.PulseAll(this); + return IceInternal.SocketStatus.Finished; + } + else if(_waitingForSend > 0) + { + _sendInProgress = false; + Monitor.PulseAll(this); + return IceInternal.SocketStatus.Finished; + } + else if(_queuedStreams.Count == 0) + { + _sendInProgress = false; + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + return IceInternal.SocketStatus.Finished; + } + else + { + LinkedList<OutgoingMessage> streams = _queuedStreams; + _queuedStreams = _sendStreams; + _sendStreams = streams; + return IceInternal.SocketStatus.NeedWrite; // We're not finished yet, there's more data to send! + } + } + } + + public void socketTimeout() + { + lock(this) + { + if(_state <= StateNotValidated) + { + setState(StateClosed, new ConnectTimeoutException()); + } + else if(_state <= StateClosing) + { + setState(StateClosed, new TimeoutException()); + } + } + } + + // // Only used by the SSL plug-in. // // The external party has to synchronize the connection, since the @@ -1423,31 +1495,33 @@ namespace Ice IceInternal.EndpointI endpoint, ObjectAdapter adapter, bool threadPerConnection) : base(instance) { + InitializationData initData = instance.initializationData(); _threadPerConnection = threadPerConnection; _transceiver = transceiver; _desc = transceiver.ToString(); _type = transceiver.type(); _endpoint = endpoint; _adapter = adapter; - _logger = instance.initializationData().logger; // Cached for better performance. + _logger = initData.logger; // Cached for better performance. _traceLevels = instance.traceLevels(); // Cached for better performance. _registeredWithPool = false; _finishedCount = 0; - _warn = instance_.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0; - _cacheBuffers = instance_.initializationData().properties.getPropertyAsIntWithDefault( - "Ice.CacheMessageBuffers", 1) == 1; + _warn = initData.properties.getPropertyAsInt("Ice.Warn.Connections") > 0; + _cacheBuffers = initData.properties.getPropertyAsIntWithDefault("Ice.CacheMessageBuffers", 1) == 1; _acmAbsoluteTimeoutMillis = 0; _nextRequestId = 1; - _batchAutoFlush = instance_.initializationData().properties.getPropertyAsIntWithDefault( - "Ice.BatchAutoFlush", 1) > 0; + _batchAutoFlush = initData.properties.getPropertyAsIntWithDefault("Ice.BatchAutoFlush", 1) > 0; _batchStream = new IceInternal.BasicStream(instance, _batchAutoFlush); _batchStreamInUse = false; _batchRequestNum = 0; _batchRequestCompress = false; + _batchMarker = 0; + _sendInProgress = false; + _waitingForSend = 0; _dispatchCount = 0; - _state = StateNotValidated; + _state = StateNotInitialized; _stateTime = IceInternal.Time.currentMonotonicTimeMillis(); - + if(_endpoint.datagram()) { _acmTimeout = 0; @@ -1464,8 +1538,7 @@ namespace Ice } } - _compressionLevel = - instance_.initializationData().properties.getPropertyAsIntWithDefault("Ice.Compression.Level", 1); + _compressionLevel = initData.properties.getPropertyAsIntWithDefault("Ice.Compression.Level", 1); if(_compressionLevel < 1) { _compressionLevel = 1; @@ -1481,16 +1554,16 @@ namespace Ice _servantManager = adapterImpl.getServantManager(); } - if(!threadPerConnection) + try { - // - // Only set _threadPool if we really need it, i.e., if we are - // not in thread per connection mode. Thread pools have lazy - // initialization in Instance, and we don't want them to be - // created if they are not needed. - // - try + if(!threadPerConnection) { + // + // Only set _threadPool if we really need it, i.e., if we are + // not in thread per connection mode. Thread pools have lazy + // initialization in Instance, and we don't want them to be + // created if they are not needed. + // if(adapterImpl != null) { _threadPool = adapterImpl.getThreadPool(); @@ -1500,70 +1573,30 @@ namespace Ice _threadPool = instance.clientThreadPool(); } } - catch(System.Exception ex) - { - try - { - _transceiver.close(); - } - catch(LocalException) - { - // Here we ignore any exceptions in close(). - } - - throw new Ice.SyscallException(ex); - } - } - _overrideCompress = instance_.defaultsAndOverrides().overrideCompress; - _overrideCompressValue = instance_.defaultsAndOverrides().overrideCompressValue; - } + _selectorThread = instance_.selectorThread(); - public void start() - { - // - // If we are in thread per connection mode, create the thread for this connection. - // - if(_threadPerConnection) + _overrideCompress = instance_.defaultsAndOverrides().overrideCompress; + _overrideCompressValue = instance_.defaultsAndOverrides().overrideCompressValue; + } + catch(LocalException) { - try - { - _thread = new Thread(new ThreadStart(RunThreadPerConnection)); - _thread.IsBackground = true; - _thread.Start(); - } - catch(System.Exception ex) - { - _logger.error("cannot create thread for connection:\n" + ex); - - try - { - _transceiver.close(); - } - catch(LocalException) - { - // Here we ignore any exceptions in close(). - } - - // - // Clean up. - // - _transceiver = null; - _thread = null; - _state = StateClosed; - - throw new Ice.SyscallException(ex); - } + throw; + } + catch(System.Exception ex) + { + throw new SyscallException(ex); } } - private const int StateNotValidated = 0; - private const int StateActive = 1; - private const int StateHolding = 2; - private const int StateClosing = 3; - private const int StateClosed = 4; - - private void setState(int state, LocalException ex) + private const int StateNotInitialized = 0; + private const int StateNotValidated = 1; + private const int StateActive = 2; + private const int StateHolding = 3; + private const int StateClosing = 4; + private const int StateClosed = 5; + + private bool setState(int state, LocalException ex) { // // If setState() is called with an exception, then only closed @@ -1573,18 +1606,13 @@ namespace Ice if(_state == state) // Don't switch twice. { - return; + return false; } - + if(_exception == null) { - // - // If we are in closed state, an exception must be set. - // - Debug.Assert(_state != StateClosed); - _exception = ex; - + if(_warn) { // @@ -1607,16 +1635,16 @@ namespace Ice } } } - + // // We must set the new state before we notify requests of any // exceptions. Otherwise new requests may retry on a // connection that is not yet marked as closed or closing. // - setState(state); + return setState(state); } - private void setState(int state) + private bool setState(int state) { // // We don't want to send close connection messages if the endpoint @@ -1630,25 +1658,35 @@ namespace Ice // // Skip graceful shutdown if we are destroyed before validation. // - if(_state == StateNotValidated && state == StateClosing) + if(_state <= StateNotValidated && state == StateClosing) { state = StateClosed; } if(_state == state) // Don't switch twice. { - return; + return false; } - + switch(state) { - case StateNotValidated: + case StateNotInitialized: { Debug.Assert(false); break; } - - case StateActive: + + case StateNotValidated: + { + if(_state != StateNotInitialized) + { + Debug.Assert(_state == StateClosed); + return false; + } + break; + } + + case StateActive: { // // Can only switch from holding or not validated to @@ -1656,7 +1694,7 @@ namespace Ice // if(_state != StateHolding && _state != StateNotValidated) { - return; + return false; } if(!_threadPerConnection) { @@ -1664,8 +1702,8 @@ namespace Ice } break; } - - case StateHolding: + + case StateHolding: { // // Can only switch from active or not validated to @@ -1673,7 +1711,7 @@ namespace Ice // if(_state != StateActive && _state != StateNotValidated) { - return; + return false; } if(!_threadPerConnection) { @@ -1681,15 +1719,15 @@ namespace Ice } break; } - - case StateClosing: + + case StateClosing: { // // Can't change back from closed. // if(_state == StateClosed) { - return; + return false; } if(!_threadPerConnection) { @@ -1697,70 +1735,47 @@ namespace Ice } break; } - - case StateClosed: + + case StateClosed: { - if(_threadPerConnection) + if(_sendInProgress) { // - // If we are in thread per connection mode, we - // shutdown both for reading and writing. This will - // unblock any read call with an exception. The thread - // per connection then closes the transceiver. + // Unregister with both the pool and the selector thread. We unregister with + // the pool to ensure that it stops reading on the socket (otherwise, if the + // socket is closed the thread pool would spin always reading 0 from the FD). + // The selector thread will register again the FD with the pool once it's + // done. // - _transceiver.shutdownReadWrite(); + _selectorThread.unregister(_transceiver.fd()); + if(!_threadPerConnection) + { + unregisterWithPool(); + } + + _transceiver.shutdownWrite(); // Prevent further writes. } - else if(_state == StateNotValidated) + else if(_state <= StateNotValidated || _threadPerConnection) { // - // If we change from not validated, we can close right - // away. - // - Debug.Assert(!_registeredWithPool); - + // If we are in thread per connection mode and the thread is started, we + // shutdown both for reading and writing. This will unblock the read call + // with an exception. The thread per connection closes the transceiver. // - // We must make sure that nobidy is sending when we - // close the transceiver. - // - lock(_sendMutex) - { - try - { - _transceiver.close(); - } - catch(LocalException) - { - // Here we ignore any exceptions in close(). - } - - _transceiver = null; - //Monitor.PulseAll(); // We notify already below. - } + _transceiver.shutdownReadWrite(); } else { - // - // Otherwise we first must make sure that we are - // registered, then we unregister, and let finished() - // do the close. - // registerWithPool(); - unregisterWithPool(); + unregisterWithPool(); // Let finished() do the close. - // - // We must prevent any further writes when _state == StateClosed. - // However, functions such as sendResponse cannot acquire the main - // mutex in order to check _state. Therefore we shut down the write - // end of the transceiver, which causes subsequent write attempts - // to fail with an exception. - // - _transceiver.shutdownWrite(); + _transceiver.shutdownWrite(); // Prevent further writes. } break; } } - - // + + // // We only register with the connection monitor if our new state // is StateActive. Otherwise we unregister with the connection // monitor, but only if we were registered before, i.e., if our @@ -1768,76 +1783,522 @@ namespace Ice // IceInternal.ConnectionMonitor connectionMonitor = instance_.connectionMonitor(); if(connectionMonitor != null) - { + { if(state == StateActive) - { + { connectionMonitor.add(this); - } + } else if(_state == StateActive) - { + { connectionMonitor.remove(this); - } - } + } + } _state = state; _stateTime = IceInternal.Time.currentMonotonicTimeMillis(); Monitor.PulseAll(this); - + if(_state == StateClosing && _dispatchCount == 0) { try { - initiateShutdown(); + return initiateShutdown(false); } catch(LocalException ex) { setState(StateClosed, ex); } } + + return false; } - - private void initiateShutdown() + + private bool initiateShutdown(bool queue) { Debug.Assert(_state == StateClosing); Debug.Assert(_dispatchCount == 0); - + if(!_endpoint.datagram()) { - lock(_sendMutex) + // + // Before we shut down, we send a close connection + // message. + // + IceInternal.BasicStream os = new IceInternal.BasicStream(instance_); + os.writeBlob(IceInternal.Protocol.magic); + os.writeByte(IceInternal.Protocol.protocolMajor); + os.writeByte(IceInternal.Protocol.protocolMinor); + os.writeByte(IceInternal.Protocol.encodingMajor); + os.writeByte(IceInternal.Protocol.encodingMinor); + os.writeByte(IceInternal.Protocol.closeConnectionMsg); + os.writeByte(_compressionSupported ? (byte)1 : (byte)0); + os.writeInt(IceInternal.Protocol.headerSize); // Message size. + + return sendMessage(new OutgoingMessage(os, false, false), queue); + + // + // The CloseConnection message should be sufficient. Closing the write + // end of the socket is probably an artifact of how things were done + // in IIOP. In fact, shutting down the write end of the socket causes + // problems on Windows by preventing the peer from using the socket. + // For example, the peer is no longer able to continue writing a large + // message after the socket is shutdown. + // + //_transceiver.shutdownWrite(); + } + + return false; + } + + private IceInternal.SocketStatus initialize() + { + int timeout = 0; + if(_startCallback == null || _threadPerConnection) + { + IceInternal.DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideConnectTimeout) { - // - // Before we shut down, we send a close connection - // message. - // - IceInternal.BasicStream os = new IceInternal.BasicStream(instance_); - os.writeBlob(IceInternal.Protocol.magic); - os.writeByte(IceInternal.Protocol.protocolMajor); - os.writeByte(IceInternal.Protocol.protocolMinor); - os.writeByte(IceInternal.Protocol.encodingMajor); - os.writeByte(IceInternal.Protocol.encodingMinor); - os.writeByte(IceInternal.Protocol.closeConnectionMsg); - os.writeByte(_compressionSupported ? (byte)1 : (byte)0); - os.writeInt(IceInternal.Protocol.headerSize); // Message size. + timeout = defaultsAndOverrides.overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint.timeout(); + } + } + try + { + IceInternal.SocketStatus status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return status; + } + } + catch(Ice.TimeoutException) + { + throw new Ice.ConnectTimeoutException(); + } + + lock(this) + { + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } + + // + // Update the connection description once the transceiver is initialized. + // + _desc = _transceiver.ToString(); + + setState(StateNotValidated); + } + + return IceInternal.SocketStatus.Finished; + } + + private IceInternal.SocketStatus validate() + { + if(!_endpoint.datagram()) // Datagram connections are always implicitly validated. + { + int timeout = 0; + if(_startCallback == null || _threadPerConnection) + { + IceInternal.DefaultsAndOverrides defaultsAndOverrides = instance_.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideConnectTimeout) + { + timeout = defaultsAndOverrides.overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint.timeout(); + } + } + + if(_adapter != null) // The server side has the active role for connection validation. + { + IceInternal.BasicStream os = stream_; + if(os.size() == 0) + { + os.writeBlob(IceInternal.Protocol.magic); + os.writeByte(IceInternal.Protocol.protocolMajor); + os.writeByte(IceInternal.Protocol.protocolMinor); + os.writeByte(IceInternal.Protocol.encodingMajor); + os.writeByte(IceInternal.Protocol.encodingMinor); + os.writeByte(IceInternal.Protocol.validateConnectionMsg); + os.writeByte((byte)0); // Compression status (always zero for validate connection). + os.writeInt(IceInternal.Protocol.headerSize); // Message size. + IceInternal.TraceUtil.traceSend(os, _logger, _traceLevels); + os.prepareWrite(); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + Debug.Assert(_startCallback != null && !_threadPerConnection); + } + + try + { + if(!_transceiver.write(os.getBuffer(), timeout)) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return IceInternal.SocketStatus.NeedWrite; + } + } + catch(Ice.TimeoutException) + { + throw new Ice.ConnectTimeoutException(); + } + } + else // The client side has the passive role for connection validation. + { + IceInternal.BasicStream istr = stream_; + if(istr.size() == 0) + { + istr.resize(IceInternal.Protocol.headerSize, true); + istr.pos(0); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + Debug.Assert(_startCallback != null && !_threadPerConnection); + } + + try + { + if(!_transceiver.read(istr.getBuffer(), timeout)) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return IceInternal.SocketStatus.NeedRead; + } + } + catch(Ice.TimeoutException) + { + throw new Ice.ConnectTimeoutException(); + } + + Debug.Assert(istr.pos() == IceInternal.Protocol.headerSize); + istr.pos(0); + byte[] m = istr.readBlob(4); + if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || + m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) + { + BadMagicException ex = new BadMagicException(); + ex.badMagic = m; + throw ex; + } + byte pMajor = istr.readByte(); + byte pMinor = istr.readByte(); + if(pMajor != IceInternal.Protocol.protocolMajor) + { + UnsupportedProtocolException e = new UnsupportedProtocolException(); + e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; + e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; + e.major = IceInternal.Protocol.protocolMajor; + e.minor = IceInternal.Protocol.protocolMinor; + throw e; + } + byte eMajor = istr.readByte(); + byte eMinor = istr.readByte(); + if(eMajor != IceInternal.Protocol.encodingMajor) + { + UnsupportedEncodingException e = new UnsupportedEncodingException(); + e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; + e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; + e.major = IceInternal.Protocol.encodingMajor; + e.minor = IceInternal.Protocol.encodingMinor; + throw e; + } + byte messageType = istr.readByte(); + if(messageType != IceInternal.Protocol.validateConnectionMsg) + { + throw new ConnectionNotValidatedException(); + } + istr.readByte(); // Ignore compression status for validate connection. + int size = istr.readInt(); + if(size != IceInternal.Protocol.headerSize) + { + throw new IllegalMessageSizeException(); + } + IceInternal.TraceUtil.traceRecv(istr, _logger, _traceLevels); + } + } + + lock(this) + { + stream_.reset(); + + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } + + // + // We start out in holding state. + // + setState(StateHolding); + } + + return IceInternal.SocketStatus.Finished; + } + + private bool send(int timeout) + { + Debug.Assert(_transceiver != null); + Debug.Assert(_sendStreams.Count > 0); + + while(_sendStreams.Count > 0) + { + OutgoingMessage message = _sendStreams.First.Value; + if(!message.prepared) + { + IceInternal.BasicStream stream = message.stream; + + bool compress = _overrideCompress ? _overrideCompressValue : message.compress; + message.stream = doCompress(message.stream, compress); + message.stream.prepareWrite(); + message.prepared = true; + + if(message.outAsync != null) + { + IceInternal.TraceUtil.trace("sending asynchronous request", stream, _logger, _traceLevels); + } + else + { + IceInternal.TraceUtil.traceSend(stream, _logger, _traceLevels); + } + } + + if(!_transceiver.write(message.stream.getBuffer(), timeout)) + { + Debug.Assert(timeout == 0); + return false; + } + + message.sent(this, timeout == 0); // timeout == 0 indicates that this is called by the selector thread. + _sendStreams.RemoveFirst(); + } + + return true; + } + + private bool sendMessage(OutgoingMessage message, bool queue) + { + Debug.Assert(_state != StateClosed); + + // + // TODO: Remove support for foreground send? If set to true, messages are sent + // by the calling thread. Foreground send might still be useful for transports + // that don't support non-blocking send. + // + bool foreground = false; + + // + // If another thread is currently sending messages, we queue the message in _queuedStreams + // if we're not required to send the message in the foreground. If we're required to send + // the request in the foreground we wait until no more threads send messages. + // + if(_sendInProgress) + { + if(!foreground) + { + message.adopt(); + _queuedStreams.AddLast(message); + return false; + } + else if(queue) + { // - // Send the message. - // - IceInternal.TraceUtil.traceHeader("sending close connection", os, _logger, _traceLevels); - _transceiver.write(os, _endpoint.timeout()); - // - // The CloseConnection message should be sufficient. Closing the write - // end of the socket is probably an artifact of how things were done - // in IIOP. In fact, shutting down the write end of the socket causes - // problems on Windows by preventing the peer from using the socket. - // For example, the peer is no longer able to continue writing a large - // message after the socket is shutdown. + // Add the message to _sendStreams if requested, this is useful for sendResponse() to + // send the close connection message after sending the response. // - //_transceiver.shutdown(); + _sendStreams.AddLast(message); + return true; // The calling thread must send the messages by calling finishSendMessage() + } + else + { + ++_waitingForSend; + while(_sendInProgress) + { + Monitor.Wait(this); + } + --_waitingForSend; + + if(_state == StateClosed) + { + Debug.Assert(_exception != null); + throw _exception; + } } } + + Debug.Assert(!_sendInProgress); + + // + // Attempt to send the message without blocking. If the send blocks, we register + // the connection with the selector thread or we request the caller to call + // finishSendMessage() outside the synchronization. + // + + Debug.Assert(!message.prepared); + + IceInternal.BasicStream stream = message.stream; + + bool compress = _overrideCompress ? _overrideCompressValue : message.compress; + message.stream = doCompress(message.stream, compress); + message.stream.prepareWrite(); + message.prepared = true; + + if(message.outAsync != null) + { + IceInternal.TraceUtil.trace("sending asynchronous request", stream, _logger, _traceLevels); + } + else + { + IceInternal.TraceUtil.traceSend(stream, _logger, _traceLevels); + } + + if(!foreground && _transceiver.write(message.stream.getBuffer(), 0)) + { + message.sent(this, false); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + return false; + } + + _sendStreams.AddLast(message); + _sendInProgress = true; + if(!foreground) + { + message.adopt(); + _selectorThread.register(_transceiver.fd(), this, IceInternal.SocketStatus.NeedWrite, + _endpoint.timeout()); + return false; // The selector thread will send the message. + } + else + { + return true; // The calling thread must send the message by calling finishSendMessage() + } } - + + private void finishSendMessage() + { + try + { + // + // Send the queued messages with a blocking write(). + // + bool finished = send(_endpoint.timeout()); + Debug.Assert(finished); + } + catch(Ice.LocalException ex) + { + lock(this) + { + setState(StateClosed, ex); + + _sendStreams.Clear(); + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + Monitor.PulseAll(this); + + Debug.Assert(_exception != null); + throw _exception; + } + } + + lock(this) + { + Debug.Assert(_sendStreams.Count == 0); + if(_state == StateClosed) + { + _sendInProgress = false; + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + Monitor.PulseAll(this); + } + if(_waitingForSend > 0) + { + _sendInProgress = false; + Monitor.PulseAll(this); + } + else if(_queuedStreams.Count == 0) + { + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + _sendInProgress = false; + } + else + { + _selectorThread.register(_transceiver.fd(), this, IceInternal.SocketStatus.NeedWrite, + _endpoint.timeout()); + } + } + } + + private void finishStart(LocalException ex) + { + // + // We set _startCallback to null to break potential cyclic reference count + // and because the finalizer checks for it to ensure that we always invoke + // on the callback. + // + + StartCallback callback = null; + lock(this) + { + callback = _startCallback; + _startCallback = null; + } + + if(callback != null) + { + if(ex == null) + { + callback.connectionStartCompleted(this); + } + else + { + callback.connectionStartFailed(this, ex); + } + } + } + private void registerWithPool() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. @@ -1848,7 +2309,7 @@ namespace Ice _registeredWithPool = true; } } - + private void unregisterWithPool() { Debug.Assert(!_threadPerConnection); // Only for use with a thread pool. @@ -1860,7 +2321,56 @@ namespace Ice ++_finishedCount; // For each unregistration, finished() is called once. } } - + + private IceInternal.BasicStream doCompress(IceInternal.BasicStream uncompressed, bool compress) + { + if(_compressionSupported) + { + if(compress && uncompressed.size() >= 100) + { + // + // Do compression. + // + IceInternal.BasicStream cstream = null; + if(uncompressed.compress(ref cstream, IceInternal.Protocol.headerSize, _compressionLevel)) + { + // + // Set compression status. + // + cstream.pos(9); + cstream.writeByte((byte)2); + + // + // Write the size of the compressed stream into the header. + // + cstream.pos(10); + cstream.writeInt(cstream.size()); + + // + // Write the compression status and size of the compressed stream into the header of the + // uncompressed stream -- we need this to trace requests correctly. + // + uncompressed.pos(9); + uncompressed.writeByte((byte)2); + uncompressed.writeInt(cstream.size()); + + return cstream; + } + } + } + + uncompressed.pos(9); + uncompressed.writeByte((byte)((_compressionSupported && compress) ? 1 : 0)); + + // + // Not compressed, fill in the message size. + // + uncompressed.pos(10); + uncompressed.writeInt(uncompressed.size()); + + return uncompressed; + } + private void warning(string msg, System.Exception ex) { _logger.warning(msg + ":\n" + ex + "\n" + _transceiver.ToString()); @@ -1892,9 +2402,7 @@ namespace Ice { if(_compressionSupported) { - IceInternal.BasicStream uncompressedStream - = stream.uncompress(IceInternal.Protocol.headerSize); - stream = uncompressedStream; + stream = stream.uncompress(IceInternal.Protocol.headerSize); } else { @@ -1904,13 +2412,12 @@ namespace Ice } } stream.pos(IceInternal.Protocol.headerSize); - + switch(messageType) { case IceInternal.Protocol.closeConnectionMsg: { - IceInternal.TraceUtil.traceHeader("received close connection", stream, _logger, - _traceLevels); + IceInternal.TraceUtil.traceRecv(stream, _logger, _traceLevels); if(_endpoint.datagram()) { if(_warn) @@ -1925,17 +2432,17 @@ namespace Ice } break; } - case IceInternal.Protocol.requestMsg: + case IceInternal.Protocol.requestMsg: { if(_state == StateClosing) { - IceInternal.TraceUtil.traceRequest("received request during closing\n" - + "(ignored by server, client will retry)", - stream, _logger, _traceLevels); + IceInternal.TraceUtil.trace("received request during closing\n" + + "(ignored by server, client will retry)", stream, _logger, + _traceLevels); } else { - IceInternal.TraceUtil.traceRequest("received request", stream, _logger, _traceLevels); + IceInternal.TraceUtil.traceRecv(stream, _logger, _traceLevels); requestId = stream.readInt(); invokeNum = 1; servantManager = _servantManager; @@ -1944,19 +2451,18 @@ namespace Ice } break; } - - case IceInternal.Protocol.requestBatchMsg: + + case IceInternal.Protocol.requestBatchMsg: { if(_state == StateClosing) { - IceInternal.TraceUtil.traceBatchRequest("received batch request during closing\n" - + "(ignored by server, client will retry)", - stream, _logger, _traceLevels); + IceInternal.TraceUtil.trace("received batch request during closing\n" + + "(ignored by server, client will retry)", stream, _logger, + _traceLevels); } else { - IceInternal.TraceUtil.traceBatchRequest("received batch request", stream, _logger, - _traceLevels); + IceInternal.TraceUtil.traceRecv(stream, _logger, _traceLevels); invokeNum = stream.readInt(); if(invokeNum < 0) { @@ -1969,47 +2475,43 @@ namespace Ice } break; } - - case IceInternal.Protocol.replyMsg: - { - IceInternal.TraceUtil.traceReply("received reply", stream, _logger, _traceLevels); + case IceInternal.Protocol.replyMsg: + { + IceInternal.TraceUtil.traceRecv(stream, _logger, _traceLevels); requestId = stream.readInt(); - - IceInternal.Outgoing og = (IceInternal.Outgoing)_requests[requestId]; - _requests.Remove(requestId); - if(og != null) + IceInternal.Outgoing og = null; + if(_requests.TryGetValue(requestId, out og)) { + _requests.Remove(requestId); og.finished(stream); } else { - outAsync = (IceInternal.OutgoingAsync)_asyncRequests[requestId]; - _asyncRequests.Remove(requestId); - if(outAsync == null) + if(!_asyncRequests.ContainsKey(requestId)) { throw new UnknownRequestIdException(); } + outAsync = _asyncRequests[requestId]; + _asyncRequests.Remove(requestId); } break; } - - case IceInternal.Protocol.validateConnectionMsg: + + case IceInternal.Protocol.validateConnectionMsg: { - IceInternal.TraceUtil.traceHeader("received validate connection", stream, _logger, - _traceLevels); + IceInternal.TraceUtil.traceRecv(stream, _logger, _traceLevels); if(_warn) { _logger.warning("ignoring unexpected validate connection message:\n" + _desc); } break; } - - default: + + default: { - IceInternal.TraceUtil.traceHeader("received unknown message\n" + - "(invalid, closing connection)", - stream, _logger, _traceLevels); + IceInternal.TraceUtil.trace("received unknown message\n(invalid, closing connection)", stream, + _logger, _traceLevels); throw new UnknownMessageException(); } } @@ -2051,7 +2553,7 @@ namespace Ice IceInternal.BasicStream ins = inc.istr(); stream.swap(ins); IceInternal.BasicStream os = inc.ostr(); - + // // Prepare the response if necessary. // @@ -2059,15 +2561,15 @@ namespace Ice { Debug.Assert(invokeNum == 1); // No further invocations if a response is expected. os.writeBlob(IceInternal.Protocol.replyHdr); - + // // Add the request ID. // os.writeInt(requestId); } - + inc.invoke(servantManager); - + // // If there are more invocations, we need the stream back. // @@ -2075,7 +2577,7 @@ namespace Ice { stream.swap(ins); } - + reclaimIncoming(inc); inc = null; } @@ -2090,68 +2592,63 @@ namespace Ice { reclaimIncoming(inc); } - } + } } private void run() { - // - // For non-datagram connections, the thread-per-connection must - // validate and activate this connection, and not in the - // connection factory. Please see the comments in the connection - // factory for details. - // - if(!_endpoint.datagram()) + try { - try - { - validate(); - } - catch(LocalException) + // + // Initialize the connection transceiver and validate the connection using + // blocking operations. + // + + IceInternal.SocketStatus status; + + status = initialize(); + Debug.Assert(status == IceInternal.SocketStatus.Finished); + + status = validate(); + Debug.Assert(status == IceInternal.SocketStatus.Finished); + } + catch(LocalException ex) + { + lock(this) { - lock(this) - { - Debug.Assert(_state == StateClosed); + setState(StateClosed, ex); - // - // We must make sure that nobody is sending when we close - // the transceiver. - // - lock(_sendMutex) + if(_transceiver != null) + { + try { - if(_transceiver != null) - { - try - { - _transceiver.close(); - } - catch(LocalException) - { - // Here we ignore any exceptions in close(). - } - - _transceiver = null; - } - Monitor.PulseAll(this); - return; + _transceiver.close(); + } + catch(LocalException) + { + // Here we ignore any exceptions in close(). } + + _transceiver = null; } + Monitor.PulseAll(this); } - activate(); + finishStart(_exception); + return; } + finishStart(null); + bool warnUdp = instance_.initializationData().properties.getPropertyAsInt("Ice.Warn.Datagrams") > 0; bool closed = false; IceInternal.BasicStream stream = new IceInternal.BasicStream(instance_); - while(!closed) { // - // We must accept new connections outside the thread - // synchronization, because we use blocking accept. + // We must read new messages outside the thread synchronization because we use blocking reads. // try @@ -2160,7 +2657,7 @@ namespace Ice { stream.resize(IceInternal.Protocol.headerSize, true); stream.pos(0); - _transceiver.read(stream, -1); + _transceiver.read(stream.getBuffer(), -1); int pos = stream.pos(); if(pos < IceInternal.Protocol.headerSize) @@ -2230,7 +2727,7 @@ namespace Ice } else { - _transceiver.read(stream, -1); + _transceiver.read(stream.getBuffer(), -1); Debug.Assert(stream.pos() == stream.size()); } } @@ -2268,9 +2765,6 @@ namespace Ice LocalException localEx = null; - Hashtable requests = null; - Hashtable asyncRequests = null; - lock(this) { while(_state == StateHolding) @@ -2290,40 +2784,38 @@ namespace Ice // if(_state == StateClosed) { - // - // We must make sure that nobody is sending when we close - // the transceiver. - // - lock(_sendMutex) + if(_sendInProgress) { - try - { - _transceiver.close(); - } - catch(LocalException ex) - { - localEx = ex; - } + _selectorThread.unregister(_transceiver.fd()); + } - _transceiver = null; - Monitor.PulseAll(this); + // + // Prevent further writes. + // + _transceiver.shutdownWrite(); - // - // We cannot simply return here. We have to make sure - // that all requests (regular and async) are notified - // about the closed connection below. - // - closed = true; + while(_sendInProgress) + { + Monitor.Wait(this); } - } - if(_state == StateClosed || _state == StateClosing) - { - requests = _requests; - _requests = new Hashtable(); + try + { + _transceiver.close(); + } + catch(LocalException ex) + { + localEx = ex; + } + _transceiver = null; + Monitor.PulseAll(this); - asyncRequests = _asyncRequests; - _asyncRequests = new Hashtable(); + // + // We cannot simply return here. We have to make sure + // that all requests (regular and async) are notified + // about the closed connection below. + // + closed = true; } } @@ -2343,20 +2835,25 @@ namespace Ice // invokeAll(stream, invokeNum, requestId, compress, servantManager, adapter); - if(requests != null) + if(closed) { - foreach(IceInternal.Outgoing og in requests.Values) + foreach(OutgoingMessage message in _queuedStreams) + { + message.finished(_exception); // The exception is immutable at this point. + } + _queuedStreams.Clear(); + + foreach(IceInternal.Outgoing og in _requests.Values) { og.finished(_exception); // The exception is immutable at this point. } - } + _requests.Clear(); - if(asyncRequests != null) - { - foreach(IceInternal.OutgoingAsync og in asyncRequests.Values) + foreach(IceInternal.OutgoingAsync og in _asyncRequests.Values) { og.finished__(_exception); // The exception is immutable at this point. } + _asyncRequests.Clear(); } if(localEx != null) @@ -2372,35 +2869,6 @@ namespace Ice } } - public void RunThreadPerConnection() - { - if(instance_.initializationData().threadHook != null) - { - instance_.initializationData().threadHook.start(); - } - - try - { - run(); - } - catch(Exception ex) - { - _logger.error("exception in thread per connection:\n" + ToString() + "\n" + ex.ToString()); - } - catch(System.Exception ex) - { - _logger.error("system exception in thread per connection:\n" + ToString() + "\n" + - ex.ToString()); - } - finally - { - if(instance_.initializationData().threadHook != null) - { - instance_.initializationData().threadHook.stop(); - } - } - } - private IceInternal.Incoming getIncoming(ObjectAdapter adapter, bool response, byte compress, int requestId) { IceInternal.Incoming inc = null; @@ -2426,10 +2894,10 @@ namespace Ice { inc = new IceInternal.Incoming(instance_, this, adapter, response, compress, requestId); } - + return inc; } - + private void reclaimIncoming(IceInternal.Incoming inc) { if(_cacheBuffers) @@ -2446,10 +2914,10 @@ namespace Ice } } - public IceInternal.Outgoing getOutgoing(IceInternal.Reference reference, string operation, OperationMode mode, - Dictionary<string, string> context, bool compress) + public IceInternal.Outgoing getOutgoing(IceInternal.RequestHandler handler, string operation, + OperationMode mode, Dictionary<string, string> context) { - IceInternal.Outgoing outg = null; + IceInternal.Outgoing og = null; if(_cacheBuffers) { @@ -2457,71 +2925,184 @@ namespace Ice { if(_outgoingCache == null) { - outg = new IceInternal.Outgoing(this, reference, operation, mode, context, compress); + og = new IceInternal.Outgoing(handler, operation, mode, context); } else { - outg = _outgoingCache; + og = _outgoingCache; _outgoingCache = _outgoingCache.next; - outg.reset(reference, operation, mode, context, compress); - outg.next = null; + og.reset(handler, operation, mode, context); + og.next = null; } } } else { - outg = new IceInternal.Outgoing(this, reference, operation, mode, context, compress); + og = new IceInternal.Outgoing(handler, operation, mode, context); } - - return outg; + + return og; } - public void reclaimOutgoing(IceInternal.Outgoing outg) + public void reclaimOutgoing(IceInternal.Outgoing og) { if(_cacheBuffers) { // // Clear references to Ice objects as soon as possible. // - outg.reclaim(); + og.reclaim(); lock(_outgoingCacheMutex) { - outg.next = _outgoingCache; - _outgoingCache = outg; + og.next = _outgoingCache; + _outgoingCache = og; + } + } + } + + public void RunThreadPerConnection() + { + if(instance_.initializationData().threadHook != null) + { + instance_.initializationData().threadHook.start(); + } + + try + { + run(); + } + catch(Exception ex) + { + _logger.error("exception in thread per connection:\n" + ToString() + "\n" + ex.ToString()); + } + catch(System.Exception ex) + { + _logger.error("system exception in thread per connection:\n" + ToString() + "\n" + ex.ToString()); + } + finally + { + if(instance_.initializationData().threadHook != null) + { + instance_.initializationData().threadHook.stop(); + } + } + } + + private class OutgoingMessage + { + internal OutgoingMessage(IceInternal.BasicStream stream, bool compress, bool adopt) + { + this.stream = stream; + this.compress = compress; + this._adopt = adopt; + } + + internal OutgoingMessage(IceInternal.OutgoingMessageCallback @out, IceInternal.BasicStream stream, + bool compress, bool resp) + { + this.stream = stream; + this.compress = compress; + this.@out = @out; + this.response = resp; + } + + internal OutgoingMessage(IceInternal.OutgoingAsyncMessageCallback @out, IceInternal.BasicStream stream, + bool compress, bool resp) + { + this.stream = stream; + this.compress = compress; + this.outAsync = @out; + this.response = resp; + } + + internal void adopt() + { + if(_adopt) + { + IceInternal.BasicStream stream = new IceInternal.BasicStream(this.stream.instance()); + stream.swap(this.stream); + this.stream = stream; + _adopt = false; + } + } + + internal void sent(ConnectionI connection, bool notify) + { + if(@out != null) + { + @out.sent(notify); // true = notify the waiting thread that the request was sent. + } + else if(outAsync != null) + { + outAsync.sent__(connection); + } + } + + internal void finished(Ice.LocalException ex) + { + // + // Only notify oneway requests. The connection keeps track of twoway + // requests in the _requests/_asyncRequests maps and will notify them + // of the connection exceptions. + // + if(!response) + { + if(@out != null) + { + @out.finished(ex); + } + else if(outAsync != null) + { + outAsync.finished__(ex); + } } } + + internal IceInternal.BasicStream stream; + internal IceInternal.OutgoingMessageCallback @out; + internal IceInternal.OutgoingAsyncMessageCallback outAsync; + internal bool compress; + internal bool response; + internal bool _adopt; + internal bool prepared; } private Thread _thread; private bool _threadPerConnection; private IceInternal.Transceiver _transceiver; + private string _desc; private string _type; private IceInternal.EndpointI _endpoint; private ObjectAdapter _adapter; private IceInternal.ServantManager _servantManager; - + private Logger _logger; private IceInternal.TraceLevels _traceLevels; - + private bool _registeredWithPool; private int _finishedCount; private IceInternal.ThreadPool _threadPool; - + private IceInternal.SelectorThread _selectorThread; + + private StartCallback _startCallback = null; + private bool _warn; - + private int _acmTimeout; private long _acmAbsoluteTimeoutMillis; private int _compressionLevel; private int _nextRequestId; - private Hashtable _requests = new Hashtable(); - private Hashtable _asyncRequests = new Hashtable(); - + + private Dictionary<int, IceInternal.Outgoing> _requests = new Dictionary<int, IceInternal.Outgoing>(); + private Dictionary<int, IceInternal.OutgoingAsync> _asyncRequests = + new Dictionary<int, IceInternal.OutgoingAsync>(); + private LocalException _exception; private bool _batchAutoFlush; @@ -2530,17 +3111,16 @@ namespace Ice private int _batchRequestNum; private bool _batchRequestCompress; private int _batchMarker; - + + private LinkedList<OutgoingMessage> _queuedStreams = new LinkedList<OutgoingMessage>(); + private LinkedList<OutgoingMessage> _sendStreams = new LinkedList<OutgoingMessage>(); + private bool _sendInProgress; + private int _waitingForSend; + private int _dispatchCount; - + private int _state; // The current state. private long _stateTime; // The last time when the state was changed. - - // - // We have a separate mutex for sending, so that we don't block - // the whole connection when we do a blocking send. - // - private object _sendMutex = new object(); private IceInternal.Incoming _incomingCache; private object _incomingCacheMutex = new object(); diff --git a/cs/src/Ice/ConnectionMonitor.cs b/cs/src/Ice/ConnectionMonitor.cs index 7168c83902c..b53f81b3d1d 100644 --- a/cs/src/Ice/ConnectionMonitor.cs +++ b/cs/src/Ice/ConnectionMonitor.cs @@ -56,7 +56,7 @@ namespace IceInternal instance_.timer().scheduleRepeated(this, interval * 1000); } - public void run() + public void runTimerTask() { Set connections = new Set(); lock(this) diff --git a/cs/src/Ice/ConnectionRequestHandler.cs b/cs/src/Ice/ConnectionRequestHandler.cs new file mode 100755 index 00000000000..7c580a8f04d --- /dev/null +++ b/cs/src/Ice/ConnectionRequestHandler.cs @@ -0,0 +1,121 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System; +using System.Collections.Generic; + +namespace IceInternal +{ + public class ConnectionRequestHandler : RequestHandler + { + public void prepareBatchRequest(BasicStream @out) + { + _connection.prepareBatchRequest(@out); + } + + public void finishBatchRequest(BasicStream @out) + { + _connection.finishBatchRequest(@out, _compress); + } + + public void abortBatchRequest() + { + _connection.abortBatchRequest(); + } + + public Ice.ConnectionI sendRequest(Outgoing @out) + { + return (!_connection.sendRequest(@out, _compress, _response) || _response) ? _connection : null; + } + + public void sendAsyncRequest(OutgoingAsync @out) + { + try + { + _connection.sendAsyncRequest(@out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + @out.finished__(ex); + } + catch(Ice.LocalException ex) + { + @out.finished__(ex); + } + } + + public bool flushBatchRequests(BatchOutgoing @out) + { + return _connection.flushBatchRequests(@out); + } + + public void flushAsyncBatchRequests(BatchOutgoingAsync @out) + { + try + { + _connection.flushAsyncBatchRequests(@out); + } + catch(Ice.LocalException ex) + { + @out.finished__(ex); + } + } + + public Outgoing getOutgoing(string operation, Ice.OperationMode mode, Dictionary<string, string> context) + { + return _connection.getOutgoing(this, operation, mode, context); + } + + public void reclaimOutgoing(Outgoing @out) + { + _connection.reclaimOutgoing(@out); + } + + public Reference getReference() + { + return _reference; + } + + public Ice.ConnectionI getConnection(bool wait) + { + return _connection; + } + + public ConnectionRequestHandler(Reference @ref, Ice.ObjectPrx proxy) + { + _reference = @ref; + _response = _reference.getMode() == Reference.Mode.ModeTwoway; + + _connection = _reference.getConnection(out _compress); + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + IceInternal.RouterInfo ri = _reference.getRouterInfo(); + if(ri != null) + { + ri.addProxy(proxy); + } + } + + public ConnectionRequestHandler(Reference @ref, Ice.ConnectionI connection, bool compress) + { + _reference = @ref; + _response = _reference.getMode() == Reference.Mode.ModeTwoway; + _connection = connection; + _compress = compress; + } + + private Reference _reference; + private bool _response; + private Ice.ConnectionI _connection; + private bool _compress; + } +} diff --git a/cs/src/Ice/Connector.cs b/cs/src/Ice/Connector.cs index 06b93045e28..d8877c2d673 100644 --- a/cs/src/Ice/Connector.cs +++ b/cs/src/Ice/Connector.cs @@ -10,10 +10,19 @@ namespace IceInternal { + using System.Net.Sockets; + public interface Connector { + // + // Blocking connect. The caller must initialize the new + // transceiver. + // Transceiver connect(int timeout); + short type(); + + int CompareTo(object obj); } } diff --git a/cs/src/Ice/EndpointFactoryManager.cs b/cs/src/Ice/EndpointFactoryManager.cs index 4d6e04bec22..48aabdd6ee7 100644 --- a/cs/src/Ice/EndpointFactoryManager.cs +++ b/cs/src/Ice/EndpointFactoryManager.cs @@ -90,8 +90,8 @@ namespace IceInternal EndpointI e = f.create(s.Substring(m.Index + m.Length), oaEndpoint); BasicStream bs = new BasicStream(instance_, true); e.streamWrite(bs); - IceInternal.ByteBuffer buf = bs.prepareRead(); - buf.position(0); + Buffer buf = bs.getBuffer(); + buf.b.position(0); short type = bs.readShort(); EndpointI ue = new IceInternal.UnknownEndpointI(type, bs); System.Console.Error.WriteLine("Normal: " + e); @@ -120,8 +120,8 @@ namespace IceInternal // BasicStream bs = new BasicStream(instance_, true); ue.streamWrite(bs); - IceInternal.ByteBuffer buf = bs.prepareRead(); - buf.position(0); + Buffer buf = bs.getBuffer(); + buf.b.position(0); bs.readShort(); // type return f.read(bs); } diff --git a/cs/src/Ice/EndpointHostResolver.cs b/cs/src/Ice/EndpointHostResolver.cs new file mode 100644 index 00000000000..f918892d12e --- /dev/null +++ b/cs/src/Ice/EndpointHostResolver.cs @@ -0,0 +1,178 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +namespace IceInternal +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net; + using System.Threading; + + public class EndpointHostResolver + { + internal EndpointHostResolver(Instance instance) + { + _instance = instance; + + _thread = new HelperThread(this); + _thread.Start(); + } + + public void resolve(string host, int port, EndpointI endpoint, EndpointI_connectors callback) + { + // + // Try to get the addresses without DNS lookup. If this doesn't work, we queue a resolve + // entry and the thread will take care of getting the endpoint addresses. + // + List<IPEndPoint> addrs = Network.getAddresses(host, port, false); + if(addrs.Count > 0) + { + callback.connectors(endpoint.connectors(addrs)); + return; + } + + lock(this) + { + Debug.Assert(!_destroyed); + + ResolveEntry entry = new ResolveEntry(); + entry.host = host; + entry.port = port; + entry.endpoint = endpoint; + entry.callback = callback; + _queue.AddLast(entry); + Monitor.Pulse(this); + } + } + + public void destroy() + { + lock(this) + { + Debug.Assert(!_destroyed); + _destroyed = true; + Monitor.Pulse(this); + } + } + + public void joinWithThread() + { + if(_thread != null) + { + _thread.Join(); + } + } + + public void run() + { + while(true) + { + ResolveEntry resolve; + lock(this) + { + while(!_destroyed && _queue.Count == 0) + { + Monitor.Wait(this); + } + + if(_destroyed) + { + break; + } + + resolve = _queue.First.Value; + _queue.RemoveFirst(); + } + + resolve.callback.connectors(resolve.endpoint.connectors( + Network.getAddresses(resolve.host, resolve.port))); + } + + foreach(ResolveEntry entry in _queue) + { + entry.callback.exception(new Ice.CommunicatorDestroyedException()); + } + _queue.Clear(); + } + + private class ResolveEntry + { + internal string host; + internal int port; + internal EndpointI endpoint; + internal EndpointI_connectors callback; + } + + private Instance _instance; + private bool _destroyed; + private LinkedList<ResolveEntry> _queue = new LinkedList<ResolveEntry>(); + + private sealed class HelperThread + { + internal HelperThread(EndpointHostResolver resolver) + { + _resolver = resolver; + _name = _resolver._instance.initializationData().properties.getProperty("Ice.ProgramName"); + if(_name.Length > 0) + { + _name += "-"; + } + _name += "Ice.EndpointHostResolverThread"; + } + + public void Join() + { + _thread.Join(); + } + + public void Start() + { + _thread = new Thread(new ThreadStart(Run)); + _thread.IsBackground = true; + _thread.Name = _name; + _thread.Start(); + } + + public void Run() + { + if(_resolver._instance.initializationData().threadHook != null) + { + _resolver._instance.initializationData().threadHook.start(); + } + + try + { + _resolver.run(); + } + catch(Ice.LocalException ex) + { + string s = "exception in endpoint host resolver thread " + _name + ":\n" + ex; + _resolver._instance.initializationData().logger.error(s); + } + catch(System.Exception ex) + { + string s = "unknown exception in endpoint host resolver thread " + _name + ":\n" + ex; + _resolver._instance.initializationData().logger.error(s); + } + + if(_resolver._instance.initializationData().threadHook != null) + { + _resolver._instance.initializationData().threadHook.stop(); + } + } + + private EndpointHostResolver _resolver; + private string _name; + private Thread _thread; + } + + private HelperThread _thread; + } +} diff --git a/cs/src/Ice/EndpointI.cs b/cs/src/Ice/EndpointI.cs index ba4b5bfc315..08fc82ba1bd 100644 --- a/cs/src/Ice/EndpointI.cs +++ b/cs/src/Ice/EndpointI.cs @@ -10,7 +10,15 @@ namespace IceInternal { - using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net; + + public interface EndpointI_connectors + { + void connectors(List<Connector> connectors); + void exception(Ice.LocalException ex); + } public abstract class EndpointI : Ice.Endpoint, System.IComparable { @@ -91,7 +99,8 @@ namespace IceInternal // Return a connector for this endpoint, or empty list if no connector // is available. // - public abstract ArrayList connectors(); + public abstract List<Connector> connectors(); + public abstract void connectors_async(EndpointI_connectors callback); // // Return an acceptor for this endpoint, or null if no acceptors @@ -106,17 +115,23 @@ namespace IceInternal // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public abstract ArrayList expand(); + public abstract List<EndpointI> expand(); // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - public abstract bool equivalent(Connector connector); + public abstract bool equivalent(EndpointI endpoint); // // Returns true if the endpoint's transport requires thread-per-connection. // public abstract bool requiresThreadPerConnection(); + + public virtual List<Connector> connectors(List<IPEndPoint> addresses) + { + Debug.Assert(false); + return null; + } } } diff --git a/cs/src/Ice/EventHandler.cs b/cs/src/Ice/EventHandler.cs index 089d7837c46..a44082375df 100644 --- a/cs/src/Ice/EventHandler.cs +++ b/cs/src/Ice/EventHandler.cs @@ -28,7 +28,7 @@ namespace IceInternal // Read data via the event handler. May only be called if // readable() returns true. // - abstract public void read(BasicStream istr); + abstract public bool read(BasicStream istr); // // A complete message has been received. @@ -66,7 +66,8 @@ namespace IceInternal protected internal Instance instance_; // - // The stream_ data member is for use by ThreadPool only. + // The stream_ data member is only for use by the ThreadPool or by the + // connection for validation. // internal BasicStream stream_; } diff --git a/cs/src/Ice/Instance.cs b/cs/src/Ice/Instance.cs index a00a4e19d6c..12864dcc535 100644 --- a/cs/src/Ice/Instance.cs +++ b/cs/src/Ice/Instance.cs @@ -185,6 +185,42 @@ namespace IceInternal } } + public SelectorThread selectorThread() + { + lock(this) + { + if(_state == StateDestroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + if(_selectorThread == null) // Lazy initialization. + { + _selectorThread = new SelectorThread(this); + } + + return _selectorThread; + } + } + + public EndpointHostResolver endpointHostResolver() + { + lock(this) + { + if(_state == StateDestroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + if(_endpointHostResolver == null) // Lazy initialization. + { + _endpointHostResolver = new EndpointHostResolver(this); + } + + return _endpointHostResolver; + } + } + public Timer timer() { @@ -210,6 +246,12 @@ namespace IceInternal return _threadPerConnection; } + public bool background() + { + // No mutex lock, immutable. + return _background; + } + public EndpointFactoryManager endpointFactoryManager() { lock(this) @@ -611,6 +653,8 @@ namespace IceInternal _threadPerConnection = _initData.properties.getPropertyAsInt("Ice.ThreadPerConnection") > 0; + _background = _initData.properties.getPropertyAsInt("Ice.Background") > 0; + _routerManager = new RouterManager(); _locatorManager = new LocatorManager(); @@ -781,7 +825,9 @@ namespace IceInternal ThreadPool serverThreadPool = null; ThreadPool clientThreadPool = null; - + SelectorThread selectorThread = null; + EndpointHostResolver endpointHostResolver = null; + lock(this) { _objectAdapterFactory = null; @@ -800,7 +846,7 @@ namespace IceInternal serverThreadPool = _serverThreadPool; _serverThreadPool = null; } - + if(_clientThreadPool != null) { _clientThreadPool.destroy(); @@ -808,6 +854,20 @@ namespace IceInternal _clientThreadPool = null; } + if(_selectorThread != null) + { + _selectorThread.destroy(); + selectorThread = _selectorThread; + _selectorThread = null; + } + + if(_endpointHostResolver != null) + { + _endpointHostResolver.destroy(); + endpointHostResolver = _endpointHostResolver; + _endpointHostResolver = null; + } + if(_timer != null) { _timer.destroy(); @@ -861,8 +921,7 @@ namespace IceInternal } // - // Join with the thread pool threads outside the - // synchronization. + // Join with threads outside the synchronization. // if(clientThreadPool != null) { @@ -872,6 +931,14 @@ namespace IceInternal { serverThreadPool.joinWithAllThreads(); } + if(selectorThread != null) + { + selectorThread.joinWithThread(); + } + if(endpointHostResolver != null) + { + endpointHostResolver.joinWithThread(); + } if(_initData.properties.getPropertyAsInt("Ice.Warn.UnusedProperties") > 0) { @@ -911,8 +978,11 @@ namespace IceInternal private ObjectAdapterFactory _objectAdapterFactory; private ThreadPool _clientThreadPool; private ThreadPool _serverThreadPool; + private SelectorThread _selectorThread; + private EndpointHostResolver _endpointHostResolver; private Timer _timer; private bool _threadPerConnection; + private bool _background; private EndpointFactoryManager _endpointFactoryManager; private Ice.PluginManager _pluginManager; private Dictionary<string, string> _defaultContext; @@ -926,7 +996,6 @@ namespace IceInternal private static bool _oneOffDone = false; private static System.Object _staticLock = new System.Object(); - } } diff --git a/cs/src/Ice/LinkedList.cs b/cs/src/Ice/LinkedList.cs index 5304109d6b7..4aa03626d9a 100644 --- a/cs/src/Ice/LinkedList.cs +++ b/cs/src/Ice/LinkedList.cs @@ -22,6 +22,20 @@ namespace IceUtil _count = 0; } + public LinkedList(LinkedList l) + { + _head = null; + _tail = null; + _count = 0; + + Node cursor = l._head; + while(cursor != null) + { + Add(cursor.val); + cursor = cursor.next; + } + } + public int Count { get @@ -142,7 +156,22 @@ namespace IceUtil _count++; } - private void Remove(Node n) + public bool Remove(object value) + { + Node n = _head; + while(n != null) + { + if(n.val == value) + { + RemoveNode(n); + return true; + } + n = n.next; + } + return false; + } + + private void RemoveNode(Node n) { Debug.Assert(n != null); Debug.Assert(_count != 0); @@ -257,7 +286,7 @@ namespace IceUtil _removed = true; _moveNext = _current.next; // Remember where to move next for call to MoveNext(). _movePrev = _current.prev; // Remember where to move next for call to MovePrev(). - _list.Remove(_current); + _list.RemoveNode(_current); _current = null; } @@ -269,4 +298,3 @@ namespace IceUtil } } } - diff --git a/cs/src/Ice/LocatorInfo.cs b/cs/src/Ice/LocatorInfo.cs index 2a836790905..968aa30de9b 100644 --- a/cs/src/Ice/LocatorInfo.cs +++ b/cs/src/Ice/LocatorInfo.cs @@ -15,6 +15,12 @@ namespace IceInternal public sealed class LocatorInfo { + public interface GetEndpointsCallback + { + void setEndpoints(EndpointI[] endpoints, bool cached); + void setException(Ice.LocalException ex); + } + internal LocatorInfo(Ice.LocatorPrx locator, LocatorTable table) { _locator = locator; @@ -74,8 +80,6 @@ namespace IceInternal public EndpointI[] getEndpoints(IndirectReference @ref, int ttl, out bool cached) { - Debug.Assert(@ref.getEndpoints().Length == 0); - EndpointI[] endpoints = null; Ice.ObjectPrx obj = null; cached = true; @@ -142,8 +146,8 @@ namespace IceInternal Reference r = ((Ice.ObjectPrxHelperBase)obj).reference__(); if(r is DirectReference) { - DirectReference odr = (DirectReference)r; endpointsCached = false; + DirectReference odr = (DirectReference)r; endpoints = odr.getEndpoints(); } else @@ -164,100 +168,153 @@ namespace IceInternal cached = objectCached || endpointsCached; } } - catch(Ice.AdapterNotFoundException ex) + catch(System.Exception ex) { - if(@ref.getInstance().traceLevels().location >= 1) - { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("adapter not found\n"); - s.Append("adapter = " + adapterId); - @ref.getInstance().initializationData().logger.trace( - @ref.getInstance().traceLevels().locationCat, s.ToString()); - } + getEndpointsException(@ref, ex); + } - Ice.NotRegisteredException e = new Ice.NotRegisteredException(ex); - e.kindOfObject = "object adapter"; - e.id = adapterId; - throw e; + if(@ref.getInstance().traceLevels().location >= 1) + { + getEndpointsTrace(@ref, endpoints, cached); + } + + return endpoints == null ? new EndpointI[0] : endpoints; + } + + private class AdapterCallback : Ice.AMI_Locator_findAdapterById + { + internal AdapterCallback(LocatorInfo info, IndirectReference @ref, GetEndpointsCallback callback) + { + _info = info; + _ref = @ref; + _callback = callback; } - catch(Ice.ObjectNotFoundException ex) + + public override void ice_response(Ice.ObjectPrx obj) { - if(@ref.getInstance().traceLevels().location >= 1) + EndpointI[] endpoints = null; + if(obj != null) { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("object not found\n"); - s.Append("object = " + @ref.getInstance().identityToString(identity)); - @ref.getInstance().initializationData().logger.trace( - @ref.getInstance().traceLevels().locationCat, s.ToString()); + endpoints = ((Ice.ObjectPrxHelperBase)obj).reference__().getEndpoints(); + if(endpoints.Length > 0) + { + _info._table.addAdapterEndpoints(_ref.getAdapterId(), endpoints); + } } - Ice.NotRegisteredException e = new Ice.NotRegisteredException(ex); - e.kindOfObject = "object"; - e.id = @ref.getInstance().identityToString(identity); - throw e; + if(_ref.getInstance().traceLevels().location >= 1) + { + _info.getEndpointsTrace(_ref, endpoints, false); + } + + if(endpoints == null) + { + _callback.setEndpoints(new EndpointI[0], false); + } + else + { + _callback.setEndpoints(endpoints, false); + } } - catch(Ice.NotRegisteredException) + + public override void ice_exception(Ice.Exception ex) { - throw; + _info.getEndpointsException(_ref, ex, _callback); } - catch(Ice.LocalException ex) + + private LocatorInfo _info; + private IndirectReference _ref; + private GetEndpointsCallback _callback; + } + + private class ObjectCallback : Ice.AMI_Locator_findObjectById + { + internal ObjectCallback(LocatorInfo info, IndirectReference @ref, int ttl, GetEndpointsCallback callback) + { + _info = info; + _ref = @ref; + _ttl = ttl; + _callback = callback; + } + + public override void ice_response(Ice.ObjectPrx obj) + { + _info.getWellKnownObjectEndpoints(_ref, obj, _ttl, false, _callback); + } + + public override void ice_exception(Ice.Exception ex) { - if(@ref.getInstance().traceLevels().location >= 1) + _info.getEndpointsException(_ref, ex, _callback); + } + + private LocatorInfo _info; + private IndirectReference _ref; + private int _ttl; + private GetEndpointsCallback _callback; + } + + public void getEndpoints(IndirectReference @ref, int ttl, GetEndpointsCallback callback) + { + string adapterId = @ref.getAdapterId(); + Ice.Identity identity = @ref.getIdentity(); + Instance instance = @ref.getInstance(); + if(adapterId.Length > 0) + { + EndpointI[] endpoints = _table.getAdapterEndpoints(adapterId, ttl); + if(endpoints == null) { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("couldn't contact the locator to retrieve adapter endpoints\n"); - if(adapterId.Length > 0) + if(instance.traceLevels().location >= 1) { - s.Append("adapter = " + adapterId + "\n"); + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("searching for adapter by id\n"); + s.Append("adapter = " + adapterId); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); } - else + + // + // Search the adapter in the location service if we didn't + // find it in the cache. + // + _locator.findAdapterById_async(new AdapterCallback(this, @ref, callback), adapterId); + return; + } + else + { + if(instance.traceLevels().location >= 1) { - s.Append("object = " + @ref.getInstance().identityToString(identity) + "\n"); + getEndpointsTrace(@ref, endpoints, true); } - s.Append("reason = " + ex); - @ref.getInstance().initializationData().logger.trace( - @ref.getInstance().traceLevels().locationCat, s.ToString()); + callback.setEndpoints(endpoints, true); + return; } } - - if(@ref.getInstance().traceLevels().location >= 1) + else { - if(endpoints != null && endpoints.Length > 0) + Ice.ObjectPrx obj = _table.getProxy(identity, ttl); + if(obj == null) { - if(cached) - { - trace("found endpoints in locator table", @ref, endpoints); - } - else + if(instance.traceLevels().location >= 1) { - trace("retrieved endpoints from locator, adding to locator table", @ref, endpoints); + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("searching for object by id\n"); + s.Append("object = " + instance.identityToString(identity)); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); } + + _locator.findObjectById_async(new ObjectCallback(this, @ref, ttl, callback), identity); + return; } else { - System.Text.StringBuilder s = new System.Text.StringBuilder(); - s.Append("no endpoints configured for "); - if(adapterId.Length > 0) - { - s.Append("adapter\n"); - s.Append("adapter = " + adapterId); - } - else - { - s.Append("object\n"); - s.Append("object = " + @ref.getInstance().identityToString(identity)); - } - @ref.getInstance().initializationData().logger.trace( - @ref.getInstance().traceLevels().locationCat, s.ToString()); + getWellKnownObjectEndpoints(@ref, obj, ttl, true, callback); + return; } } - - return endpoints == null ? new EndpointI[0] : endpoints; } - + public void clearObjectCache(IndirectReference rf) { - if(rf.getAdapterId().Length == 0 && rf.getEndpoints().Length == 0) + if(rf.getAdapterId().Length == 0) { Ice.ObjectPrx obj = _table.removeProxy(rf.getIdentity()); if(obj != null) @@ -344,7 +401,206 @@ namespace IceInternal r.getInstance().initializationData().logger.trace(r.getInstance().traceLevels().locationCat, s.ToString()); } - + + private void getEndpointsException(IndirectReference @ref, System.Exception exc) + { + try + { + throw exc; + } + catch(Ice.AdapterNotFoundException ex) + { + Instance instance = @ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("adapter not found\n"); + s.Append("adapter = " + @ref.getAdapterId()); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); + } + + Ice.NotRegisteredException e = new Ice.NotRegisteredException(ex); + e.kindOfObject = "object adapter"; + e.id = @ref.getAdapterId(); + throw e; + } + catch(Ice.ObjectNotFoundException ex) + { + Instance instance = @ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("object not found\n"); + s.Append("object = " + instance.identityToString(@ref.getIdentity())); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); + } + + Ice.NotRegisteredException e = new Ice.NotRegisteredException(ex); + e.kindOfObject = "object"; + e.id = instance.identityToString(@ref.getIdentity()); + throw e; + } + catch(Ice.NotRegisteredException) + { + throw; + } + catch(Ice.LocalException ex) + { + Instance instance = @ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("couldn't contact the locator to retrieve adapter endpoints\n"); + if(@ref.getAdapterId().Length > 0) + { + s.Append("adapter = " + @ref.getAdapterId() + "\n"); + } + else + { + s.Append("object = " + instance.identityToString(@ref.getIdentity()) + "\n"); + } + s.Append("reason = " + ex); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); + } + throw; + } + catch(System.Exception) + { + Debug.Assert(false); + } + } + + private void getEndpointsException(IndirectReference @ref, System.Exception exc, GetEndpointsCallback callback) + { + try + { + getEndpointsException(@ref, exc); + } + catch(Ice.LocalException ex) + { + callback.setException(ex); + } + catch(System.Exception) + { + Debug.Assert(false); + } + } + + private class GetWellKnownObjectEndpointsCallback : GetEndpointsCallback + { + internal GetWellKnownObjectEndpointsCallback(LocatorInfo info, IndirectReference @ref, Ice.ObjectPrx obj, + bool objectCached, GetEndpointsCallback callback) + { + _info = info; + _ref = @ref; + _obj = obj; + _objectCached = objectCached; + _callback = callback; + } + + public void setEndpoints(EndpointI[] endpoints, bool endpointsCached) + { + if(!_objectCached && endpoints != null && endpoints.Length > 0) + { + _info._table.addProxy(_ref.getIdentity(), _obj); + } + + if(_ref.getInstance().traceLevels().location >= 1) + { + _info.getEndpointsTrace(_ref, endpoints, _objectCached || endpointsCached); + } + + _callback.setEndpoints(endpoints, _objectCached || endpointsCached); + } + + public void setException(Ice.LocalException ex) + { + _callback.setException(ex); + } + + private LocatorInfo _info; + private IndirectReference _ref; + private Ice.ObjectPrx _obj; + private bool _objectCached; + private GetEndpointsCallback _callback; + } + + private void getWellKnownObjectEndpoints(IndirectReference @ref, Ice.ObjectPrx obj, int ttl, + bool objectCached, GetEndpointsCallback callback) + { + EndpointI[] endpoints = null; + if(obj != null) + { + Reference r = ((Ice.ObjectPrxHelperBase)obj).reference__(); + if(r is DirectReference) + { + DirectReference odr = (DirectReference)r; + endpoints = odr.getEndpoints(); + } + else + { + IndirectReference oir = (IndirectReference)r; + if(oir.getAdapterId().Length > 0) + { + getEndpoints(oir, ttl, + new GetWellKnownObjectEndpointsCallback(this, @ref, obj, objectCached, callback)); + return; + } + } + } + + if(!objectCached && endpoints != null && endpoints.Length > 0) + { + _table.addProxy(@ref.getIdentity(), obj); + } + + if(@ref.getInstance().traceLevels().location >= 1) + { + getEndpointsTrace(@ref, endpoints, objectCached); + } + + if(endpoints == null) + { + callback.setEndpoints(new EndpointI[0], false); + } + else + { + callback.setEndpoints(endpoints, objectCached); + } + } + + private void getEndpointsTrace(IndirectReference @ref, EndpointI[] endpoints, bool cached) + { + if(endpoints != null && endpoints.Length > 0) + { + if(cached) + { + trace("found endpoints in locator table", @ref, endpoints); + } + else + { + trace("retrieved endpoints from locator, adding to locator table", @ref, endpoints); + } + } + else + { + Instance instance = @ref.getInstance(); + System.Text.StringBuilder s = new System.Text.StringBuilder(); + s.Append("no endpoints configured for "); + if(@ref.getAdapterId().Length > 0) + { + s.Append("adapter\n"); + s.Append("adapter = " + @ref.getAdapterId()); + } + else + { + s.Append("object\n"); + s.Append("object = " + instance.identityToString(@ref.getIdentity())); + } + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.ToString()); + } + } + private readonly Ice.LocatorPrx _locator; private Ice.LocatorRegistryPrx _locatorRegistry; private readonly LocatorTable _table; @@ -386,7 +642,7 @@ namespace IceInternal // The locator can't be located. // Ice.LocatorPrx locator = Ice.LocatorPrxHelper.uncheckedCast(loc.ice_locator(null)); - + // // TODO: reap unused locator info objects? // diff --git a/cs/src/Ice/Makefile b/cs/src/Ice/Makefile index 0f1213c4742..59de8ba8f02 100644 --- a/cs/src/Ice/Makefile +++ b/cs/src/Ice/Makefile @@ -20,11 +20,14 @@ SRCS = Acceptor.cs \ AssemblyUtil.cs \ Base64.cs \ BasicStream.cs \ + Buffer.cs \ ByteBuffer.cs \ CommunicatorI.cs \ Compare.cs \ CollectionBase.cs \ + ConnectRequestHandler.cs \ ConnectionI.cs \ + ConnectionRequestHandler.cs \ ConnectionFactory.cs \ ConnectionMonitor.cs \ Connector.cs \ @@ -35,6 +38,7 @@ SRCS = Acceptor.cs \ EndpointI.cs \ EndpointFactory.cs \ EndpointFactoryManager.cs \ + EndpointHostResolver.cs \ EventHandler.cs \ Exception.cs \ ImplicitContextI.cs \ @@ -69,7 +73,9 @@ SRCS = Acceptor.cs \ Reference.cs \ ReferenceFactory.cs \ ReplyStatus.cs \ + RequestHandler.cs \ RouterInfo.cs \ + SelectorThread.cs \ ServantManager.cs \ Set.cs \ SliceChecksums.cs \ diff --git a/cs/src/Ice/Makefile.mak b/cs/src/Ice/Makefile.mak index b0cdf8862db..6d5a5beb4f1 100644 --- a/cs/src/Ice/Makefile.mak +++ b/cs/src/Ice/Makefile.mak @@ -20,11 +20,14 @@ SRCS = Acceptor.cs \ AssemblyUtil.cs \ Base64.cs \ BasicStream.cs \ + Buffer.cs \ ByteBuffer.cs \ CommunicatorI.cs \ Compare.cs \ CollectionBase.cs \ + ConnectRequestHandler.cs \ ConnectionI.cs \ + ConnectionRequestHandler.cs \ ConnectionFactory.cs \ ConnectionMonitor.cs \ Connector.cs \ @@ -35,6 +38,7 @@ SRCS = Acceptor.cs \ EndpointI.cs \ EndpointFactory.cs \ EndpointFactoryManager.cs \ + EndpointHostResolver.cs \ EventHandler.cs \ Exception.cs \ ImplicitContextI.cs \ @@ -69,7 +73,9 @@ SRCS = Acceptor.cs \ Reference.cs \ ReferenceFactory.cs \ ReplyStatus.cs \ + RequestHandler.cs \ RouterInfo.cs \ + SelectorThread.cs \ ServantManager.cs \ Set.cs \ SliceChecksums.cs \ diff --git a/cs/src/Ice/Network.cs b/cs/src/Ice/Network.cs index f77ba0d831b..6103eaee679 100644 --- a/cs/src/Ice/Network.cs +++ b/cs/src/Ice/Network.cs @@ -12,6 +12,7 @@ namespace IceInternal using System; using System.Collections; + using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Net; @@ -391,33 +392,13 @@ namespace IceInternal throw new Ice.SocketException(ex); } } - - public static void doConnect(Socket socket, EndPoint addr, int timeout) - { - // - // MONO workaround for - // http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1647. - // - // It would have been nice to be able to get rid of the 2 - // implementations of doConnect() and only use - // doConnectAsync() however, with .NET doConnectAsync() - // doesn't work with the TCP transport. In particular, - // the test/Ice/timeout test fails in the connect timeout - // test because the client hangs in the Receive() call - // waiting for the connection validation (for some reasons - // Receive blocks even though the socket is - // non-blocking...) - // - if(AssemblyUtil.runtime_ == AssemblyUtil.Runtime.Mono) - { - doConnectAsync(socket, addr, timeout); - return; - } + public static bool doConnect(Socket fd, EndPoint addr, int timeout) + { repeatConnect: try { - socket.Connect(addr); + fd.Connect(addr); } catch(SocketException ex) { @@ -428,51 +409,73 @@ namespace IceInternal if(!connectInProgress(ex)) { - closeSocketNoThrow(socket); - // - // Check for connectionRefused, and connectFailed - // here. - // + closeSocketNoThrow(fd); + if(connectionRefused(ex)) { throw new Ice.ConnectionRefusedException(ex); } - else if(connectFailed(ex)) - { - throw new Ice.ConnectFailedException(ex); - } else { - throw new Ice.SocketException(ex); + throw new Ice.ConnectFailedException(ex); } } + } + + if(!fd.Connected) + { + if(timeout == 0) + { + return false; + } - repeatSelect: - bool ready; - bool error; try { - ArrayList writeList = new ArrayList(); - writeList.Add(socket); - ArrayList errorList = new ArrayList(); - errorList.Add(socket); - doSelect(null, writeList, errorList, timeout); - ready = writeList.Count != 0; - error = errorList.Count != 0; + doFinishConnect(fd, timeout); + } + catch(Ice.LocalException) + { + closeSocketNoThrow(fd); + throw; + } + } + if(addr.Equals(fd.LocalEndPoint)) + { + closeSocketNoThrow(fd); + throw new Ice.ConnectionRefusedException(); + } + return true; + } + + public static void doFinishConnect(Socket fd, int timeout) + { + // + // Note: we don't close the socket if there's an exception. It's the responsibility + // of the caller to do so. + // + + if(timeout != 0) + { + Selector selector = new Selector(); + selector.add(fd, SocketStatus.NeedConnect); + selector.select(timeout); + + bool ready = selector.selWrite.Count != 0; + bool error = selector.selError.Count != 0; + + try + { // // As with C++ we need to get the SO_ERROR error // to determine whether the connect has actually // failed. // - int val = (int)socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); + int val = (int)fd.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Error); if(val > 0) { - closeSocketNoThrow(socket); - // - // Create a Win32Exception out of this error value. Check the for refused, and - // failed. Otherwise its a plain old socket exception. + // Create a Win32Exception out of this error value. // Win32Exception sockEx = new Win32Exception(val); if(connectionRefused(sockEx)) @@ -488,24 +491,16 @@ namespace IceInternal throw new Ice.SocketException(sockEx); } } - - Debug.Assert(!(ready && error)); } catch(SocketException e) { - if(interrupted(e)) - { - goto repeatSelect; - } - - closeSocketNoThrow(socket); throw new Ice.SocketException(e); } + Debug.Assert(!(ready && error)); + if(error || !ready) { - closeSocketNoThrow(socket); - // // If GetSocketOption didn't return an error and we've failed then we cannot // distinguish between connect failed and connection refused. @@ -520,90 +515,23 @@ namespace IceInternal } } } - } - - internal class AsyncConnectInfo - { - internal AsyncConnectInfo(Socket fd) - { - this.fd = fd; - this.ex = null; - this.done = false; - } - - internal Socket fd; - volatile internal Exception ex; - volatile internal bool done; - } - - private static void asyncConnectCallback(IAsyncResult ar) - { - AsyncConnectInfo info = (AsyncConnectInfo)ar.AsyncState; - lock(info) - { - try - { - info.fd.EndConnect(ar); - } - catch(Exception ex) - { - info.ex = ex; - } - finally - { - info.done = true; - Monitor.Pulse(info); - } - } - } - public static void doConnectAsync(Socket socket, EndPoint addr, int timeout) - { - repeatConnect: + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // try { - AsyncConnectInfo info = new AsyncConnectInfo(socket); - /* IAsyncResult ar = */ socket.BeginConnect(addr, new AsyncCallback(asyncConnectCallback), info); - lock(info) + EndPoint addr = fd.RemoteEndPoint; + if(addr != null && addr.Equals(fd.LocalEndPoint)) { - if(!info.done) - { - if(!Monitor.Wait(info, timeout == -1 ? Timeout.Infinite : timeout)) - { - throw new Ice.ConnectTimeoutException(); - } - } - if(info.ex != null) - { - throw info.ex; - } + throw new Ice.ConnectionRefusedException(); } } - catch(SocketException ex) + catch(SocketException) { - if(interrupted(ex)) - { - goto repeatConnect; - } - - closeSocketNoThrow(socket); - - // - // Check for connectionRefused, and connectFailed - // here. - // - if(connectionRefused(ex)) - { - throw new Ice.ConnectionRefusedException(ex); - } - else if(connectFailed(ex)) - { - throw new Ice.ConnectFailedException(ex); - } - else - { - throw new Ice.SocketException(ex); - } + // Ignore - the socket may not be connected. } } @@ -624,27 +552,7 @@ namespace IceInternal } if(wouldBlock(ex)) { - repeatSelect: - ArrayList readList = new ArrayList(); - readList.Add(socket); - try - { - doSelect(readList, null, null, timeout); - } - catch(Win32Exception we) - { - if(interrupted(we)) - { - goto repeatSelect; - } - throw new Ice.SocketException(we); - } - catch(System.Exception se) - { - throw new Ice.SocketException(se); - } - - if(readList.Count == 0) + if(!doPoll(socket, timeout, PollMode.Read)) { throw new Ice.TimeoutException(); } @@ -688,13 +596,38 @@ namespace IceInternal // while((timeout > System.Int32.MaxValue / 1000)) { - if(s.Poll((System.Int32.MaxValue / 1000) * 1000, (SelectMode)mode)) + try + { + if(s.Poll((System.Int32.MaxValue / 1000) * 1000, (SelectMode)mode)) + { + return true; + } + } + catch(SocketException ex) { - return true; + if(interrupted(ex)) + { + continue; + } + throw new Ice.SocketException(ex); } timeout -= System.Int32.MaxValue / 1000; } - return s.Poll(timeout * 1000, (SelectMode)mode); + while(true) + { + try + { + return s.Poll(timeout * 1000, (SelectMode)mode); + } + catch(SocketException ex) + { + if(interrupted(ex)) + { + continue; + } + throw new Ice.SocketException(ex); + } + } } public static void doSelect(IList checkRead, IList checkWrite, IList checkError, int milliSeconds) @@ -710,6 +643,9 @@ namespace IceInternal // of blocking indefinitely), so we have to emulate a blocking select here. // (Using Int32.MaxValue isn't good enough because that's only about 35 minutes.) // + // According to the .NET 2.0 API docs, Select() should block when given a timeout + // value of -1, but that doesn't appear to be the case, at least not on Windows. + // do { cr = copyList(checkRead); cw = copyList(checkWrite); @@ -722,7 +658,7 @@ namespace IceInternal { if(interrupted(e)) { - continue; + continue; } throw new Ice.SocketException(e); } @@ -730,9 +666,6 @@ namespace IceInternal while((cr == null || cr.Count == 0) && (cw == null || cw.Count == 0) && (ce == null || ce.Count == 0)); - overwriteList(cr, checkRead); - overwriteList(cw, checkWrite); - overwriteList(ce, checkError); } else { @@ -740,9 +673,7 @@ namespace IceInternal // Select() wants microseconds, so we need to deal with overflow. // while((milliSeconds > System.Int32.MaxValue / 1000) && - ((cr == null) || cr.Count == 0) && - ((cw == null) || cw.Count == 0) && - ((ce == null) || ce.Count == 0)) + (cr == null || cr.Count == 0) && (cw == null || cw.Count == 0) && (ce == null || ce.Count == 0)) { cr = copyList(checkRead); cw = copyList(checkWrite); @@ -761,14 +692,32 @@ namespace IceInternal } milliSeconds -= System.Int32.MaxValue / 1000; } - if(cr == null && cw == null && ce == null) + if((cr == null || cr.Count == 0) && (cw == null || cw.Count == 0) && (ce == null || ce.Count == 0)) { - Socket.Select(checkRead, checkWrite, checkError, milliSeconds * 1000); + while(true) + { + cr = copyList(checkRead); + cw = copyList(checkWrite); + ce = copyList(checkError); + try + { + Socket.Select(cr, cw, ce, milliSeconds * 1000); + break; + } + catch(SocketException e) + { + if(interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + } } - overwriteList(cr, checkRead); - overwriteList(cw, checkWrite); - overwriteList(ce, checkError); } + overwriteList(cr, checkRead); + overwriteList(cw, checkWrite); + overwriteList(ce, checkError); } public static IPEndPoint getAddress(string host, int port) @@ -889,9 +838,14 @@ namespace IceInternal throw dns; } - public static IPEndPoint[] getAddresses(string host, int port) + public static List<IPEndPoint> getAddresses(string host, int port) + { + return getAddresses(host, port, true); + } + + public static List<IPEndPoint> getAddresses(string host, int port, bool blocking) { - ArrayList addresses = new ArrayList(); + List<IPEndPoint> addresses = new List<IPEndPoint>(); if(host.Equals("0.0.0.0")) { @@ -915,8 +869,13 @@ namespace IceInternal { addresses.Add(new IPEndPoint(IPAddress.Parse(host), port)); } - catch (FormatException) + catch(FormatException) { + if(!blocking) + { + return addresses; + } + IPHostEntry e = Dns.GetHostEntry(host); for(int i = 0; i < e.AddressList.Length; ++i) { @@ -945,7 +904,7 @@ namespace IceInternal } } - return (IPEndPoint[])addresses.ToArray(typeof(IPEndPoint)); + return addresses; } public static string[] getLocalHosts() @@ -1219,4 +1178,156 @@ namespace IceInternal return remoteEndpoint; } } + + public enum SocketStatus { Finished, NeedConnect, NeedRead, NeedWrite }; + + public sealed class Selector + { + public void add(Socket fd, SocketStatus status) + { + switch(status) + { + case SocketStatus.Finished: + Debug.Assert(false); + break; + case SocketStatus.NeedConnect: + _writeList.Add(fd, null); + if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) + { + _errorList.Add(fd, null); + } + break; + case SocketStatus.NeedRead: + _readList.Add(fd, null); + break; + case SocketStatus.NeedWrite: + _writeList.Add(fd, null); + break; + } + } + + public void remove(Socket fd, SocketStatus status) + { + switch(status) + { + case SocketStatus.Finished: + Debug.Assert(false); + break; + case SocketStatus.NeedConnect: + _writeList.Remove(fd); + if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) + { + _errorList.Remove(fd); + } + break; + case SocketStatus.NeedRead: + _readList.Remove(fd); + break; + case SocketStatus.NeedWrite: + _writeList.Remove(fd); + break; + } + } + + public int select(int timeout) + { + List<Socket> cr = null; + List<Socket> cw = null; + List<Socket> ce = null; + + if(timeout < 0) + { + // + // Socket.Select() returns immediately if the timeout is < 0 (instead + // of blocking indefinitely), so we have to emulate a blocking select here. + // (Using Int32.MaxValue isn't good enough because that's only about 35 minutes.) + // + // According to the .NET 2.0 API docs, Select() should block when given a timeout + // value of -1, but that doesn't appear to be the case, at least not on Windows. + // + do { + cr = new List<Socket>(_readList.Keys); + cw = new List<Socket>(_writeList.Keys); + ce = new List<Socket>(_errorList.Keys); + try + { + Socket.Select(cr, cw, ce, System.Int32.MaxValue); + } + catch(SocketException e) + { + if(Network.interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + } + while((cr == null || cr.Count == 0) && + (cw == null || cw.Count == 0) && + (ce == null || ce.Count == 0)); + } + else + { + // + // Select() wants microseconds, so we need to deal with overflow. + // + while((timeout > System.Int32.MaxValue / 1000) && + (cr == null || cr.Count == 0) && (cw == null || cw.Count == 0) && (ce == null || ce.Count == 0)) + { + cr = new List<Socket>(_readList.Keys); + cw = new List<Socket>(_writeList.Keys); + ce = new List<Socket>(_errorList.Keys); + try + { + Socket.Select(cr, cw, ce, (System.Int32.MaxValue / 1000) * 1000); + } + catch(SocketException e) + { + if(Network.interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + timeout -= System.Int32.MaxValue / 1000; + } + if((cr == null || cr.Count == 0) && (cw == null || cw.Count == 0) && (ce == null || ce.Count == 0)) + { + while(true) + { + cr = new List<Socket>(_readList.Keys); + cw = new List<Socket>(_writeList.Keys); + ce = new List<Socket>(_errorList.Keys); + try + { + Socket.Select(cr, cw, ce, timeout * 1000); + break; + } + catch(SocketException e) + { + if(Network.interrupted(e)) + { + continue; + } + throw new Ice.SocketException(e); + } + } + } + } + + selRead = cr; + selWrite = cw; + selError = ce; + + return selRead.Count + selWrite.Count + selError.Count; + } + + public List<Socket> selRead; // Sockets selected for read + public List<Socket> selWrite; // Sockets selected for write + public List<Socket> selError; // Sockets selected for error + + private Dictionary<Socket, object> _readList = new Dictionary<Socket, object>(); + private Dictionary<Socket, object> _writeList = new Dictionary<Socket, object>(); + private Dictionary<Socket, object> _errorList = new Dictionary<Socket, object>(); + } } diff --git a/cs/src/Ice/ObjectAdapterI.cs b/cs/src/Ice/ObjectAdapterI.cs index 8421d84c733..41b03e99437 100644 --- a/cs/src/Ice/ObjectAdapterI.cs +++ b/cs/src/Ice/ObjectAdapterI.cs @@ -130,8 +130,7 @@ namespace Ice int sz = _incomingConnectionFactories.Count; for(int i = 0; i < sz; ++i) { - IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories[i]; + IceInternal.IncomingConnectionFactory factory = _incomingConnectionFactories[i]; factory.hold(); } } @@ -146,8 +145,7 @@ namespace Ice int sz = _incomingConnectionFactories.Count; for(int i = 0; i < sz; ++i) { - IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories[i]; + IceInternal.IncomingConnectionFactory factory = _incomingConnectionFactories[i]; factory.waitUntilHolding(); } } @@ -156,7 +154,7 @@ namespace Ice public void deactivate() { IceInternal.OutgoingConnectionFactory outgoingConnectionFactory; - ArrayList incomingConnectionFactories; + List<IceInternal.IncomingConnectionFactory> incomingConnectionFactories; IceInternal.LocatorInfo locatorInfo; lock(this) @@ -193,7 +191,8 @@ namespace Ice _routerInfo.setAdapter(null); } - incomingConnectionFactories = new ArrayList(_incomingConnectionFactories); + incomingConnectionFactories = + new List<IceInternal.IncomingConnectionFactory>(_incomingConnectionFactories); outgoingConnectionFactory = instance_.outgoingConnectionFactory(); locatorInfo = _locatorInfo; @@ -222,8 +221,7 @@ namespace Ice int sz = incomingConnectionFactories.Count; for(int i = 0; i < sz; ++i) { - IceInternal.IncomingConnectionFactory factory = - (IceInternal.IncomingConnectionFactory)incomingConnectionFactories[i]; + IceInternal.IncomingConnectionFactory factory = incomingConnectionFactories[i]; factory.destroy(); } @@ -255,9 +253,7 @@ namespace Ice System.Threading.Monitor.Wait(this); } - incomingConnectionFactories = - (IceInternal.IncomingConnectionFactory[])_incomingConnectionFactories.ToArray( - typeof(IceInternal.IncomingConnectionFactory)); + incomingConnectionFactories = _incomingConnectionFactories.ToArray(); } // @@ -353,7 +349,6 @@ namespace Ice _routerInfo = null; _publishedEndpoints = null; _locatorInfo = null; - _connectors = null; objectAdapterFactory = _objectAdapterFactory; _objectAdapterFactory = null; @@ -533,16 +528,15 @@ namespace Ice // // Get all incoming connections for this object adapter. // - ArrayList connections = new ArrayList(); + List<ConnectionI> connections = new List<ConnectionI>(); int sz = _incomingConnectionFactories.Count; for(int i = 0; i < sz; ++i) { - IceInternal.IncomingConnectionFactory factory - = (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories[i]; - ConnectionI[] cons = factory.connections(); - for(int j = 0; j < cons.Length; j++) + IceInternal.IncomingConnectionFactory factory = _incomingConnectionFactories[i]; + IceUtil.LinkedList l = factory.connections(); + foreach(ConnectionI conn in l) { - connections.Add(cons[j]); + connections.Add(conn); } } @@ -550,14 +544,9 @@ namespace Ice // Create a reference and return a reverse proxy for this // reference. // - ConnectionI[] arr = new ConnectionI[connections.Count]; - if(arr.Length != 0) - { - connections.CopyTo(arr, 0); - } + ConnectionI[] arr = connections.ToArray(); IceInternal.Reference @ref = instance_.referenceFactory().create( - ident, instance_.getDefaultContext(), "", IceInternal.Reference.Mode.ModeTwoway, - arr); + ident, instance_.getDefaultContext(), "", IceInternal.Reference.Mode.ModeTwoway, arr); return instance_.proxyFactory().referenceToProxy(@ref); } } @@ -576,7 +565,7 @@ namespace Ice { IceInternal.LocatorInfo locatorInfo = null; bool registerProcess = false; - ArrayList oldPublishedEndpoints; + List<IceInternal.EndpointI> oldPublishedEndpoints; lock(this) { @@ -585,12 +574,6 @@ namespace Ice oldPublishedEndpoints = _publishedEndpoints; _publishedEndpoints = parsePublishedEndpoints(); - _connectors.Clear(); - foreach(IceInternal.IncomingConnectionFactory factory in _incomingConnectionFactories) - { - _connectors.AddRange(factory.endpoint().connectors()); - } - locatorInfo = _locatorInfo; if(!_noConfig) { @@ -668,11 +651,16 @@ namespace Ice // for(int i = 0; i < endpoints.Length; ++i) { - int sz = _connectors.Count; - for(int j = 0; j < sz; j++) + foreach(IceInternal.EndpointI endpoint in _publishedEndpoints) + { + if(endpoints[i].equivalent(endpoint)) + { + return true; + } + } + foreach(IceInternal.IncomingConnectionFactory factory in _incomingConnectionFactories) { - IceInternal.Connector connector = (IceInternal.Connector)_connectors[j]; - if(endpoints[i].equivalent(connector)) + if(endpoints[i].equivalent(factory.endpoint())) { return true; } @@ -701,10 +689,10 @@ namespace Ice public void flushBatchRequests() { - ArrayList f; + List<IceInternal.IncomingConnectionFactory> f; lock(this) { - f = new ArrayList(_incomingConnectionFactories); + f = new List<IceInternal.IncomingConnectionFactory>(_incomingConnectionFactories); } foreach(IceInternal.IncomingConnectionFactory factory in f) @@ -791,10 +779,9 @@ namespace Ice _servantManager = new IceInternal.ServantManager(instance, name); _activateOneOffDone = false; _name = name; - _incomingConnectionFactories = new ArrayList(); - _connectors = new ArrayList(); - _publishedEndpoints = new ArrayList(); - _routerEndpoints = new ArrayList(); + _incomingConnectionFactories = new List<IceInternal.IncomingConnectionFactory>(); + _publishedEndpoints = new List<IceInternal.EndpointI>(); + _routerEndpoints = new List<IceInternal.EndpointI>(); _routerInfo = null; _directCount = 0; _waitForActivate = false; @@ -809,7 +796,7 @@ namespace Ice } Properties properties = instance_.initializationData().properties; - ArrayList unknownProps = new ArrayList(); + List<string> unknownProps = new List<string>(); bool noProps = filterProperties(unknownProps); // @@ -872,7 +859,8 @@ namespace Ice if(router == null) { - router = RouterPrxHelper.uncheckedCast(instance_.proxyFactory().propertyToProxy(_name + ".Router")); + router = RouterPrxHelper.uncheckedCast( + instance_.proxyFactory().propertyToProxy(_name + ".Router")); } if(router != null) { @@ -906,9 +894,9 @@ namespace Ice // for(int i = 0; i < _routerEndpoints.Count-1;) { - System.Object o1 = _routerEndpoints[i]; - System.Object o2 = _routerEndpoints[i + 1]; - if(o1.Equals(o2)) + IceInternal.EndpointI e1 = _routerEndpoints[i]; + IceInternal.EndpointI e2 = _routerEndpoints[i + 1]; + if(e1.Equals(e2)) { _routerEndpoints.RemoveAt(i); } @@ -936,11 +924,10 @@ namespace Ice else { // - // Parse the endpoints, but don't store them in the adapter. - // The connection factory might change it, for example, to - // fill in the real port number. + // Parse the endpoints, but don't store them in the adapter. The connection + // factory might change it, for example, to fill in the real port number. // - ArrayList endpoints; + List<IceInternal.EndpointI> endpoints; if(endpointInfo.Length == 0) { endpoints = parseEndpoints(properties.getProperty(_name + ".Endpoints")); @@ -957,19 +944,18 @@ namespace Ice ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endp.ToString(); throw ex; } + IceInternal.IncomingConnectionFactory factory = new IceInternal.IncomingConnectionFactory(instance, endp, this, _name); _incomingConnectionFactories.Add(factory); - - _connectors.AddRange(factory.endpoint().connectors()); } if(endpoints.Count == 0) { IceInternal.TraceLevels tl = instance_.traceLevels(); if(tl.network >= 2) { - instance_.initializationData().logger.trace(tl.networkCat, - "created adapter `" + _name + "' without endpoints"); + instance_.initializationData().logger.trace(tl.networkCat, "created adapter `" + _name + + "' without endpoints"); } } @@ -1057,7 +1043,7 @@ namespace Ice endpoints = new IceInternal.EndpointI[sz + _routerEndpoints.Count]; for(int i = 0; i < sz; ++i) { - endpoints[i] = (IceInternal.EndpointI)_publishedEndpoints[i]; + endpoints[i] = _publishedEndpoints[i]; } // @@ -1067,7 +1053,7 @@ namespace Ice // for(int i = 0; i < _routerEndpoints.Count; ++i) { - endpoints[sz + i] = (IceInternal.EndpointI)_routerEndpoints[i]; + endpoints[sz + i] = _routerEndpoints[i]; } // @@ -1127,14 +1113,14 @@ namespace Ice } } - private ArrayList parseEndpoints(string endpts) + private List<IceInternal.EndpointI> parseEndpoints(string endpts) { int beg; int end = 0; string delim = " \t\n\r"; - ArrayList endpoints = new ArrayList(); + List<IceInternal.EndpointI> endpoints = new List<IceInternal.EndpointI>(); while(end < endpts.Length) { beg = IceUtil.StringUtil.findFirstNotOf(endpts, delim, end); @@ -1179,15 +1165,14 @@ namespace Ice return endpoints; } - ArrayList parsePublishedEndpoints() + private List<IceInternal.EndpointI> parsePublishedEndpoints() { - // // Parse published endpoints. If set, these are used in proxies // instead of the connection factory endpoints. // string endpts = instance_.initializationData().properties.getProperty(_name + ".PublishedEndpoints"); - ArrayList endpoints = parseEndpoints(endpts); + List<IceInternal.EndpointI> endpoints = parseEndpoints(endpts); if(endpoints.Count == 0) { foreach(IceInternal.IncomingConnectionFactory factory in _incomingConnectionFactories) @@ -1200,10 +1185,10 @@ namespace Ice // Expand any endpoints that may be listening on INADDR_ANY to // include actual addresses in the published endpoints. // - ArrayList expandedEndpoints = new ArrayList(); + List<IceInternal.EndpointI> expandedEndpoints = new List<IceInternal.EndpointI>(); foreach(IceInternal.EndpointI endp in endpoints) { - ArrayList endps = endp.expand(); + List<IceInternal.EndpointI> endps = endp.expand(); expandedEndpoints.AddRange(endps); } return expandedEndpoints; @@ -1298,7 +1283,7 @@ namespace Ice _processId = addWithUUID(servant).ice_getIdentity(); } locatorRegistry.setServerProcessProxy(serverId, - ProcessPrxHelper.uncheckedCast(createDirectProxy(_processId))); + ProcessPrxHelper.uncheckedCast(createDirectProxy(_processId))); } catch(ServerNotFoundException) { @@ -1327,8 +1312,7 @@ namespace Ice "ThreadPool.StackSize" }; - private bool - filterProperties(ArrayList unknownProps) + private bool filterProperties(List<string> unknownProps) { // // Do not create unknown properties list if Ice prefix, ie Ice, Glacier2, etc @@ -1345,7 +1329,8 @@ namespace Ice } bool noProps = true; - Dictionary<string, string> props = instance_.initializationData().properties.getPropertiesForPrefix(prefix); + Dictionary<string, string> props = + instance_.initializationData().properties.getPropertiesForPrefix(prefix); foreach(String prop in props.Keys) { bool valid = false; @@ -1378,11 +1363,10 @@ namespace Ice private readonly string _name; private readonly string _id; private readonly string _replicaGroupId; - private ArrayList _incomingConnectionFactories; - private ArrayList _connectors; - private ArrayList _routerEndpoints; + private List<IceInternal.IncomingConnectionFactory> _incomingConnectionFactories; + private List<IceInternal.EndpointI> _routerEndpoints; private IceInternal.RouterInfo _routerInfo; - private ArrayList _publishedEndpoints; + private List<IceInternal.EndpointI> _publishedEndpoints; private IceInternal.LocatorInfo _locatorInfo; private int _directCount; private bool _waitForActivate; diff --git a/cs/src/Ice/Outgoing.cs b/cs/src/Ice/Outgoing.cs index 507bf3530bb..995d492ed65 100644 --- a/cs/src/Ice/Outgoing.cs +++ b/cs/src/Ice/Outgoing.cs @@ -12,33 +12,41 @@ namespace IceInternal using System.Collections.Generic; using System.Diagnostics; + using System.Threading; - public class Outgoing + public interface OutgoingMessageCallback { - public Outgoing(Ice.ConnectionI connection, Reference r, string operation, Ice.OperationMode mode, - Dictionary<string, string> context, bool compress) + void sent(bool notify); + void finished(Ice.LocalException ex); + } + + public class Outgoing : OutgoingMessageCallback + { + public Outgoing(RequestHandler handler, string operation, Ice.OperationMode mode, + Dictionary<string, string> context) { - _connection = connection; - _reference = r; _state = StateUnsent; - _is = new BasicStream(r.getInstance()); - _os = new BasicStream(r.getInstance()); - _compress = compress; - + _sent = false; + _handler = handler; + + Instance instance = _handler.getReference().getInstance(); + _is = new BasicStream(instance); + _os = new BasicStream(instance); + writeHeader(operation, mode, context); } // // These functions allow this object to be reused, rather than reallocated. // - public void reset(Reference r, string operation, Ice.OperationMode mode, - Dictionary<string, string> context, bool compress) + public void reset(RequestHandler handler, string operation, Ice.OperationMode mode, + Dictionary<string, string> context) { - _reference = r; _state = StateUnsent; _exception = null; - _compress = compress; - + _sent = false; + _handler = handler; + writeHeader(operation, mode, context); } @@ -47,55 +55,47 @@ namespace IceInternal _is.reset(); _os.reset(); } - + // Returns true if ok, false if user exception. public bool invoke() { Debug.Assert(_state == StateUnsent); _os.endWriteEncaps(); - - switch(_reference.getMode()) + + switch(_handler.getReference().getMode()) { - case Reference.Mode.ModeTwoway: + case Reference.Mode.ModeTwoway: { - // - // We let all exceptions raised by sending directly - // propagate to the caller, because they can be - // retried without violating "at-most-once". In case - // of such exceptions, the connection object does not - // call back on this object, so we don't need to lock - // the mutex, keep track of state, or save exceptions. - // - _connection.sendRequest(_os, this, _compress); + _state = StateInProgress; - // - // Wait until the request has completed, or until the - // request times out. - // + Ice.ConnectionI connection = _handler.sendRequest(this); bool timedOut = false; - + lock(this) { + // - // It's possible that the request has already - // completed, due to a regular response, or because of - // an exception. So we only change the state to "in - // progress" if it is still "unsent". + // If the request is being sent in the background we first wait for the + // sent notification. // - if(_state == StateUnsent) + while(_state != StateFailed && !_sent) { - _state = StateInProgress; + Monitor.Wait(this); } - int timeout = _connection.timeout(); + // + // Wait until the request has completed, or until the request + // times out. + // + int timeout = connection.timeout(); while(_state == StateInProgress && !timedOut) { if(timeout >= 0) { - System.Threading.Monitor.Wait(this, timeout); - + Monitor.Wait(this, timeout); + if(_state == StateInProgress) { timedOut = true; @@ -103,18 +103,18 @@ namespace IceInternal } else { - System.Threading.Monitor.Wait(this); + Monitor.Wait(this); } } } - + if(timedOut) { // // Must be called outside the synchronization of // this object // - _connection.exception(new Ice.TimeoutException()); + connection.exception(new Ice.TimeoutException()); // // We must wait until the exception set above has @@ -124,14 +124,14 @@ namespace IceInternal { while(_state == StateInProgress) { - System.Threading.Monitor.Wait(this); + Monitor.Wait(this); } } } - + if(_exception != null) { - // + // // A CloseConnectionException indicates graceful // server shutdown, and is therefore always repeatable // without violating "at-most-once". That's because by @@ -142,11 +142,13 @@ namespace IceInternal // An ObjectNotExistException can always be retried as // well without violating "at-most-once". // - if(_exception is Ice.CloseConnectionException || _exception is Ice.ObjectNotExistException) + if(!_sent || + _exception is Ice.CloseConnectionException || + _exception is Ice.ObjectNotExistException) { throw _exception; } - + // // Throw the exception wrapped in a LocalExceptionWrapper, to // indicate that the request cannot be resent without @@ -154,35 +156,46 @@ namespace IceInternal // throw new LocalExceptionWrapper(_exception, false); } - + if(_state == StateUserException) { return false; } - - Debug.Assert(_state == StateOK); - break; + else + { + Debug.Assert(_state == StateOK); + return true; + } } - - case Reference.Mode.ModeOneway: - case Reference.Mode.ModeDatagram: + + case Reference.Mode.ModeOneway: + case Reference.Mode.ModeDatagram: { - // - // For oneway and datagram requests, the - // connection object never calls back on this - // object. Therefore we don't need to lock the - // mutex or save exceptions. We simply let all - // exceptions from sending propagate to the - // caller, because such exceptions can be retried - // without violating "at-most-once". - // _state = StateInProgress; - _connection.sendRequest(_os, null, _compress); - break; + if(_handler.sendRequest(this) != null) + { + // + // If the handler returns the connection, we must wait for the sent callback. + // + lock(this) + { + while(_state != StateFailed && !_sent) + { + Monitor.Wait(this); + } + + if(_exception != null) + { + Debug.Assert(!_sent); + throw _exception; + } + } + } + return true; } - - case Reference.Mode.ModeBatchOneway: - case Reference.Mode.ModeBatchDatagram: + + case Reference.Mode.ModeBatchOneway: + case Reference.Mode.ModeBatchDatagram: { // // For batch oneways and datagrams, the same rules @@ -190,28 +203,29 @@ namespace IceInternal // comment above) apply. // _state = StateInProgress; - _connection.finishBatchRequest(_os, _compress); - break; + _handler.finishBatchRequest(_os); + return true; } } - - return true; + + Debug.Assert(false); + return false; } - + public void abort(Ice.LocalException ex) { Debug.Assert(_state == StateUnsent); - + // // If we didn't finish a batch oneway or datagram request, // we must notify the connection about that we give up // ownership of the batch stream. // - if(_reference.getMode() == Reference.Mode.ModeBatchOneway || - _reference.getMode() == Reference.Mode.ModeBatchDatagram) + Reference.Mode mode = _handler.getReference().getMode(); + if(mode == Reference.Mode.ModeBatchOneway || mode == Reference.Mode.ModeBatchDatagram) { - _connection.abortBatchRequest(); - + _handler.abortBatchRequest(); + // // If we abort a batch requests, we cannot retry, // because not only the batch request that caused the @@ -220,15 +234,35 @@ namespace IceInternal // throw new LocalExceptionWrapper(ex, false); } - + throw ex; } + public void sent(bool notify) + { + if(notify) + { + lock(this) + { + _sent = true; + Monitor.Pulse(this); + } + } + else + { + // + // No synchronization is necessary if called from sendRequest() because the connection + // send mutex is locked and no other threads can call on Outgoing until it's released. + // + _sent = true; + } + } + public void finished(BasicStream istr) { lock(this) { - Debug.Assert(_reference.getMode() == Reference.Mode.ModeTwoway); // Can only be called for twoways. + Debug.Assert(_handler.getReference().getMode() == Reference.Mode.ModeTwoway); // Only for twoways. Debug.Assert(_state <= StateInProgress); @@ -248,7 +282,7 @@ namespace IceInternal _state = StateOK; // The state must be set last, in case there is an exception. break; } - + case ReplyStatus.replyUserException: { // @@ -260,7 +294,7 @@ namespace IceInternal _state = StateUserException; // The state must be set last, in case there is an exception. break; } - + case ReplyStatus.replyObjectNotExist: case ReplyStatus.replyFacetNotExist: case ReplyStatus.replyOperationNotExist: @@ -273,26 +307,26 @@ namespace IceInternal ex = new Ice.ObjectNotExistException(); break; } - + case ReplyStatus.replyFacetNotExist: { ex = new Ice.FacetNotExistException(); break; } - + case ReplyStatus.replyOperationNotExist: { ex = new Ice.OperationNotExistException(); break; } - + default: { Debug.Assert(false); break; } } - + ex.id = new Ice.Identity(); ex.id.read__(_is); @@ -319,7 +353,7 @@ namespace IceInternal _state = StateLocalException; // The state must be set last, in case there is an exception. break; } - + case ReplyStatus.replyUnknownException: case ReplyStatus.replyUnknownLocalException: case ReplyStatus.replyUnknownUserException: @@ -332,33 +366,33 @@ namespace IceInternal ex = new Ice.UnknownException(); break; } - + case ReplyStatus.replyUnknownLocalException: { ex = new Ice.UnknownLocalException(); break; } - - case ReplyStatus.replyUnknownUserException: + + case ReplyStatus.replyUnknownUserException: { ex = new Ice.UnknownUserException(); break; } - + default: { Debug.Assert(false); break; } } - + ex.unknown = _is.readString(); _exception = ex; _state = StateLocalException; // The state must be set last, in case there is an exception. break; } - + default: { _exception = new Ice.UnknownReplyStatusException(); @@ -367,62 +401,59 @@ namespace IceInternal } } - System.Threading.Monitor.Pulse(this); + Monitor.Pulse(this); } } - + public void finished(Ice.LocalException ex) { lock(this) { - Debug.Assert(_reference.getMode() == Reference.Mode.ModeTwoway); // Can only be called for twoways. - Debug.Assert(_state <= StateInProgress); - - _state = StateLocalException; + _state = StateFailed; _exception = ex; - System.Threading.Monitor.Pulse(this); + Monitor.Pulse(this); } } - + public BasicStream istr() { return _is; } - + public BasicStream ostr() { return _os; } - + private void writeHeader(string operation, Ice.OperationMode mode, Dictionary<string, string> context) { - switch(_reference.getMode()) + switch(_handler.getReference().getMode()) { - case Reference.Mode.ModeTwoway: - case Reference.Mode.ModeOneway: - case Reference.Mode.ModeDatagram: + case Reference.Mode.ModeTwoway: + case Reference.Mode.ModeOneway: + case Reference.Mode.ModeDatagram: { _os.writeBlob(IceInternal.Protocol.requestHdr); break; } - - case Reference.Mode.ModeBatchOneway: - case Reference.Mode.ModeBatchDatagram: + + case Reference.Mode.ModeBatchOneway: + case Reference.Mode.ModeBatchDatagram: { - _connection.prepareBatchRequest(_os); + _handler.prepareBatchRequest(_os); break; } } try { - _reference.getIdentity().write__(_os); + _handler.getReference().getIdentity().write__(_os); // // For compatibility with the old FacetPath. // - string facet = _reference.getFacet(); + string facet = _handler.getReference().getFacet(); if(facet == null || facet.Length == 0) { _os.writeStringSeq(null); @@ -449,11 +480,9 @@ namespace IceInternal // // Implicit context // - Ice.ImplicitContextI implicitContext = - _reference.getInstance().getImplicitContext(); - - Dictionary<string, string> prxContext = _reference.getContext(); - + Ice.ImplicitContextI implicitContext = _handler.getReference().getInstance().getImplicitContext(); + Dictionary<string, string> prxContext = _handler.getReference().getContext(); + if(implicitContext == null) { Ice.ContextHelper.write(_os, prxContext); @@ -463,7 +492,7 @@ namespace IceInternal implicitContext.write(prxContext, _os); } } - + // // Input and output parameters are always sent in an // encapsulation, which makes it possible to forward requests as @@ -476,24 +505,98 @@ namespace IceInternal abort(ex); } } - - private Ice.ConnectionI _connection; - private Reference _reference; + + internal RequestHandler _handler; + internal BasicStream _is; + internal BasicStream _os; + internal bool _sent; + private Ice.LocalException _exception; - + private const int StateUnsent = 0; private const int StateInProgress = 1; private const int StateOK = 2; private const int StateUserException = 3; private const int StateLocalException = 4; + private const int StateFailed = 5; private int _state; - - private BasicStream _is; - private BasicStream _os; - private bool _compress; // Immutable after construction - public Outgoing next; // For use by Ice.ObjectDelM_ } + public class BatchOutgoing : OutgoingMessageCallback + { + public BatchOutgoing(Ice.ConnectionI connection, Instance instance) + { + _connection = connection; + _sent = false; + _os = new BasicStream(instance); + } + + public BatchOutgoing(RequestHandler handler) + { + _handler = handler; + _sent = false; + _os = new BasicStream(handler.getReference().getInstance()); + } + + public void invoke() + { + Debug.Assert(_handler != null || _connection != null); + + if(_handler != null && !_handler.flushBatchRequests(this) || + _connection != null && !_connection.flushBatchRequests(this)) + { + lock(this) + { + while(_exception == null && !_sent) + { + Monitor.Wait(this); + } + + if(_exception != null) + { + throw _exception; + } + } + } + } + + public void sent(bool notify) + { + if(notify) + { + lock(this) + { + _sent = true; + Monitor.Pulse(this); + } + } + else + { + _sent = true; + } + } + + public void finished(Ice.LocalException ex) + { + lock(this) + { + _exception = ex; + Monitor.Pulse(this); + } + } + + public BasicStream ostr() + { + return _os; + } + + private RequestHandler _handler; + private Ice.ConnectionI _connection; + private BasicStream _os; + private bool _sent; + private Ice.LocalException _exception; + } + } diff --git a/cs/src/Ice/OutgoingAsync.cs b/cs/src/Ice/OutgoingAsync.cs index 695b3e89611..e9a0c6af7a7 100644 --- a/cs/src/Ice/OutgoingAsync.cs +++ b/cs/src/Ice/OutgoingAsync.cs @@ -15,22 +15,93 @@ namespace IceInternal using System.Diagnostics; using System.Threading; - public abstract class OutgoingAsync + public interface OutgoingAsyncMessageCallback { + void sent__(Ice.ConnectionI connection); + void finished__(Ice.LocalException ex); + } + + public abstract class OutgoingAsync : OutgoingAsyncMessageCallback + { + public OutgoingAsync() + { + } + public abstract void ice_exception(Ice.Exception ex); - - public void finished__(BasicStream istr) + + public BasicStream ostr__() // Avoids name clash with os__ member. + { + return os__; + } + + private class TaskI : TimerTask + { + internal TaskI(OutgoingAsync @out, Ice.ConnectionI connection) + { + _out = @out; + _connection = connection; + } + + public void runTimerTask() + { + _out.runTimerTask__(_connection); + } + + private OutgoingAsync _out; + private Ice.ConnectionI _connection; + } + + public void sent__(Ice.ConnectionI connection) { lock(_monitor) { - byte replyStatus; - - try + _sent = true; + + if(!_proxy.ice_isTwoway()) { + cleanup(); // No response expected, we're done with the OutgoingAsync. + } + else if(_response) + { + // + // If the response was already received notify finished() which is waiting. + // + Monitor.PulseAll(_monitor); + } + else if(connection.timeout() >= 0) + { + Debug.Assert(_timerTask == null); + _timerTask = new TaskI(this, connection); + _proxy.reference__().getInstance().timer().schedule(_timerTask, connection.timeout()); + } + } + } + + public void finished__(BasicStream istr) + { + Debug.Assert(_proxy.ice_isTwoway()); // Can only be called for twoways. + + byte replyStatus; + try + { + lock(_monitor) + { + Debug.Assert(os__ != null); + _response = true; + + if(_timerTask != null && _proxy.reference__().getInstance().timer().cancel(_timerTask)) + { + _timerTask = null; // Timer cancelled. + } + + while(!_sent || _timerTask != null) + { + Monitor.Wait(_monitor); + } + is__.swap(istr); - replyStatus = is__.readByte(); - + switch(replyStatus) { case ReplyStatus.replyOK: @@ -39,7 +110,7 @@ namespace IceInternal is__.startReadEncaps(); break; } - + case ReplyStatus.replyObjectNotExist: case ReplyStatus.replyFacetNotExist: case ReplyStatus.replyOperationNotExist: @@ -70,29 +141,29 @@ namespace IceInternal Ice.RequestFailedException ex = null; switch(replyStatus) { - case ReplyStatus.replyObjectNotExist: - { - ex = new Ice.ObjectNotExistException(); - break; - } - - case ReplyStatus.replyFacetNotExist: - { - ex = new Ice.FacetNotExistException(); - break; - } - - case ReplyStatus.replyOperationNotExist: - { - ex = new Ice.OperationNotExistException(); - break; - } + case ReplyStatus.replyObjectNotExist: + { + ex = new Ice.ObjectNotExistException(); + break; + } - default: - { - Debug.Assert(false); - break; - } + case ReplyStatus.replyFacetNotExist: + { + ex = new Ice.FacetNotExistException(); + break; + } + + case ReplyStatus.replyOperationNotExist: + { + ex = new Ice.OperationNotExistException(); + break; + } + + default: + { + Debug.Assert(false); + break; + } } ex.id = id; @@ -100,7 +171,7 @@ namespace IceInternal ex.operation = operation; throw ex; } - + case ReplyStatus.replyUnknownException: case ReplyStatus.replyUnknownLocalException: case ReplyStatus.replyUnknownUserException: @@ -110,26 +181,26 @@ namespace IceInternal Ice.UnknownException ex = null; switch(replyStatus) { - case ReplyStatus.replyUnknownException: - { - ex = new Ice.UnknownException(); - break; - } - case ReplyStatus.replyUnknownLocalException: - { - ex = new Ice.UnknownLocalException(); - break; - } - case ReplyStatus.replyUnknownUserException: - { - ex = new Ice.UnknownUserException(); - break; - } - default: - { - Debug.Assert(false); - break; - } + case ReplyStatus.replyUnknownException: + { + ex = new Ice.UnknownException(); + break; + } + case ReplyStatus.replyUnknownLocalException: + { + ex = new Ice.UnknownLocalException(); + break; + } + case ReplyStatus.replyUnknownUserException: + { + ex = new Ice.UnknownUserException(); + break; + } + default: + { + Debug.Assert(false); + break; + } } ex.unknown = unknown; throw ex; @@ -141,36 +212,49 @@ namespace IceInternal } } } - catch(Ice.LocalException ex) - { - finished__(ex); - return; - } - - Debug.Assert(replyStatus == ReplyStatus.replyOK || replyStatus == ReplyStatus.replyUserException); - - try - { - response__(replyStatus == ReplyStatus.replyOK); - } - catch(System.Exception ex) - { - warning(ex); - } - finally + } + catch(Ice.LocalException ex) + { + finished__(ex); + return; + } + + Debug.Assert(replyStatus == ReplyStatus.replyOK || replyStatus == ReplyStatus.replyUserException); + + try + { + response__(replyStatus == ReplyStatus.replyOK); + } + catch(System.Exception ex) + { + warning(ex); + } + finally + { + lock(_monitor) { cleanup(); } } } - + public void finished__(Ice.LocalException exc) { + bool retry = false; lock(_monitor) { - - if(os__ != null) + if(os__ != null) // Might be called from prepare__ or before prepare__ { + if(_timerTask != null && _proxy.reference__().getInstance().timer().cancel(_timerTask)) + { + _timerTask = null; // Timer cancelled. + } + + while(_timerTask != null) + { + Monitor.Wait(_monitor); + } + // // A CloseConnectionException indicates graceful // server shutdown, and is therefore always repeatable @@ -183,52 +267,84 @@ namespace IceInternal // An ObjectNotExistException can always be retried as // well without violating "at-most-once". // - if(_mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent || - exc is Ice.CloseConnectionException || exc is Ice.ObjectNotExistException) + if(!_sent || + _mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent || + exc is Ice.CloseConnectionException || exc is Ice.ObjectNotExistException) { - try - { - _cnt = ((Ice.ObjectPrxHelperBase)_proxy).handleException__(_delegate, exc, _cnt); - send__(); - return; - } - catch(Ice.LocalException) - { - } + retry = true; } } - + } + + if(retry) + { try { - ice_exception(exc); + _cnt = _proxy.handleException__(_delegate, exc, _cnt); + send__(); + return; } - catch(System.Exception ex) + catch(Ice.LocalException) { - warning(ex); } - finally + } + + try + { + ice_exception(exc); + } + catch(System.Exception ex) + { + warning(ex); + } + finally + { + lock(_monitor) { cleanup(); } } } - - public bool timedOut__() - { - long absoluteTimeoutMillis; - lock(_timeoutMutex) // MONO bug: Should be WaitOne(), but that's broken under Mono 1.0 for Linux. - { - absoluteTimeoutMillis = _absoluteTimeoutMillis; - } + public void finished__(LocalExceptionWrapper ex) + { + // + // NOTE: This is called if sendRequest/sendAsyncRequest fails with + // a LocalExceptionWrapper exception. It's not possible for the + // timer to be set at this point because the request couldn't be + // sent. + // + Debug.Assert(!_sent && _timerTask == null); - if(absoluteTimeoutMillis > 0) + try { - return Time.currentMonotonicTimeMillis() >= absoluteTimeoutMillis; + if(_mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent) + { + _cnt = _proxy.handleExceptionWrapperRelaxed__(_delegate, ex, _cnt); + } + else + { + _proxy.handleExceptionWrapper__(_delegate, ex); + } + send__(); } - else + catch(Ice.LocalException exc) { - return false; + try + { + ice_exception(exc); + } + catch(System.Exception exl) + { + warning(exl); + } + finally + { + lock(_monitor) + { + cleanup(); + } + } } } @@ -249,23 +365,28 @@ namespace IceInternal } // - // Can't call sync via a oneway proxy. + // Can't call async via a batch proxy. // - ((Ice.ObjectPrxHelperBase)prx).checkTwowayOnly__(operation); + _proxy = (Ice.ObjectPrxHelperBase)prx; + if(_proxy.ice_isBatchOneway() || _proxy.ice_isBatchDatagram()) + { + throw new Ice.FeatureNotSupportedException("can't send batch requests with AMI"); + } - _proxy = prx; _delegate = null; _cnt = 0; _mode = mode; + _sent = false; + _response = false; - Reference rf = ((Ice.ObjectPrxHelperBase)prx).reference__(); + Reference rf = _proxy.reference__(); Debug.Assert(is__ == null); is__ = new BasicStream(rf.getInstance()); Debug.Assert(os__ == null); os__ = new BasicStream(rf.getInstance()); os__.writeBlob(IceInternal.Protocol.requestHdr); - + rf.getIdentity().write__(os__); // @@ -298,11 +419,9 @@ namespace IceInternal // // Implicit context // - Ice.ImplicitContextI implicitContext = - rf.getInstance().getImplicitContext(); - + Ice.ImplicitContextI implicitContext = rf.getInstance().getImplicitContext(); Dictionary<string, string> prxContext = rf.getContext(); - + if(implicitContext == null) { Ice.ContextHelper.write(os__, prxContext); @@ -312,7 +431,7 @@ namespace IceInternal implicitContext.write(prxContext, os__); } } - + os__.startWriteEncaps(); } catch(Ice.LocalException) @@ -322,69 +441,57 @@ namespace IceInternal } } } - + protected void send__() { + // + // NOTE: no synchronization needed. At this point, no other threads can be calling on this object. + // + + RequestHandler handler; + try + { + _delegate = _proxy.getDelegate__(true); + handler = _delegate.getRequestHandler__(); + } + catch(Ice.LocalException ex) + { + finished__(ex); + return; + } + + _sent = false; + _response = false; + handler.sendAsyncRequest(this); + } + + protected abstract void response__(bool ok); + + private void runTimerTask__(Ice.ConnectionI connection) + { lock(_monitor) { - try - { - while(true) - { - bool comp; - _delegate = ((Ice.ObjectPrxHelperBase)_proxy).getDelegate__(); - Ice.ConnectionI con = _delegate.getConnection__(out comp); + Debug.Assert(_timerTask != null && _sent); // Can only be set once the request is sent. - // MONO bug: Should be WaitOne(), but that's broken under Mono 1.0 for Linux. - lock(_timeoutMutex) - { - if(con.timeout() >= 0) - { - _absoluteTimeoutMillis = Time.currentMonotonicTimeMillis() + con.timeout(); - } - else - { - _absoluteTimeoutMillis = 0; - } - } - - try - { - con.sendAsyncRequest(os__, this, comp); - - // - // Don't do anything after sendAsyncRequest() returned - // without an exception. I such case, there will be - // callbacks, i.e., calls to the finished__() - // functions. Since there is no mutex protection, we - // cannot modify state here and in such callbacks. - // - return; - } - catch(LocalExceptionWrapper ex) - { - ((Ice.ObjectPrxHelperBase)_proxy).handleExceptionWrapper__(_delegate, ex); - } - catch(Ice.LocalException ex) - { - _cnt = ((Ice.ObjectPrxHelperBase)_proxy).handleException__(_delegate, ex, _cnt); - } - } - } - catch(Ice.LocalException ex) + if(_response) // If the response was just received, don't close the connection. { - finished__(ex); + connection = null; } + _timerTask = null; + Monitor.PulseAll(_monitor); } - } - protected abstract void response__(bool ok); + if(connection != null) + { + connection.exception(new Ice.TimeoutException()); + } + } private void warning(System.Exception ex) { if(os__ != null) // Don't print anything if cleanup() was already called. { - Reference rf = ((Ice.ObjectPrxHelperBase)_proxy).reference__(); + Reference rf = _proxy.reference__(); if(rf.getInstance().initializationData().properties.getPropertyAsIntWithDefault( "Ice.Warn.AMICallback", 1) > 0) { @@ -395,26 +502,105 @@ namespace IceInternal private void cleanup() { + Debug.Assert(_timerTask == null); + is__ = null; os__ = null; Monitor.Pulse(_monitor); } - + protected BasicStream is__; - protected BasicStream os__; + protected BasicStream os__; // Cannot rename because the generated code assumes this name - private Ice.ObjectPrx _proxy; + private bool _sent; + private bool _response; + private Ice.ObjectPrxHelperBase _proxy; private Ice.ObjectDel_ _delegate; private int _cnt; private Ice.OperationMode _mode; - private long _absoluteTimeoutMillis; - Mutex _timeoutMutex = new Mutex(); + private TimerTask _timerTask; object _monitor = new object(); } + public abstract class BatchOutgoingAsync : OutgoingAsyncMessageCallback + { + public BatchOutgoingAsync() + { + } + + public abstract void ice_exception(Ice.LocalException ex); + + public BasicStream ostr__() + { + return os__; + } + + public void sent__(Ice.ConnectionI connection) + { + lock(_monitor) + { + cleanup(); + } + } + + public void finished__(Ice.LocalException exc) + { + try + { + ice_exception(exc); + } + catch(System.Exception ex) + { + warning(ex); + } + finally + { + lock(_monitor) + { + cleanup(); + } + } + } + + protected void prepare__(Instance instance) + { + lock(_monitor) + { + while(os__ != null) + { + Monitor.Wait(_monitor); + } + + Debug.Assert(os__ == null); + os__ = new BasicStream(instance); + } + } + + private void warning(System.Exception ex) + { + if(os__ != null) // Don't print anything if cleanup() was already called. + { + if(os__.instance().initializationData().properties.getPropertyAsIntWithDefault( + "Ice.Warn.AMICallback", 1) > 0) + { + os__.instance().initializationData().logger.warning("exception raised by AMI callback:\n" + ex); + } + } + } + + private void cleanup() + { + os__ = null; + Monitor.Pulse(_monitor); + } + + protected BasicStream os__; + private object _monitor = new object(); + } + } namespace Ice @@ -460,4 +646,28 @@ namespace Ice } } + public abstract class AMI_Object_ice_flushBatchRequests : IceInternal.BatchOutgoingAsync + { + public abstract override void ice_exception(LocalException ex); + + public void invoke__(Ice.ObjectPrx prx) + { + Ice.ObjectDel_ @delegate; + IceInternal.RequestHandler handler; + try + { + Ice.ObjectPrxHelperBase proxy = (Ice.ObjectPrxHelperBase)prx; + prepare__(proxy.reference__().getInstance()); + @delegate = proxy.getDelegate__(true); + handler = @delegate.getRequestHandler__(); + } + catch(Ice.LocalException ex) + { + finished__(ex); + return; + } + + handler.flushAsyncBatchRequests(this); + } + } } diff --git a/cs/src/Ice/PropertyNames.cs b/cs/src/Ice/PropertyNames.cs index c3c2e306490..12ce389da8a 100644 --- a/cs/src/Ice/PropertyNames.cs +++ b/cs/src/Ice/PropertyNames.cs @@ -7,7 +7,7 @@ // // ********************************************************************** // -// Generated by makeprops.py from file ../config/PropertyNames.xml, Thu Nov 22 20:40:28 2007 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Nov 26 11:29:02 2007 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cs/src/Ice/ProtocolPluginFacade.cs b/cs/src/Ice/ProtocolPluginFacade.cs index 1da53a9c0cb..ed1fb274f52 100644 --- a/cs/src/Ice/ProtocolPluginFacade.cs +++ b/cs/src/Ice/ProtocolPluginFacade.cs @@ -18,6 +18,11 @@ namespace IceInternal Ice.Communicator getCommunicator(); // + // Get the endpoint host resolver. + // + IceInternal.EndpointHostResolver getEndpointHostResolver(); + + // // Get the default hostname to be used in endpoints. // string getDefaultHost(); @@ -32,6 +37,11 @@ namespace IceInternal // Register an EndpointFactory. // void addEndpointFactory(EndpointFactory factory); + + // + // Get an EndpointFactory. + // + EndpointFactory getEndpointFactory(short type); } public sealed class ProtocolPluginFacadeI : ProtocolPluginFacade @@ -53,6 +63,14 @@ namespace IceInternal } // + // Get the endpoint host resolver. + // + public IceInternal.EndpointHostResolver getEndpointHostResolver() + { + return _instance.endpointHostResolver(); + } + + // // Get the default hostname to be used in endpoints. // public string getDefaultHost() @@ -81,6 +99,14 @@ namespace IceInternal _instance.endpointFactoryManager().add(factory); } + // + // Get an EndpointFactory. + // + public EndpointFactory getEndpointFactory(short type) + { + return _instance.endpointFactoryManager().get(type); + } + private Instance _instance; private Ice.Communicator _communicator; } diff --git a/cs/src/Ice/Proxy.cs b/cs/src/Ice/Proxy.cs index 10521766920..40eef1117f6 100644 --- a/cs/src/Ice/Proxy.cs +++ b/cs/src/Ice/Proxy.cs @@ -119,6 +119,9 @@ namespace Ice bool ice_isThreadPerConnection(); ObjectPrx ice_threadPerConnection(bool tpc); + void ice_flushBatchRequests(); + void ice_flushBatchRequests_async(AMI_Object_ice_flushBatchRequests cb); + [Obsolete("This method is deprecated, use ice_getConnection instead.")] Connection ice_connection(); Connection ice_getConnection(); @@ -172,8 +175,7 @@ namespace Ice return ice_isA(id__, context__, true); } - private bool ice_isA(string id__, Dictionary<string, string> context__, - bool explicitContext__) + private bool ice_isA(string id__, Dictionary<string, string> context__, bool explicitContext__) { if(explicitContext__ && context__ == null) { @@ -187,7 +189,7 @@ namespace Ice try { checkTwowayOnly__("ice_isA"); - del__ = getDelegate__(); + del__ = getDelegate__(false); return del__.ice_isA(id__, context__); } catch(IceInternal.LocalExceptionWrapper ex__) @@ -224,7 +226,7 @@ namespace Ice ObjectDel_ del__ = null; try { - del__ = getDelegate__(); + del__ = getDelegate__(false); del__.ice_ping(context__); return; } @@ -262,7 +264,7 @@ namespace Ice try { checkTwowayOnly__("ice_ids"); - del__ = getDelegate__(); + del__ = getDelegate__(false); return del__.ice_ids(context__); } catch(IceInternal.LocalExceptionWrapper ex__) @@ -299,7 +301,7 @@ namespace Ice try { checkTwowayOnly__("ice_id"); - del__ = getDelegate__(); + del__ = getDelegate__(false); return del__.ice_id(context__); } catch(IceInternal.LocalExceptionWrapper ex__) @@ -338,7 +340,7 @@ namespace Ice ObjectDel_ del__ = null; try { - del__ = getDelegate__(); + del__ = getDelegate__(false); return del__.ice_invoke(operation, mode, inParams, out outParams, context); } catch(IceInternal.LocalExceptionWrapper ex__) @@ -804,9 +806,9 @@ namespace Ice ObjectDel_ del__ = null; try { - del__ = getDelegate__(); - bool comp; - return del__.getConnection__(out comp); + del__ = getDelegate__(false); + // Wait for the connection to be established. + return del__.getRequestHandler__().getConnection(true); } catch(LocalException ex__) { @@ -827,8 +829,8 @@ namespace Ice { try { - bool comp; - return del__.getConnection__(out comp); + // Wait for the connection to be established. + return del__.getRequestHandler__().getConnection(false); } catch(CollocationOptimizationException) { @@ -837,6 +839,34 @@ namespace Ice return null; } + public void ice_flushBatchRequests() + { + int cnt__ = 0; + while(true) + { + ObjectDel_ del__ = null; + try + { + del__ = getDelegate__(false); + del__.ice_flushBatchRequests(); + return; + } + catch(IceInternal.LocalExceptionWrapper ex__) + { + handleExceptionWrapper__(del__, ex__); + } + catch(LocalException ex__) + { + cnt__ = handleException__(del__, ex__, cnt__); + } + } + } + + public void ice_flushBatchRequests_async(AMI_Object_ice_flushBatchRequests cb) + { + cb.invoke__(this); + } + public override bool Equals(object r) { ObjectPrxHelperBase rhs = r as ObjectPrxHelperBase; @@ -990,7 +1020,7 @@ namespace Ice } } - public ObjectDel_ getDelegate__() + public ObjectDel_ getDelegate__(bool async) { lock(this) { @@ -1014,19 +1044,8 @@ namespace Ice if(@delegate == null) { ObjectDelM_ d = createDelegateM__(); - d.setup(_reference); + d.setup(_reference, this, async); @delegate = d; - - // - // If this proxy is for a non-local object, and we are - // using a router, then add this proxy to the router info - // object. - // - IceInternal.RouterInfo ri = _reference.getRouterInfo(); - if(ri != null) - { - ri.addProxy(this); - } } if(_reference.getCacheConnection()) @@ -1043,6 +1062,26 @@ namespace Ice } } + public void setRequestHandler__(ObjectDel_ @delegate, IceInternal.RequestHandler handler) + { + lock(this) + { + if(@delegate == _delegate) + { + if(_delegate is ObjectDelM_) + { + _delegate = createDelegateM__(); + _delegate.setRequestHandler__(handler); + } + else if(_delegate is ObjectDelD_) + { + _delegate = createDelegateD__(); + _delegate.setRequestHandler__(handler); + } + } + } + } + protected virtual ObjectDelM_ createDelegateM__() { return new ObjectDelM_(); @@ -1163,7 +1202,10 @@ namespace Ice bool ice_invoke(string operation, Ice.OperationMode mode, byte[] inParams, out byte[] outParams, Dictionary<string, string> context); - ConnectionI getConnection__(out bool compress); + void ice_flushBatchRequests(); + + IceInternal.RequestHandler getRequestHandler__(); + void setRequestHandler__(IceInternal.RequestHandler handler); } public class ObjectDelD_ : ObjectDel_ @@ -1335,8 +1377,18 @@ namespace Ice { throw new CollocationOptimizationException(); } - - public virtual ConnectionI getConnection__(out bool compress) + + public virtual void ice_flushBatchRequests() + { + throw new CollocationOptimizationException(); + } + + public virtual IceInternal.RequestHandler getRequestHandler__() + { + throw new CollocationOptimizationException(); + } + + public virtual void setRequestHandler__(IceInternal.RequestHandler handler) { throw new CollocationOptimizationException(); } @@ -1421,7 +1473,7 @@ namespace Ice { public virtual bool ice_isA(string id__, Dictionary<string, string> context__) { - IceInternal.Outgoing og__ = getOutgoing("ice_isA", OperationMode.Nonmutating, context__); + IceInternal.Outgoing og__ = handler__.getOutgoing("ice_isA", OperationMode.Nonmutating, context__); try { try @@ -1457,13 +1509,13 @@ namespace Ice } finally { - reclaimOutgoing(og__); + handler__.reclaimOutgoing(og__); } } public virtual void ice_ping(Dictionary<string, string> context__) { - IceInternal.Outgoing og__ = getOutgoing("ice_ping", OperationMode.Nonmutating, context__); + IceInternal.Outgoing og__ = handler__.getOutgoing("ice_ping", OperationMode.Nonmutating, context__); try { bool ok__ = og__.invoke(); @@ -1489,13 +1541,13 @@ namespace Ice } finally { - reclaimOutgoing(og__); + handler__.reclaimOutgoing(og__); } } public virtual string[] ice_ids(Dictionary<string, string> context__) { - IceInternal.Outgoing og__ = getOutgoing("ice_ids", OperationMode.Nonmutating, context__); + IceInternal.Outgoing og__ = handler__.getOutgoing("ice_ids", OperationMode.Nonmutating, context__); try { bool ok__ = og__.invoke(); @@ -1522,13 +1574,13 @@ namespace Ice } finally { - reclaimOutgoing(og__); + handler__.reclaimOutgoing(og__); } } public virtual string ice_id(Dictionary<string, string> context__) { - IceInternal.Outgoing og__ = getOutgoing("ice_id", OperationMode.Nonmutating, context__); + IceInternal.Outgoing og__ = handler__.getOutgoing("ice_id", OperationMode.Nonmutating, context__); try { bool ok__ = og__.invoke(); @@ -1555,14 +1607,14 @@ namespace Ice } finally { - reclaimOutgoing(og__); + handler__.reclaimOutgoing(og__); } } - + public virtual bool ice_invoke(string operation, OperationMode mode, byte[] inParams, out byte[] outParams, Dictionary<string, string> context__) { - IceInternal.Outgoing og__ = getOutgoing(operation, mode, context__); + IceInternal.Outgoing og__ = handler__.getOutgoing(operation, mode, context__); try { try @@ -1576,7 +1628,7 @@ namespace Ice } bool ok = og__.invoke(); outParams = null; - if(reference__.getMode() == IceInternal.Reference.Mode.ModeTwoway) + if(handler__.getReference().getMode() == IceInternal.Reference.Mode.ModeTwoway) { try { @@ -1593,14 +1645,36 @@ namespace Ice } finally { - reclaimOutgoing(og__); + handler__.reclaimOutgoing(og__); } } - public virtual ConnectionI getConnection__(out bool compress) + public virtual void ice_flushBatchRequests() + { + IceInternal.BatchOutgoing @out = new IceInternal.BatchOutgoing(handler__); + try + { + @out.invoke(); + } + catch(Ice.LocalException ex) + { + // + // We never retry flusing the batch requests as the connection batched + // requests were discarded and the caller needs to be notified of the + // failure. + // + throw new IceInternal.LocalExceptionWrapper(ex, false); + } + } + + public virtual IceInternal.RequestHandler getRequestHandler__() { - compress = compress__; - return connection__; + return handler__; + } + + public virtual void setRequestHandler__(IceInternal.RequestHandler handler) + { + handler__ = handler; } // @@ -1612,47 +1686,39 @@ namespace Ice // No need to synchronize "from", as the delegate is immutable // after creation. // - + // // No need to synchronize, as this operation is only called // upon initialization. // - - Debug.Assert(reference__ == null); - Debug.Assert(connection__ == null); - - reference__ = from.reference__; - connection__ = from.connection__; - compress__ = from.compress__; + + Debug.Assert(handler__ == null); + + handler__ = from.handler__; } - protected IceInternal.Reference reference__; - protected ConnectionI connection__; - protected bool compress__; + protected IceInternal.RequestHandler handler__; - public virtual void setup(IceInternal.Reference rf) + public virtual void setup(IceInternal.Reference rf, Ice.ObjectPrx proxy, bool async) { // // No need to synchronize, as this operation is only called // upon initialization. // - - Debug.Assert(reference__ == null); - Debug.Assert(connection__ == null); - - reference__ = rf; - connection__ = reference__.getConnection(out compress__); - } - - protected IceInternal.Outgoing getOutgoing(string operation, OperationMode mode, - Dictionary<string, string> context) - { - return connection__.getOutgoing(reference__, operation, mode, context, compress__); - } - protected void reclaimOutgoing(IceInternal.Outgoing outg) - { - connection__.reclaimOutgoing(outg); + Debug.Assert(handler__ == null); + + if(async || + rf.getMode() == IceInternal.Reference.Mode.ModeBatchOneway || + rf.getMode() == IceInternal.Reference.Mode.ModeBatchDatagram) + { + IceInternal.ConnectRequestHandler handler = new IceInternal.ConnectRequestHandler(rf, proxy, this); + handler__ = handler.connect(); + } + else + { + handler__ = new IceInternal.ConnectionRequestHandler(rf, proxy); + } } } } diff --git a/cs/src/Ice/Reference.cs b/cs/src/Ice/Reference.cs index 9c5e88ff2e9..0e981a927d1 100644 --- a/cs/src/Ice/Reference.cs +++ b/cs/src/Ice/Reference.cs @@ -26,6 +26,12 @@ namespace IceInternal ModeLast=ModeBatchDatagram }; + public interface GetConnectionCallback + { + void setConnection(Ice.ConnectionI connection, bool compress); + void setException(Ice.LocalException ex); + } + public Mode getMode() { return mode_; @@ -320,6 +326,7 @@ namespace IceInternal } public abstract Ice.ConnectionI getConnection(out bool comp); + public abstract void getConnection(GetConnectionCallback callback); public override bool Equals(object obj) { @@ -557,6 +564,19 @@ namespace IceInternal return connection; } + public override void getConnection(GetConnectionCallback callback) + { + try + { + bool compress; + callback.setConnection(getConnection(out compress), compress); + } + catch(Ice.LocalException ex) + { + callback.setException(ex); + } + } + public override bool Equals(object obj) { if(object.ReferenceEquals(this, obj)) @@ -736,19 +756,6 @@ namespace IceInternal return _routerInfo; } - public EndpointI[] getRoutedEndpoints() - { - if(_routerInfo != null) - { - // - // If we route, we send everything to the router's client - // proxy endpoints. - // - return _routerInfo.getClientEndpoints(); - } - return new EndpointI[0]; - } - public override bool getSecure() { return _secure; @@ -1004,7 +1011,7 @@ namespace IceInternal } } - protected Ice.ConnectionI createConnection(EndpointI[] allEndpoints, out bool comp) + private EndpointI[] filterEndpoints(EndpointI[] allEndpoints) { ArrayList endpoints = new ArrayList(); @@ -1122,27 +1129,35 @@ namespace IceInternal { IceUtil.Arrays.Sort(ref endpoints, _preferNonSecureEndpointComparator); } - - if(endpoints.Count == 0) + + EndpointI[] arr = new EndpointI[endpoints.Count]; + endpoints.CopyTo(arr); + return arr; + } + + protected Ice.ConnectionI createConnection(EndpointI[] allEndpoints, out bool compress) + { + compress = false; // Satisfy the compiler + + EndpointI[] endpoints = filterEndpoints(allEndpoints); + if(endpoints.Length == 0) { - Ice.NoEndpointException ex = new Ice.NoEndpointException(); - ex.proxy = ToString(); - throw ex; + throw new Ice.NoEndpointException(ToString()); } - + // // Finally, create the connection. // OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory(); - if(getCacheConnection() || endpoints.Count == 1) + Ice.ConnectionI connection = null; + if(getCacheConnection() || endpoints.Length == 1) { // // Get an existing connection or create one if there's no // existing connection to one of the given endpoints. // - EndpointI[] arr = new EndpointI[endpoints.Count]; - endpoints.CopyTo(arr); - return factory.create(arr, false, _threadPerConnection, getEndpointSelection(), out comp); + connection = factory.create(endpoints, false, _threadPerConnection, getEndpointSelection(), + out compress); } else { @@ -1153,16 +1168,18 @@ namespace IceInternal // create a new connection even if there's an existing // connection for one of the endpoints. // + Ice.LocalException exception = null; EndpointI[] endpoint = new EndpointI[1]; - - foreach(EndpointI e in endpoints) + for(int i = 0; i < endpoints.Length; ++i) { try { - endpoint[0] = e; - return factory.create(endpoint, e != endpoints[endpoints.Count - 1], _threadPerConnection, - getEndpointSelection(), out comp); + endpoint[0] = endpoints[i]; + bool more = i != endpoints.Length - 1; + connection = factory.create(endpoint, more, _threadPerConnection, getEndpointSelection(), + out compress); + break; } catch(Ice.LocalException ex) { @@ -1170,8 +1187,111 @@ namespace IceInternal } } - Debug.Assert(exception != null); - throw exception; + if(connection == null) + { + Debug.Assert(exception != null); + throw exception; + } + } + + Debug.Assert(connection != null); + + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo != null) + { + connection.setAdapter(_routerInfo.getAdapter()); + } + + return connection; + } + + private sealed class ConnectionCallback : OutgoingConnectionFactory.CreateConnectionCallback + { + internal ConnectionCallback(RoutableReference rr, EndpointI[] endpoints, GetConnectionCallback callback) + { + _rr = rr; + _endpoints = endpoints; + _callback = callback; + } + + public void setConnection(Ice.ConnectionI connection, bool compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_rr._routerInfo != null) + { + connection.setAdapter(_rr._routerInfo.getAdapter()); + } + _callback.setConnection(connection, compress); + } + + public void setException(Ice.LocalException ex) + { + if(_exception == null) + { + _exception = ex; + } + + if(_endpoints == null || ++_i == _endpoints.Length) + { + _callback.setException(_exception); + return; + } + + bool more = _i != _endpoints.Length - 1; + EndpointI[] endpoint = new EndpointI[]{ _endpoints[_i] }; + _rr.getInstance().outgoingConnectionFactory().create(endpoint, more, _rr._threadPerConnection, + _rr.getEndpointSelection(), this); + } + + private RoutableReference _rr; + private EndpointI[] _endpoints; + private GetConnectionCallback _callback; + private int _i = 0; + private Ice.LocalException _exception = null; + } + + protected void createConnection(EndpointI[] allEndpoints, GetConnectionCallback callback) + { + EndpointI[] endpoints = filterEndpoints(allEndpoints); + if(endpoints.Length == 0) + { + callback.setException(new Ice.NoEndpointException(ToString())); + return; + } + + // + // Finally, create the connection. + // + OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory(); + if(getCacheConnection() || endpoints.Length == 1) + { + // + // Get an existing connection or create one if there's no + // existing connection to one of the given endpoints. + // + factory.create(endpoints, false, _threadPerConnection, getEndpointSelection(), + new ConnectionCallback(this, null, callback)); + } + else + { + // + // Go through the list of endpoints and try to create the + // connection until it succeeds. This is different from just + // calling create() with the given endpoints since this might + // create a new connection even if there's an existing + // connection for one of the endpoints. + // + + factory.create(new EndpointI[]{ endpoints[0] }, true, _threadPerConnection, getEndpointSelection(), + new ConnectionCallback(this, endpoints, callback)); } } @@ -1398,28 +1518,65 @@ namespace IceInternal public override Ice.ConnectionI getConnection(out bool comp) { - EndpointI[] endpts = base.getRoutedEndpoints(); - applyOverrides(ref endpts); + if(getRouterInfo() != null) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + EndpointI[] endpts = getRouterInfo().getClientEndpoints(); + if(endpts.Length > 0) + { + applyOverrides(ref endpts); + return createConnection(endpts, out comp); + } + } + + return createConnection(_endpoints, out comp); + } + + private sealed class RouterEndpointsCallback : RouterInfo.GetClientEndpointsCallback + { + internal RouterEndpointsCallback(DirectReference dr, GetConnectionCallback cb) + { + _dr = dr; + _cb = cb; + } - if(endpts.Length == 0) + public void setEndpoints(EndpointI[] endpts) { - endpts = _endpoints; // Endpoint overrides are already applied on these endpoints. + if(endpts.Length > 0) + { + _dr.applyOverrides(ref endpts); + _dr.createConnection(endpts, _cb); + return; + } + + _dr.createConnection(_dr._endpoints, _cb); } - Ice.ConnectionI connection = createConnection(endpts, out comp); + public void setException(Ice.LocalException ex) + { + _cb.setException(ex); + } - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // + private DirectReference _dr; + private GetConnectionCallback _cb; + } + + public override void getConnection(GetConnectionCallback callback) + { if(getRouterInfo() != null) { - connection.setAdapter(getRouterInfo().getAdapter()); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo().getClientEndpoints(new RouterEndpointsCallback(this, callback)); + return; } - Debug.Assert(connection != null); - return connection; + createConnection(_endpoints, callback); } public override bool Equals(object obj) @@ -1592,23 +1749,38 @@ namespace IceInternal public override Ice.ConnectionI getConnection(out bool comp) { - Ice.ConnectionI connection; + if(getRouterInfo() != null) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + EndpointI[] endpts = getRouterInfo().getClientEndpoints(); + if(endpts.Length > 0) + { + applyOverrides(ref endpts); + return createConnection(endpts, out comp); + } + } while(true) { - EndpointI[] endpts = base.getRoutedEndpoints(); bool cached = false; - if(endpts.Length == 0 && locatorInfo_ != null) + EndpointI[] endpts = null; + if(locatorInfo_ != null) { endpts = locatorInfo_.getEndpoints(this, locatorCacheTimeout_, out cached); + applyOverrides(ref endpts); } - applyOverrides(ref endpts); + if(endpts == null || endpts.Length == 0) + { + throw new Ice.NoEndpointException(ToString()); + } try { - connection = createConnection(endpts, out comp); - Debug.Assert(connection != null); + return createConnection(endpts, out comp); } catch(Ice.NoEndpointException ex) { @@ -1616,44 +1788,158 @@ namespace IceInternal } catch(Ice.LocalException ex) { - if(getRouterInfo() == null) + Debug.Assert(locatorInfo_ != null); + locatorInfo_.clearCache(this); + if(cached) { - Debug.Assert(locatorInfo_ != null); - locatorInfo_.clearCache(this); - - if(cached) + TraceLevels traceLevels = getInstance().traceLevels(); + if(traceLevels.retry >= 2) { - TraceLevels traceLevels = getInstance().traceLevels(); - - if(traceLevels.retry >= 2) - { - String s = "connection to cached endpoints failed\n" + - "removing endpoints from cache and trying one more time\n" + ex; - getInstance().initializationData().logger.trace(traceLevels.retryCat, s); - } - - continue; + String s = "connection to cached endpoints failed\n" + + "removing endpoints from cache and trying one more time\n" + ex; + getInstance().initializationData().logger.trace(traceLevels.retryCat, s); } + continue; // Try again if the endpoints were cached. } - throw; } + } + } - break; + private sealed class RouterEndpointsCallback : RouterInfo.GetClientEndpointsCallback + { + internal RouterEndpointsCallback(IndirectReference ir, GetConnectionCallback cb) + { + _ir = ir; + _cb = cb; } - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // + public void setEndpoints(EndpointI[] endpts) + { + if(endpts.Length > 0) + { + _ir.applyOverrides(ref endpts); + _ir.createConnection(endpts, _cb); + } + else + { + _ir.getConnectionNoRouterInfo(_cb); + } + } + + public void setException(Ice.LocalException ex) + { + _cb.setException(ex); + } + + private IndirectReference _ir; + private GetConnectionCallback _cb; + } + + public override void getConnection(GetConnectionCallback callback) + { if(getRouterInfo() != null) { - connection.setAdapter(getRouterInfo().getAdapter()); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo().getClientEndpoints(new RouterEndpointsCallback(this, callback)); + } + else + { + getConnectionNoRouterInfo(callback); } + } - Debug.Assert(connection != null); - return connection; + private sealed class LocatorEndpointsCallback : LocatorInfo.GetEndpointsCallback + { + internal LocatorEndpointsCallback(IndirectReference ir, GetConnectionCallback cb) + { + _ir = ir; + _cb = cb; + } + + public void setEndpoints(EndpointI[] endpoints, bool cached) + { + if(endpoints.Length == 0) + { + _cb.setException(new Ice.NoEndpointException(_ir.ToString())); + return; + } + + _ir.applyOverrides(ref endpoints); + _ir.createConnection(endpoints, new ConnectionCallback(_ir, _cb, cached)); + } + + public void setException(Ice.LocalException ex) + { + _cb.setException(ex); + } + + private IndirectReference _ir; + private GetConnectionCallback _cb; + } + + private sealed class ConnectionCallback : GetConnectionCallback + { + internal ConnectionCallback(IndirectReference ir, GetConnectionCallback cb, bool cached) + { + _ir = ir; + _cb = cb; + _cached = cached; + } + + public void setConnection(Ice.ConnectionI connection, bool compress) + { + _cb.setConnection(connection, compress); + } + + public void setException(Ice.LocalException exc) + { + try + { + throw exc; + } + catch(Ice.NoEndpointException ex) + { + _cb.setException(ex); // No need to retry if there's no endpoints. + } + catch(Ice.LocalException ex) + { + Debug.Assert(_ir.locatorInfo_ != null); + _ir.locatorInfo_.clearCache(_ir); + if(_cached) + { + TraceLevels traceLevels = _ir.getInstance().traceLevels(); + if(traceLevels.retry >= 2) + { + String s = "connection to cached endpoints failed\n" + + "removing endpoints from cache and trying one more time\n" + ex; + _ir.getInstance().initializationData().logger.trace(traceLevels.retryCat, s); + } + _ir.getConnectionNoRouterInfo(_cb); // Retry. + return; + } + _cb.setException(ex); + } + } + + private IndirectReference _ir; + private GetConnectionCallback _cb; + private bool _cached; + } + + private void getConnectionNoRouterInfo(GetConnectionCallback callback) + { + if(locatorInfo_ != null) + { + locatorInfo_.getEndpoints(this, locatorCacheTimeout_, new LocatorEndpointsCallback(this, callback)); + } + else + { + callback.setException(new Ice.NoEndpointException(ToString())); + } } public override bool Equals(object obj) diff --git a/cs/src/Ice/ReferenceFactory.cs b/cs/src/Ice/ReferenceFactory.cs index bb6ac0cfe4a..3e004454481 100644 --- a/cs/src/Ice/ReferenceFactory.cs +++ b/cs/src/Ice/ReferenceFactory.cs @@ -84,8 +84,8 @@ namespace IceInternal // Create new reference // IndirectReference @ref = new IndirectReference(instance_, _communicator, ident, context, facet, mode, - secure, preferSecure, adapterId, routerInfo, locatorInfo, - collocationOptimization, cacheConnection, + secure, preferSecure, adapterId, routerInfo, + locatorInfo, collocationOptimization, cacheConnection, endpointSelection, threadPerConnection, locatorCacheTimeout); return updateCache(@ref); @@ -590,7 +590,8 @@ namespace IceInternal } else { - @ref = @ref.changeRouter(Ice.RouterPrxHelper.uncheckedCast(_communicator.propertyToProxy(property))); + @ref = @ref.changeRouter( + Ice.RouterPrxHelper.uncheckedCast(_communicator.propertyToProxy(property))); } } diff --git a/cs/src/Ice/RequestHandler.cs b/cs/src/Ice/RequestHandler.cs new file mode 100755 index 00000000000..e33e957f53f --- /dev/null +++ b/cs/src/Ice/RequestHandler.cs @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System.Collections.Generic; + +namespace IceInternal +{ + public interface RequestHandler + { + void prepareBatchRequest(BasicStream @out); + void finishBatchRequest(BasicStream @out); + void abortBatchRequest(); + + Ice.ConnectionI sendRequest(Outgoing @out); + + void sendAsyncRequest(OutgoingAsync @out); + + bool flushBatchRequests(BatchOutgoing @out); + void flushAsyncBatchRequests(BatchOutgoingAsync @out); + + Reference getReference(); + + Ice.ConnectionI getConnection(bool wait); + + Outgoing getOutgoing(string operation, Ice.OperationMode mode, Dictionary<string, string> context); + + void reclaimOutgoing(Outgoing @out); + } +} diff --git a/cs/src/Ice/RouterInfo.cs b/cs/src/Ice/RouterInfo.cs index 1ee95536bdc..b7ae00d4314 100644 --- a/cs/src/Ice/RouterInfo.cs +++ b/cs/src/Ice/RouterInfo.cs @@ -11,18 +11,30 @@ namespace IceInternal { using System.Collections; + using System.Collections.Generic; using System.Diagnostics; public sealed class RouterInfo { + public interface GetClientEndpointsCallback + { + void setEndpoints(EndpointI[] endpoints); + void setException(Ice.LocalException ex); + } + + public interface AddProxyCallback + { + void addedProxy(); + void setException(Ice.LocalException ex); + } internal RouterInfo(Ice.RouterPrx router) { _router = router; - + Debug.Assert(_router != null); } - + public void destroy() { lock(this) @@ -33,7 +45,7 @@ namespace IceInternal _identities.Clear(); } } - + public override bool Equals(System.Object obj) { if(object.ReferenceEquals(this, obj)) @@ -49,7 +61,7 @@ namespace IceInternal { return _router.GetHashCode(); } - + public Ice.RouterPrx getRouter() { // @@ -62,24 +74,167 @@ namespace IceInternal { lock(this) { - if(_clientEndpoints == null) // Lazy initialization. + if(_clientEndpoints != null) // Lazy initialization. + { + return _clientEndpoints; + } + } + + return setClientEndpoints(_router.getClientProxy()); + } + + private class GetClientProxyCallback : Ice.AMI_Router_getClientProxy + { + internal GetClientProxyCallback(RouterInfo info, GetClientEndpointsCallback callback) + { + _info = info; + _callback = callback; + } + + public override void ice_response(Ice.ObjectPrx clientProxy) + { + _callback.setEndpoints(_info.setClientEndpoints(clientProxy)); + } + + public override void ice_exception(Ice.Exception ex) + { + Debug.Assert(ex is Ice.LocalException); + _callback.setException((Ice.LocalException)ex); + } + + private RouterInfo _info; + private GetClientEndpointsCallback _callback; + } + + public void getClientEndpoints(GetClientEndpointsCallback callback) + { + EndpointI[] clientEndpoints = null; + lock(this) + { + clientEndpoints = _clientEndpoints; + } + + if(clientEndpoints != null) // Lazy initialization. + { + callback.setEndpoints(clientEndpoints); + return; + } + + _router.getClientProxy_async(new GetClientProxyCallback(this, callback)); + } + + public EndpointI[] getServerEndpoints() + { + lock(this) + { + if(_serverEndpoints != null) // Lazy initialization. + { + return _serverEndpoints; + } + + } + + return setServerEndpoints(_router.getServerProxy()); + } + + public void addProxy(Ice.ObjectPrx proxy) + { + Debug.Assert(proxy != null); + lock(this) + { + if(_identities.Contains(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return; + } + } + + addAndEvictProxies(proxy, _router.addProxies(new Ice.ObjectPrx[] { proxy })); + } + + private class AddProxiesCallback : Ice.AMI_Router_addProxies + { + internal AddProxiesCallback(RouterInfo info, Ice.ObjectPrx prx, AddProxyCallback callback) + { + _info = info; + _prx = prx; + _callback = callback; + } + + public override void ice_response(Ice.ObjectPrx[] evictedProxies) + { + _info.addAndEvictProxies(_prx, evictedProxies); + _callback.addedProxy(); + } + + public override void ice_exception(Ice.Exception ex) + { + Debug.Assert(ex is Ice.LocalException); + _callback.setException((Ice.LocalException)ex); + } + + private RouterInfo _info; + private Ice.ObjectPrx _prx; + private AddProxyCallback _callback; + } + + public bool addProxy(Ice.ObjectPrx proxy, AddProxyCallback callback) + { + Debug.Assert(proxy != null); + lock(this) + { + if(_identities.Contains(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return true; + } + } + + _router.addProxies_async(new AddProxiesCallback(this, proxy, callback), new Ice.ObjectPrx[] { proxy }); + return false; + } + + public void setAdapter(Ice.ObjectAdapter adapter) + { + lock(this) + { + _adapter = adapter; + } + } + + public Ice.ObjectAdapter getAdapter() + { + lock(this) + { + return _adapter; + } + } + + private EndpointI[] setClientEndpoints(Ice.ObjectPrx clientProxy) + { + lock(this) + { + if(_clientEndpoints == null) { - Ice.ObjectPrx clientProxy = _router.getClientProxy(); if(clientProxy == null) { // - // Use router endpoints if getClientProxy returns nil. + // If getClientProxy() return nil, use router endpoints. // _clientEndpoints = ((Ice.ObjectPrxHelperBase)_router).reference__().getEndpoints(); } else { clientProxy = clientProxy.ice_router(null); // The client proxy cannot be routed. - + // - // In order to avoid creating a new connection to - // the router, we must use the same timeout as the - // already existing connection. + // In order to avoid creating a new connection to the + // router, we must use the same timeout as the already + // existing connection. // try { @@ -93,16 +248,14 @@ namespace IceInternal _clientEndpoints = ((Ice.ObjectPrxHelperBase)clientProxy).reference__().getEndpoints(); } } - return _clientEndpoints; } } - public EndpointI[] getServerEndpoints() + private EndpointI[] setServerEndpoints(Ice.ObjectPrx serverProxy) { - if(_serverEndpoints == null) // Lazy initialization. + lock(this) { - Ice.ObjectPrx serverProxy = _router.getServerProxy(); if(serverProxy == null) { throw new Ice.NoEndpointException(); @@ -110,72 +263,66 @@ namespace IceInternal serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed. _serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy).reference__().getEndpoints(); + return _serverEndpoints; } - - return _serverEndpoints; } - public void addProxy(Ice.ObjectPrx proxy) + private void addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies) { - Debug.Assert(proxy != null); - lock(this) { - if(!_identities.Contains(proxy.ice_getIdentity())) + // + // Check if the proxy hasn't already been evicted by a + // concurrent addProxies call. If it's the case, don't + // add it to our local map. + // + int index = _evictedIdentities.IndexOf(proxy.ice_getIdentity()); + if(index >= 0) + { + _evictedIdentities.RemoveAt(index); + } + else { // - // Only add the proxy to the router if it's not already in our local map. - // - Ice.ObjectPrx[] proxies = new Ice.ObjectPrx[1]; - proxies[0] = proxy; - Ice.ObjectPrx[] evictedProxies = _router.addProxies(proxies); - - // - // If we successfully added the proxy to the router, we add it to our local map. + // If we successfully added the proxy to the router, + // we add it to our local map. // _identities.Add(proxy.ice_getIdentity()); + } - // - // We also must remove whatever proxies the router evicted. - // - for(int i = 0; i < evictedProxies.Length; ++i) + // + // We also must remove whatever proxies the router evicted. + // + for(int i = 0; i < evictedProxies.Length; ++i) + { + if(!_identities.Remove(evictedProxies[i].ice_getIdentity())) { - _identities.Remove(evictedProxies[i].ice_getIdentity()); + // + // It's possible for the proxy to not have been + // added yet in the local map if two threads + // concurrently call addProxies. + // + _evictedIdentities.Add(evictedProxies[i].ice_getIdentity()); } } } } - public void setAdapter(Ice.ObjectAdapter adapter) - { - lock(this) - { - _adapter = adapter; - } - } - - public Ice.ObjectAdapter getAdapter() - { - lock(this) - { - return _adapter; - } - } - private readonly Ice.RouterPrx _router; private EndpointI[] _clientEndpoints; private EndpointI[] _serverEndpoints; - private IceUtil.Set _identities = new IceUtil.Set(); private Ice.ObjectAdapter _adapter; + private IceUtil.Set _identities = new IceUtil.Set(); + private List<Ice.Identity> _evictedIdentities = new List<Ice.Identity>(); } public sealed class RouterManager { internal RouterManager() { - _table = new Hashtable(); + _table = new Dictionary<Ice.RouterPrx, RouterInfo>(); } - + internal void destroy() { lock(this) @@ -187,7 +334,7 @@ namespace IceInternal _table.Clear(); } } - + // // Returns router info for a given router. Automatically creates // the router info if it doesn't exist yet. @@ -198,18 +345,21 @@ namespace IceInternal { return null; } - - Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); // The router cannot be routed. - + + // + // The router cannot be routed. + // + Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); + lock(this) { - RouterInfo info = (RouterInfo)_table[router]; - if(info == null) + RouterInfo info = null; + if(!_table.TryGetValue(router, out info)) { info = new RouterInfo(router); - _table[router] = info; + _table.Add(router, info); } - + return info; } } @@ -221,13 +371,16 @@ namespace IceInternal public RouterInfo erase(Ice.RouterPrx rtr) { RouterInfo info = null; - if(rtr == null) + if(rtr != null) { - Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); // The router cannot be routed. + // + // The router cannot be routed. + // + Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); + lock(this) { - info = (RouterInfo)_table[router]; - if(info != null) + if(_table.TryGetValue(router, out info)) { _table.Remove(router); } @@ -235,8 +388,8 @@ namespace IceInternal } return info; } - - private Hashtable _table; + + private Dictionary<Ice.RouterPrx, RouterInfo> _table; } } diff --git a/cs/src/Ice/SelectorThread.cs b/cs/src/Ice/SelectorThread.cs new file mode 100644 index 00000000000..96d1b0317b9 --- /dev/null +++ b/cs/src/Ice/SelectorThread.cs @@ -0,0 +1,417 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +namespace IceInternal +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net.Sockets; + using System.Threading; + + public sealed class SelectorThread + { + public interface SocketReadyCallback + { + // + // The selector thread unregisters the callback when socketReady returns SocketStatus.Finished. + // + SocketStatus socketReady(bool finished); + + // + // The selector thread doesn't unregister the callback when sockectTimeout is called; socketTimeout + // must unregister the callback either explicitly with unregister() or by shutting down the socket + // (if necessary). + // + void socketTimeout(); + } + + internal SelectorThread(Instance instance) + { + _instance = instance; + _destroyed = false; + + Network.SocketPair pair = Network.createPipe(); + _fdIntrRead = pair.source; + _fdIntrWrite = pair.sink; + Network.setBlock(_fdIntrRead, false); + + _thread = new HelperThread(this); + _thread.Start(); + + _timer = _instance.timer(); + } + + public void destroy() + { + lock(this) + { + Debug.Assert(!_destroyed); + _destroyed = true; + setInterrupt(); + } + } + + public void register(Socket fd, SocketReadyCallback cb, SocketStatus status, int timeout) + { + lock(this) + { + Debug.Assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing connection + // factories. + Debug.Assert(status != SocketStatus.Finished); + + SocketInfo info = new SocketInfo(fd, cb, status, timeout); + _changes.AddLast(info); + if(info.timeout >= 0) + { + _timer.schedule(info, info.timeout); + } + setInterrupt(); + } + } + + // + // Unregister the given file descriptor. The registered callback will be notified with socketReady() + // upon registration to allow some cleanup to be done. + // + public void unregister(Socket fd) + { + lock(this) + { + Debug.Assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing + // connection factories. + _changes.AddLast(new SocketInfo(fd, null, SocketStatus.Finished, 0)); + setInterrupt(); + } + } + + public void joinWithThread() + { + if(_thread != null) + { + _thread.Join(); + } + } + + private void clearInterrupt() + { + repeat: + try + { + _fdIntrRead.Receive(_intrBuf); + } + catch(SocketException ex) + { + if(Network.interrupted(ex)) + { + goto repeat; + } + if(!Network.wouldBlock(ex)) + { + throw new Ice.SocketException(ex); + } + } + } + + private void setInterrupt() + { + repeat: + try + { + _fdIntrWrite.Send(_intrBuf); + } + catch(SocketException ex) + { + if(Network.interrupted(ex)) + { + goto repeat; + } + throw new Ice.SocketException(ex); + } + } + + private static byte[] _intrBuf = new byte[1]; + + public void run() + { + Dictionary<Socket, SocketInfo> socketMap = new Dictionary<Socket, SocketInfo>(); + List<SocketInfo> readyList = new List<SocketInfo>(); + List<SocketInfo> finishedList = new List<SocketInfo>(); + + Selector selector = new Selector(); + selector.add(_fdIntrRead, SocketStatus.NeedRead); + + while(true) + { + selector.select(-1); + + Debug.Assert(readyList.Count == 0 && finishedList.Count == 0); + + if(selector.selRead.Contains(_fdIntrRead)) + { + lock(this) + { + // + // There are two possiblities for an interrupt: + // + // 1. The selector thread has been destroyed. + // 2. A socket was registered or unregistered. + // + + // + // Thread destroyed? + // + if(_destroyed) + { + break; + } + + clearInterrupt(); + SocketInfo info = _changes.First.Value; + _changes.RemoveFirst(); + if(info.cb != null) // Registration + { + selector.add(info.fd, info.status); + Debug.Assert(!socketMap.ContainsKey(info.fd)); + socketMap.Add(info.fd, info); + } + else // Unregistration + { + if(socketMap.TryGetValue(info.fd, out info)) + { + if(info.status != SocketStatus.Finished) + { + if(info.timeout >= 0) + { + _timer.cancel(info); + } + + selector.remove(info.fd, info.status); + info.status = SocketStatus.Finished; + readyList.Add(info); + } + } + } + } + } + else + { + // + // Examine the selected sockets. + // + foreach(Socket fd in selector.selRead) + { + Debug.Assert(fd != _fdIntrRead); + SocketInfo info = null; + if(socketMap.TryGetValue(fd, out info)) + { + if(info.timeout >= 0) + { + _timer.cancel(info); + } + Debug.Assert(!readyList.Contains(info)); + readyList.Add(info); + } + } + foreach(Socket fd in selector.selWrite) + { + SocketInfo info = null; + if(socketMap.TryGetValue(fd, out info)) + { + if(info.timeout >= 0) + { + _timer.cancel(info); + } + Debug.Assert(!readyList.Contains(info)); + readyList.Add(info); + } + } + foreach(Socket fd in selector.selError) + { + SocketInfo info = null; + if(socketMap.TryGetValue(fd, out info)) + { + if(info.timeout >= 0) + { + _timer.cancel(info); + } + Debug.Assert(!readyList.Contains(info)); + readyList.Add(info); + } + } + } + + foreach(SocketInfo info in readyList) + { + SocketStatus status; + try + { + status = info.cb.socketReady(info.status == SocketStatus.Finished); + } + catch(Ice.LocalException ex) + { + string s = "exception in selector thread " + _thread.Name() + + " while calling socketReady():\n" + ex; + _instance.initializationData().logger.error(s); + status = SocketStatus.Finished; + } + + if(status == SocketStatus.Finished) + { + finishedList.Add(info); + } + else + { + Debug.Assert(info.status != SocketStatus.Finished); + if(status != info.status) // Status has changed. + { + selector.remove(info.fd, info.status); + selector.add(info.fd, status); + } + info.status = status; + if(info.timeout >= 0) + { + _timer.schedule(info, info.timeout); + } + } + } + readyList.Clear(); + + if(finishedList.Count == 0) + { + continue; + } + + foreach(SocketInfo info in finishedList) + { + if(info.status != SocketStatus.Finished) + { + selector.remove(info.fd, info.status); + } + socketMap.Remove(info.fd); + } + finishedList.Clear(); + } + + Debug.Assert(_destroyed); + + try + { + _fdIntrWrite.Close(); + } + catch(System.IO.IOException) + { + } + _fdIntrWrite = null; + + try + { + _fdIntrRead.Close(); + } + catch(System.IO.IOException) + { + } + _fdIntrRead = null; + } + + private Instance _instance; + private bool _destroyed; + private Socket _fdIntrRead; + private Socket _fdIntrWrite; + private LinkedList<SocketInfo> _changes = new LinkedList<SocketInfo>(); + + private sealed class SocketInfo : TimerTask + { + internal Socket fd; + internal SocketReadyCallback cb; + internal SocketStatus status; + internal int timeout; + + public void runTimerTask() + { + this.cb.socketTimeout(); // Exceptions will be reported by the timer thread. + } + + internal SocketInfo(Socket fd, SocketReadyCallback cb, SocketStatus status, int timeout) + { + this.fd = fd; + this.cb = cb; + this.status = status; + this.timeout = timeout; + } + } + + private sealed class HelperThread + { + internal HelperThread(SelectorThread selectorThread) + { + selectorThread_ = selectorThread; + name_ = selectorThread_._instance.initializationData().properties.getProperty("Ice.ProgramName"); + if(name_.Length > 0) + { + name_ += "-"; + } + name_ += "Ice.SelectorThread"; + } + + public string Name() + { + return name_; + } + + public void Join() + { + _thread.Join(); + } + + public void Start() + { + _thread = new Thread(new ThreadStart(Run)); + _thread.IsBackground = true; + _thread.Name = name_; + _thread.Start(); + } + + public void Run() + { + if(selectorThread_._instance.initializationData().threadHook != null) + { + selectorThread_._instance.initializationData().threadHook.start(); + } + + try + { + selectorThread_.run(); + } + catch(Ice.LocalException ex) + { + string s = "exception in selector thread " + name_ + ":\n" + ex; + selectorThread_._instance.initializationData().logger.error(s); + } + catch(System.Exception ex) + { + string s = "unknown exception in selector thread " + name_ + ":\n" + ex; + selectorThread_._instance.initializationData().logger.error(s); + } + + if(selectorThread_._instance.initializationData().threadHook != null) + { + selectorThread_._instance.initializationData().threadHook.stop(); + } + } + + private SelectorThread selectorThread_; + private string name_; + private Thread _thread; + } + + private HelperThread _thread; + private Timer _timer; + } +} diff --git a/cs/src/Ice/StreamI.cs b/cs/src/Ice/StreamI.cs index 9b418c6744c..1770e32a7e9 100644 --- a/cs/src/Ice/StreamI.cs +++ b/cs/src/Ice/StreamI.cs @@ -18,10 +18,10 @@ namespace Ice _is = new IceInternal.BasicStream(Util.getInstance(communicator)); _is.closure(this); _is.resize(data.Length, true); - IceInternal.ByteBuffer buf = _is.prepareRead(); - buf.position(0); - buf.put(data); - buf.position(0); + IceInternal.Buffer buf = _is.getBuffer(); + buf.b.position(0); + buf.b.put(data); + buf.b.position(0); } public Communicator communicator() @@ -362,9 +362,9 @@ namespace Ice public byte[] finished() { - IceInternal.ByteBuffer buf = _os.prepareWrite(); - byte[] result = new byte[buf.limit()]; - buf.get(result); + IceInternal.Buffer buf = _os.prepareWrite(); + byte[] result = new byte[buf.b.limit()]; + buf.b.get(result); return result; } diff --git a/cs/src/Ice/TcpAcceptor.cs b/cs/src/Ice/TcpAcceptor.cs index af74e4e78a5..dcb59845a3e 100644 --- a/cs/src/Ice/TcpAcceptor.cs +++ b/cs/src/Ice/TcpAcceptor.cs @@ -72,7 +72,7 @@ namespace IceInternal _logger.trace(_traceLevels.networkCat, s); } - return new TcpTransceiver(instance_, fd); + return new TcpTransceiver(instance_, fd, true); } public virtual void connectToSelf() diff --git a/cs/src/Ice/TcpConnector.cs b/cs/src/Ice/TcpConnector.cs index 88de588dabd..9081568f881 100644 --- a/cs/src/Ice/TcpConnector.cs +++ b/cs/src/Ice/TcpConnector.cs @@ -24,73 +24,25 @@ namespace IceInternal string s = "trying to establish tcp connection to " + ToString(); _logger.trace(_traceLevels.networkCat, s); } - + Socket fd = Network.createSocket(false); Network.setBlock(fd, false); Network.setTcpBufSize(fd, instance_.initializationData().properties, _logger); - Network.doConnect(fd, _addr, timeout); - - if(_traceLevels.network >= 1) + bool connected = Network.doConnect(fd, _addr, timeout); + if(connected) { - string s = "tcp connection established\n" + Network.fdToString(fd); - _logger.trace(_traceLevels.networkCat, s); + if(_traceLevels.network >= 1) + { + string s = "tcp connection established\n" + Network.fdToString(fd); + _logger.trace(_traceLevels.networkCat, s); + } } - - return new TcpTransceiver(instance_, fd); + return new TcpTransceiver(instance_, fd, connected); } public short type() { - return TYPE; - } - - public override string ToString() - { - return Network.addrToString(_addr); - } - - internal bool equivalent(string host, int port) - { - IPEndPoint addr; - try - { - addr = Network.getAddress(host, port); - } - catch(Ice.DNSException) - { - return false; - } - return addr.Equals(_addr); - } - - // - // Only for use by TcpEndpoint - // - internal TcpConnector(Instance instance, IPEndPoint addr, int timeout, string connectionId) - { - instance_ = instance; - _traceLevels = instance.traceLevels(); - _logger = instance.initializationData().logger; - _addr = addr; - _timeout = timeout; - _connectionId = connectionId; - - _hashCode = _addr.GetHashCode(); - _hashCode = 5 * _hashCode + _timeout; - _hashCode = 5 * _hashCode + _connectionId.GetHashCode(); - } - - public override int GetHashCode() - { - return _hashCode; - } - - // - // Compare endpoints for sorting purposes - // - public override bool Equals(object obj) - { - return CompareTo(obj) == 0; + return TcpEndpointI.TYPE; } public int CompareTo(object obj) @@ -135,7 +87,39 @@ namespace IceInternal return Network.compareAddress(_addr, p._addr); } - + + // + // Only for use by TcpEndpoint + // + internal TcpConnector(Instance instance, IPEndPoint addr, int timeout, string connectionId) + { + instance_ = instance; + _traceLevels = instance.traceLevels(); + _logger = instance.initializationData().logger; + _addr = addr; + _timeout = timeout; + _connectionId = connectionId; + + _hashCode = _addr.GetHashCode(); + _hashCode = 5 * _hashCode + _timeout; + _hashCode = 5 * _hashCode + _connectionId.GetHashCode(); + } + + public override bool Equals(object obj) + { + return CompareTo(obj) == 0; + } + + public override string ToString() + { + return Network.addrToString(_addr); + } + + public override int GetHashCode() + { + return _hashCode; + } + private Instance instance_; private TraceLevels _traceLevels; private Ice.Logger _logger; diff --git a/cs/src/Ice/TcpEndpointI.cs b/cs/src/Ice/TcpEndpointI.cs index 629d2a2014b..ebce3d9460d 100644 --- a/cs/src/Ice/TcpEndpointI.cs +++ b/cs/src/Ice/TcpEndpointI.cs @@ -12,6 +12,8 @@ namespace IceInternal using System.Diagnostics; using System.Collections; + using System.Collections.Generic; + using System.Net; sealed class TcpEndpointI : EndpointI { @@ -335,22 +337,21 @@ namespace IceInternal endpoint = this; return null; } - + // // Return connectors for this endpoint, or empty list if no connector // is available. // - public override ArrayList connectors() + public override List<Connector> connectors() { - ArrayList connectors = new ArrayList(); - System.Net.IPEndPoint[] addresses = Network.getAddresses(_host, _port); - for(int i = 0; i < addresses.Length; ++i) - { - connectors.Add(new TcpConnector(instance_, addresses[i], _timeout, _connectionId)); - } - return connectors; + return connectors(Network.getAddresses(_host, _port)); } - + + public override void connectors_async(EndpointI_connectors callback) + { + instance_.endpointHostResolver().resolve(_host, _port, this, callback); + } + // // Return an acceptor for this endpoint, or null if no acceptors // is available. In case an acceptor is created, this operation @@ -369,10 +370,10 @@ namespace IceInternal // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public override ArrayList + public override List<EndpointI> expand() { - ArrayList endps = new ArrayList(); + List<EndpointI> endps = new List<EndpointI>(); if(_host.Equals("0.0.0.0")) { string[] hosts = Network.getLocalHosts(); @@ -392,20 +393,20 @@ namespace IceInternal } // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - public override bool equivalent(Connector connector) + public override bool equivalent(EndpointI endpoint) { - TcpConnector tcpConnector = null; + TcpEndpointI tcpEndpointI = null; try { - tcpConnector = (TcpConnector)connector; + tcpEndpointI = (TcpEndpointI)endpoint; } catch(System.InvalidCastException) { return false; } - return tcpConnector.equivalent(_host, _port); + return tcpEndpointI._host.Equals(_host) && tcpEndpointI._port == _port; } public override bool requiresThreadPerConnection() @@ -413,6 +414,16 @@ namespace IceInternal return false; } + public override List<Connector> connectors(List<IPEndPoint> addresses) + { + List<Connector> connectors = new List<Connector>(); + foreach(IPEndPoint addr in addresses) + { + connectors.Add(new TcpConnector(instance_, addr, _timeout, _connectionId)); + } + return connectors; + } + public override int GetHashCode() { return _hashCode; diff --git a/cs/src/Ice/TcpTransceiver.cs b/cs/src/Ice/TcpTransceiver.cs index 1ead7d49b43..3c856b2d0c2 100644 --- a/cs/src/Ice/TcpTransceiver.cs +++ b/cs/src/Ice/TcpTransceiver.cs @@ -22,7 +22,29 @@ namespace IceInternal Debug.Assert(_fd != null); return _fd; } - + + public SocketStatus initialize(int timeout) + { + if(_state == StateNeedConnect && timeout == 0) + { + _state = StateConnectPending; + return SocketStatus.NeedConnect; + } + else if(_state <= StateConnectPending) + { + Network.doFinishConnect(_fd, timeout); + _state = StateConnected; + _desc = Network.fdToString(_fd); + if(_traceLevels.network >= 1) + { + string s = "tcp connection established\n" + _desc; + _logger.trace(_traceLevels.networkCat, s); + } + } + Debug.Assert(_state == StateConnected); + return SocketStatus.Finished; + } + public void close() { if(_traceLevels.network >= 1) @@ -30,7 +52,7 @@ namespace IceInternal string s = "closing tcp connection\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } - + lock(this) { Debug.Assert(_fd != null); @@ -51,12 +73,17 @@ namespace IceInternal public void shutdownWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels.network >= 2) { string s = "shutting down tcp connection for writing\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } - + Debug.Assert(_fd != null); try { @@ -74,12 +101,17 @@ namespace IceInternal public void shutdownReadWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels.network >= 2) { string s = "shutting down tcp connection for reading and writing\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } - + Debug.Assert(_fd != null); try { @@ -95,113 +127,40 @@ namespace IceInternal } } - public void write(BasicStream stream, int timeout) + public bool write(Buffer buf, int timeout) { - Debug.Assert(_fd != null); - - ByteBuffer buf = stream.prepareWrite(); - int remaining = buf.remaining(); - int position = buf.position(); - int packetSize = remaining; - if(_maxPacketSize > 0 && packetSize > _maxPacketSize) + while(writeBuffer(buf.b)) { - packetSize = _maxPacketSize; - } - - try - { - while(remaining > 0) - { - int ret; - try - { - // - // Try to send first. Most of the time, this will work and - // avoids the cost of calling Poll(). - // - ret = _fd.Send(buf.rawBytes(), position, packetSize, SocketFlags.None); - Debug.Assert(ret != 0); - } - catch(Win32Exception e) - { - if(Network.wouldBlock(e)) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - ret = 0; - } - else - { - throw; - } - } - if(ret == 0) - { - // - // The first attempt to write would have blocked, - // so wait for the socket to become writable now. - // - if(!Network.doPoll(_fd, timeout, Network.PollMode.Write)) - { - throw new Ice.TimeoutException(); - } - continue; - } - - if(_traceLevels.network >= 3) - { - string s = "sent " + ret + " of " + remaining + " bytes via tcp\n" + ToString(); - _logger.trace(_traceLevels.networkCat, s); - } - if(_stats != null) - { - _stats.bytesSent(type(), ret); - } + // + // There is more data to write but the socket would block; now we + // must deal with timeouts. + // + Debug.Assert(buf.b.hasRemaining()); - remaining -= ret; - buf.position(position += ret); - if(remaining < packetSize) - { - packetSize = remaining; - } - } - } - catch(SocketException ex) - { - if(Network.connectionLost(ex)) + if(timeout == 0) { - throw new Ice.ConnectionLostException(ex); + return false; } - if(Network.wouldBlock(ex)) + + if(!Network.doPoll(_fd, timeout, Network.PollMode.Write)) { throw new Ice.TimeoutException(); } - throw new Ice.SocketException(ex); - } - catch(Ice.LocalException) - { - throw; - } - catch(System.Exception ex) - { - throw new Ice.SyscallException(ex); } + return true; } - - public void read(BasicStream stream, int timeout) + + public bool read(Buffer buf, int timeout) { - Debug.Assert(_fd != null); + int remaining = buf.b.remaining(); + int position = buf.b.position(); - ByteBuffer buf = stream.prepareRead(); - int remaining = buf.remaining(); - int position = buf.position(); - - try + while(buf.b.hasRemaining()) { - while(remaining > 0) + try { + Debug.Assert(_fd != null); + int ret; try { @@ -209,7 +168,7 @@ namespace IceInternal // Try to receive first. Much of the time, this will work and we // avoid the cost of calling Poll(). // - ret = _fd.Receive(buf.rawBytes(), position, remaining, SocketFlags.None); + ret = _fd.Receive(buf.b.rawBytes(), position, remaining, SocketFlags.None); if(ret == 0) { throw new Ice.ConnectionLostException(); @@ -219,47 +178,54 @@ namespace IceInternal { if(Network.wouldBlock(e)) { + if(timeout == 0) + { + return false; + } + if(!Network.doPoll(_fd, timeout, Network.PollMode.Read)) { throw new Ice.TimeoutException(); } + continue; } throw; } + + Debug.Assert(ret > 0); + if(_traceLevels.network >= 3) { string s = "received " + ret + " of " + remaining + " bytes via tcp\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } + if(_stats != null) { _stats.bytesReceived(type(), ret); } + remaining -= ret; - buf.position(position += ret); + buf.b.position(position += ret); } - } - catch(SocketException ex) - { - if(Network.connectionLost(ex)) + catch(Win32Exception ex) { - throw new Ice.ConnectionLostException(ex); - } - if(Network.wouldBlock(ex)) - { - throw new Ice.TimeoutException(); + if(Network.interrupted(ex)) + { + continue; + } + + if(Network.connectionLost(ex)) + { + throw new Ice.ConnectionLostException(ex); + } + + throw new Ice.SocketException(ex); } - throw new Ice.SocketException(ex); - } - catch(Ice.LocalException) - { - throw; - } - catch(System.Exception ex) - { - throw new Ice.SyscallException(ex); } + + return true; } public string type() @@ -267,32 +233,29 @@ namespace IceInternal return "tcp"; } - public void initialize(int timeout) + public override string ToString() { + return _desc; } - public void checkSendSize(BasicStream stream, int messageSizeMax) + public void checkSendSize(Buffer buf, int messageSizeMax) { - if(stream.size() > messageSizeMax) + if(buf.size() > messageSizeMax) { throw new Ice.MemoryLimitException(); } } - public override string ToString() - { - return _desc; - } - // // Only for use by TcpConnector, TcpAcceptor // - internal TcpTransceiver(Instance instance, Socket fd) + internal TcpTransceiver(Instance instance, Socket fd, bool connected) { _fd = fd; _traceLevels = instance.traceLevels(); _logger = instance.initializationData().logger; _stats = instance.initializationData().stats; + _state = connected ? StateConnected : StateNeedConnect; _desc = Network.fdToString(_fd); _maxPacketSize = 0; @@ -310,13 +273,100 @@ namespace IceInternal } } } - + + private bool writeBuffer(ByteBuffer buf) + { + int size = buf.limit(); + int packetSize = size - buf.position(); + if(_maxPacketSize > 0 && packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + buf.limit(buf.position() + packetSize); + } + + while(buf.hasRemaining()) + { + try + { + Debug.Assert(_fd != null); + + int ret; + try + { + // + // Try to send first. Most of the time, this will work and + // avoids the cost of calling Poll(). + // + ret = _fd.Send(buf.rawBytes(), buf.position(), buf.remaining(), SocketFlags.None); + } + catch(Win32Exception e) + { + if(Network.wouldBlock(e)) + { + // + // Writing would block, so we reset the limit (if necessary) and return true to indicate + // that more data must be sent. + // + if(packetSize == _maxPacketSize) + { + buf.limit(size); + } + return true; + } + throw; + } + + Debug.Assert(ret > 0); + + if(_traceLevels.network >= 3) + { + string s = "sent " + ret + " of " + buf.remaining() + " bytes via tcp\n" + ToString(); + _logger.trace(_traceLevels.networkCat, s); + } + + if(_stats != null) + { + _stats.bytesSent(type(), ret); + } + + buf.position(buf.position() + ret); + + if(packetSize == _maxPacketSize) + { + Debug.Assert(buf.position() == buf.limit()); + packetSize = size - buf.position(); + if(packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + } + buf.limit(buf.position() + packetSize); + } + } + catch(SocketException ex) + { + if(Network.connectionLost(ex)) + { + throw new Ice.ConnectionLostException(ex); + } + + throw new Ice.SocketException(ex); + } + } + + return false; // No more data to send. + } + private Socket _fd; private TraceLevels _traceLevels; private Ice.Logger _logger; private Ice.Stats _stats; private string _desc; + private int _state; private int _maxPacketSize; + + private const int StateNeedConnect = 0; + private const int StateConnectPending = 1; + private const int StateConnected = 2; } } diff --git a/cs/src/Ice/ThreadPool.cs b/cs/src/Ice/ThreadPool.cs index 140eff984d9..1d810f4fbd5 100644 --- a/cs/src/Ice/ThreadPool.cs +++ b/cs/src/Ice/ThreadPool.cs @@ -24,11 +24,17 @@ namespace IceInternal using System; using System.Collections; + using System.Collections.Generic; using System.Diagnostics; using System.Net.Sockets; using System.Threading; using IceUtil; + public interface ThreadPoolWorkItem + { + void execute(ThreadPool threadPool); + } + public sealed class ThreadPool { public ThreadPool(Instance instance, string prefix, int timeout) @@ -56,12 +62,12 @@ namespace IceInternal { _programNamePrefix = ""; } - + Network.SocketPair pair = Network.createPipe(); _fdIntrRead = pair.source; _fdIntrWrite = pair.sink; Network.setBlock(_fdIntrRead, false); - + // // We use just one thread as the default. This is the fastest // possible setting, still allows one level of nesting, and @@ -74,7 +80,7 @@ namespace IceInternal instance_.initializationData().logger.warning(s); size = 1; } - + int sizeMax = instance_.initializationData().properties.getPropertyAsIntWithDefault(_prefix + ".SizeMax", size); if(sizeMax < size) @@ -83,7 +89,7 @@ namespace IceInternal instance_.initializationData().logger.warning(s); sizeMax = size; } - + int sizeWarn = instance_.initializationData().properties.getPropertyAsIntWithDefault(_prefix + ".SizeWarn", sizeMax * 80 / 100); if(sizeWarn > sizeMax) @@ -97,7 +103,7 @@ namespace IceInternal size_ = size; sizeMax_ = sizeMax; sizeWarn_ = sizeWarn; - + try { threads_ = new ArrayList(); @@ -114,13 +120,13 @@ namespace IceInternal { string s = "cannot create thread for `" + _prefix + "':\n" + ex; instance_.initializationData().logger.error(s); - + destroy(); joinWithAllThreads(); throw; } } - + public void destroy() { lock(this) @@ -128,7 +134,7 @@ namespace IceInternal #if TRACE_SHUTDOWN trace("destroy"); #endif - + Debug.Assert(!_destroyed); Debug.Assert(_handlerMap.Count == 0); Debug.Assert(_changes.Count == 0); @@ -136,7 +142,7 @@ namespace IceInternal setInterrupt(); } } - + public void register(Socket fd, EventHandler handler) { lock(this) @@ -149,7 +155,7 @@ namespace IceInternal setInterrupt(); } } - + public void unregister(Socket fd) { lock(this) @@ -168,13 +174,23 @@ namespace IceInternal trace("removing handler for channel " + fd.Handle); #endif #endif - + Debug.Assert(!_destroyed); _changes.Add(new FdHandlerPair(fd, null)); setInterrupt(); } } - + + public void execute(ThreadPoolWorkItem workItem) + { + lock(this) + { + Debug.Assert(!_destroyed); + _workItems.AddLast(workItem); + setInterrupt(); + } + } + public void promoteFollower() { if(sizeMax_ > 1) @@ -184,12 +200,12 @@ namespace IceInternal Debug.Assert(!promote_); promote_ = true; System.Threading.Monitor.Pulse(this); - + if(!_destroyed) { Debug.Assert(inUse_ >= 0); ++inUse_; - + if(inUse_ == sizeWarn_) { string s = "thread pool `" + _prefix + "' is running low on threads\n" @@ -197,7 +213,7 @@ namespace IceInternal + "SizeWarn=" + sizeWarn_; instance_.initializationData().logger.warning(s); } - + Debug.Assert(inUse_ <= running_); if(inUse_ < sizeMax_ && inUse_ == running_) { @@ -219,7 +235,7 @@ namespace IceInternal } } } - + public void joinWithAllThreads() { // @@ -249,7 +265,7 @@ namespace IceInternal { } } - + public string prefix() { return _prefix; @@ -288,7 +304,7 @@ namespace IceInternal throw new Ice.SocketException(ex); } } - + private void setInterrupt() { #if TRACE_INTERRUPT @@ -342,12 +358,12 @@ namespace IceInternal promote_ = false; } - + #if TRACE_THREAD trace("thread " + System.Threading.Thread.CurrentThread.Name + " has the lock"); #endif } - + while(true) { #if TRACE_REGISTRATION @@ -358,7 +374,7 @@ namespace IceInternal trace(", " + socket.Handle); } #endif - + ArrayList readList = new ArrayList(_handlerMap.Count + 1); readList.Add(_fdIntrRead); readList.AddRange(_handlerMap.Keys); @@ -366,6 +382,7 @@ namespace IceInternal Network.doSelect(readList, null, null, _timeout > 0 ? _timeout * 1000 : -1); EventHandler handler = null; + ThreadPoolWorkItem workItem = null; bool finished = false; bool shutdown = false; @@ -376,7 +393,7 @@ namespace IceInternal #if TRACE_SELECT trace("timeout"); #endif - + Debug.Assert(_timeout > 0); _timeout = 0; shutdown = true; @@ -388,15 +405,17 @@ namespace IceInternal #if TRACE_SELECT || TRACE_INTERRUPT trace("detected interrupt"); #endif - + // - // There are two possibilities for an interrupt: + // There are three possibilities for an interrupt: // // 1. The thread pool has been destroyed. // // 2. An event handler was registered or unregistered. // - + // 3. A work item has been scheduled. + // + // // Thread pool destroyed? // @@ -405,7 +424,7 @@ namespace IceInternal #if TRACE_SHUTDOWN trace("destroyed, thread id = " + System.Threading.Thread.CurrentThread.Name); #endif - + // // Don't clear the interrupt fd if // destroyed, so that the other threads @@ -413,7 +432,7 @@ namespace IceInternal // return true; } - + // // Remove the interrupt channel from the // readList. @@ -421,41 +440,49 @@ namespace IceInternal readList.Remove(_fdIntrRead); clearInterrupt(); - + // // An event handler must have been registered // or unregistered. // - Debug.Assert(_changes.Count != 0); - LinkedList.Enumerator first = (LinkedList.Enumerator)_changes.GetEnumerator(); - first.MoveNext(); - FdHandlerPair change = (FdHandlerPair)first.Current; - first.Remove(); - if(change.handler != null) // Addition if handler is set. + if(_changes.Count > 0) { - _handlerMap[change.fd] = change.handler; - - #if TRACE_REGISTRATION - trace("added handler (" + change.handler.GetType().FullName + ") for fd " - + change.fd.Handle); - #endif - - continue; + LinkedList.Enumerator first = (LinkedList.Enumerator)_changes.GetEnumerator(); + first.MoveNext(); + FdHandlerPair change = (FdHandlerPair)first.Current; + first.Remove(); + if(change.handler != null) // Addition if handler is set. + { + _handlerMap[change.fd] = change.handler; + + #if TRACE_REGISTRATION + trace("added handler (" + change.handler.GetType().FullName + ") for fd " + + change.fd.Handle); + #endif + + continue; + } + else // Removal if handler is not set. + { + handler = (EventHandler)_handlerMap[change.fd]; + _handlerMap.Remove(change.fd); + finished = true; + + #if TRACE_REGISTRATION + trace("removed handler (" + handler.GetType().FullName + ") for fd " + + change.fd.Handle); + #endif + + // Don't continue; we have to call + // finished() on the event handler below, + // outside the thread synchronization. + } } - else // Removal if handler is not set. + else { - handler = (EventHandler)_handlerMap[change.fd]; - _handlerMap.Remove(change.fd); - finished = true; - - #if TRACE_REGISTRATION - trace("removed handler (" + handler.GetType().FullName + ") for fd " - + change.fd.Handle); - #endif - - // Don't continue; we have to call - // finished() on the event handler below, - // outside the thread synchronization. + Debug.Assert(_workItems.Count > 0); + workItem = _workItems.First.Value; + _workItems.RemoveFirst(); } } else @@ -465,13 +492,13 @@ namespace IceInternal trace("found a readable socket: " + fd.Handle); #endif handler = (EventHandler)_handlerMap[fd]; - + if(handler == null) { #if TRACE_SELECT trace("socket " + fd.Handle + " not registered with " + _prefix); #endif - + continue; } } @@ -481,13 +508,13 @@ namespace IceInternal // // Now we are outside the thread synchronization. // - + if(shutdown) { #if TRACE_SHUTDOWN trace("shutdown detected"); #endif - + // // Initiate server shutdown. // @@ -500,7 +527,7 @@ namespace IceInternal { continue; } - + promoteFollower(); factory.shutdown(); @@ -510,6 +537,24 @@ namespace IceInternal // promoteFollower(); // } + else if(workItem != null) + { + try + { + workItem.execute(this); + } + catch(Ice.LocalException ex) + { + string s = "exception in `" + _prefix + "' while calling execute():\n" + ex; + instance_.initializationData().logger.error(s); + } + + // + // No "continue", because we want shutdown to be done in + // its own thread from this pool. Therefore we called + // promoteFollower(); + // + } else { Debug.Assert(handler != null); @@ -550,10 +595,14 @@ namespace IceInternal { try { - read(handler); + if(!read(handler)) + { + continue; // Can't read without blocking. + } } - catch(Ice.TimeoutException) // Expected. + catch(Ice.TimeoutException) { + Debug.Assert(false); // This shouldn't occur as we only perform non-blocking reads. continue; } catch(Ice.DatagramLimitException) // Expected. @@ -566,7 +615,7 @@ namespace IceInternal trace("informing handler (" + handler.GetType().FullName + ") about " + ex.GetType().FullName + " exception " + ex); #endif - + handler.exception(ex); continue; } @@ -588,16 +637,16 @@ namespace IceInternal trace("informing handler (" + handler.GetType().FullName + ") about " + ex.GetType().FullName + " exception " + ex); #endif - + handler.exception(ex); } continue; } - + stream.swap(handler.stream_); Debug.Assert(stream.pos() == stream.size()); } - + // // Provide a new message to the handler. // @@ -624,7 +673,7 @@ namespace IceInternal } } } - + if(sizeMax_ > 1) { lock(this) @@ -653,7 +702,7 @@ namespace IceInternal } threads_ = liveThreads; } - + // // Now we check if this thread can be destroyed, based // on a load factor. @@ -692,49 +741,52 @@ namespace IceInternal { Debug.Assert(inUse_ > 0); --inUse_; - + Debug.Assert(running_ > 0); --running_; - + return false; } } - + Debug.Assert(inUse_ > 0); --inUse_; } - + while(!promote_) { System.Threading.Monitor.Wait(this); } - + promote_ = false; } - + #if TRACE_THREAD trace("thread " + System.Threading.Thread.CurrentThread.Name + " has the lock"); #endif } } } - - private void read(EventHandler handler) + + private bool read(EventHandler handler) { BasicStream stream = handler.stream_; - + if(stream.size() == 0) { stream.resize(Protocol.headerSize, true); stream.pos(0); } - + if(stream.pos() != stream.size()) { - handler.read(stream); + if(!handler.read(stream)) + { + return false; + } Debug.Assert(stream.pos() == stream.size()); } - + int pos = stream.pos(); if(pos < Protocol.headerSize) { @@ -756,7 +808,7 @@ namespace IceInternal ex.badMagic = m; throw ex; } - + byte pMajor = stream.readByte(); byte pMinor = stream.readByte(); if(pMajor != Protocol.protocolMajor || pMinor > Protocol.protocolMinor) @@ -768,7 +820,7 @@ namespace IceInternal e.minor = Protocol.protocolMinor; throw e; } - + byte eMajor = stream.readByte(); byte eMinor = stream.readByte(); if(eMajor != Protocol.encodingMajor || eMinor > Protocol.encodingMinor) @@ -780,7 +832,7 @@ namespace IceInternal e.minor = Protocol.encodingMinor; throw e; } - + stream.readByte(); // Message type. stream.readByte(); // Compression status. int size = stream.readInt(); @@ -797,7 +849,7 @@ namespace IceInternal stream.resize(size, true); } stream.pos(pos); - + if(stream.pos() != stream.size()) { if(handler.datagram()) @@ -813,12 +865,17 @@ namespace IceInternal } else { - handler.read(stream); + if(!handler.read(stream)) + { + return false; + } Debug.Assert(stream.pos() == stream.size()); } } + + return true; } - + /* * Commented out because it is unused. * @@ -830,12 +887,12 @@ namespace IceInternal trace("non-blocking select on " + _handlerMap.Count + " sockets, thread id = " + System.Threading.Thread.CurrentThread.Name); #endif - + ArrayList readList = new ArrayList(_handlerMap.Count + 1); readList.Add(_fdIntrRead); readList.AddRange(_handlerMap.Keys); Network.doSelect(readList, null, null, 0); - + #if TRACE_SELECT if(readList.Count > 0) { @@ -846,12 +903,12 @@ namespace IceInternal } } #endif - + break; } } */ - + /* * Commented out because it is unused. * @@ -860,41 +917,42 @@ namespace IceInternal System.Console.Error.WriteLine(_prefix + "(" + System.Threading.Thread.CurrentThread.Name + "): " + msg); } */ - + private sealed class FdHandlerPair { internal Socket fd; internal EventHandler handler; - + internal FdHandlerPair(Socket fd, EventHandler handler) { this.fd = fd; this.handler = handler; } } - + private Instance instance_; private bool _destroyed; private readonly string _prefix; private readonly string _programNamePrefix; - + private Socket _fdIntrRead; private Socket _fdIntrWrite; - + private IceUtil.LinkedList _changes = new IceUtil.LinkedList(); - + private LinkedList<ThreadPoolWorkItem> _workItems = new LinkedList<ThreadPoolWorkItem>(); + private Hashtable _handlerMap = new Hashtable(); - + private int _timeout; - + private sealed class EventHandlerThread { - private ThreadPool thread_Pool; + private ThreadPool threadPool_; internal EventHandlerThread(ThreadPool threadPool, string name) : base() { - thread_Pool = threadPool; + threadPool_ = threadPool; name_ = name; } @@ -918,72 +976,72 @@ namespace IceInternal public void Run() { - if(thread_Pool.instance_.initializationData().threadHook != null) + if(threadPool_.instance_.initializationData().threadHook != null) { - thread_Pool.instance_.initializationData().threadHook.start(); + threadPool_.instance_.initializationData().threadHook.start(); } - BasicStream stream = new BasicStream(thread_Pool.instance_); - + BasicStream stream = new BasicStream(threadPool_.instance_); + bool promote; - + try { - promote = thread_Pool.run(stream); + promote = threadPool_.run(stream); } catch(Ice.LocalException ex) { - string s = "exception in `" + thread_Pool._prefix + "' thread " + thread_.Name + ":\n" + ex; - thread_Pool.instance_.initializationData().logger.error(s); + string s = "exception in `" + threadPool_._prefix + "' thread " + thread_.Name + ":\n" + ex; + threadPool_.instance_.initializationData().logger.error(s); promote = true; } catch(System.Exception ex) { - string s = "unknown exception in `" + thread_Pool._prefix + "' thread " + thread_.Name + ":\n" + ex; - thread_Pool.instance_.initializationData().logger.error(s); + string s = "unknown exception in `" + threadPool_._prefix + "' thread " + thread_.Name + ":\n" + ex; + threadPool_.instance_.initializationData().logger.error(s); promote = true; } - - if(promote && thread_Pool.sizeMax_ > 1) + + if(promote && threadPool_.sizeMax_ > 1) { // // Promote a follower, but w/o modifying inUse_ or // creating new threads. // - lock(thread_Pool) + lock(threadPool_) { - Debug.Assert(!thread_Pool.promote_); - thread_Pool.promote_ = true; - System.Threading.Monitor.Pulse(thread_Pool); + Debug.Assert(!threadPool_.promote_); + threadPool_.promote_ = true; + System.Threading.Monitor.Pulse(threadPool_); } } - if(thread_Pool.instance_.initializationData().threadHook != null) + if(threadPool_.instance_.initializationData().threadHook != null) { - thread_Pool.instance_.initializationData().threadHook.stop(); + threadPool_.instance_.initializationData().threadHook.stop(); } - + #if TRACE_THREAD - thread_Pool.trace("run() terminated"); + threadPool_.trace("run() terminated"); #endif } private string name_; private Thread thread_; } - + private readonly int size_; // Number of threads that are pre-created. private readonly int sizeMax_; // Maximum number of threads. private readonly int sizeWarn_; // If inUse_ reaches sizeWarn_, a "low on threads" warning will be printed. - + private ArrayList threads_; // All threads, running or not. private int threadIndex_; // For assigning thread names. private int running_; // Number of running threads. private int inUse_; // Number of threads that are currently in use. private double load_; // Current load in number of threads. - + private bool promote_; - + private readonly bool warnUdp_; } diff --git a/cs/src/Ice/Timer.cs b/cs/src/Ice/Timer.cs index 610dfc1acf0..1587c7b8ad7 100644 --- a/cs/src/Ice/Timer.cs +++ b/cs/src/Ice/Timer.cs @@ -15,8 +15,8 @@ namespace IceInternal public interface TimerTask { - void run(); - }; + void runTimerTask(); + } public sealed class Timer { @@ -39,7 +39,6 @@ namespace IceInternal _thread.Join(); } - public void schedule(TimerTask task, long delay) { lock(this) @@ -212,7 +211,7 @@ namespace IceInternal { try { - token.task.run(); + token.task.runTimerTask(); } catch(System.Exception ex) { diff --git a/cs/src/Ice/TraceUtil.cs b/cs/src/Ice/TraceUtil.cs index 31b6522f9be..cbe38904327 100644 --- a/cs/src/Ice/TraceUtil.cs +++ b/cs/src/Ice/TraceUtil.cs @@ -16,198 +16,60 @@ namespace IceInternal sealed class TraceUtil { - internal static void traceHeader(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) - { - if(tl.protocol >= 1) - { - int p = str.pos(); - str.pos(0); - - using(System.IO.StringWriter s = new System.IO.StringWriter()) - { - s.Write(heading); - printHeader(s, str); - - logger.trace(tl.protocolCat, s.ToString()); - } - str.pos(p); - } - } - - internal static void traceRequest(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + internal static void traceSend(BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { int p = str.pos(); str.pos(0); - + using(System.IO.StringWriter s = new System.IO.StringWriter()) { - s.Write(heading); - printHeader(s, str); - - int requestId = str.readInt(); - s.Write("\nrequest id = " + requestId); - if(requestId == 0) - { - s.Write(" (oneway)"); - } - - printRequestHeader(s, str); - - logger.trace(tl.protocolCat, s.ToString()); + byte type = printMessage(s, str); + + logger.trace(tl.protocolCat, "sending " + getMessageTypeAsString(type) + " " + s.ToString()); } str.pos(p); } } - - internal static void traceBatchRequest(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + + internal static void traceRecv(BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { int p = str.pos(); str.pos(0); - + using(System.IO.StringWriter s = new System.IO.StringWriter()) { - s.Write(heading); - printHeader(s, str); - - int batchRequestNum = str.readInt(); - s.Write("\nnumber of requests = " + batchRequestNum); - - for(int i = 0; i < batchRequestNum; ++i) - { - s.Write("\nrequest #" + i + ':'); - printRequestHeader(s, str); - str.skipEncaps(); - } - - logger.trace(tl.protocolCat, s.ToString()); + byte type = printMessage(s, str); + + logger.trace(tl.protocolCat, "received " + getMessageTypeAsString(type) + " " + s.ToString()); } str.pos(p); } } - - internal static void traceReply(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + + internal static void trace(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { int p = str.pos(); str.pos(0); - + using(System.IO.StringWriter s = new System.IO.StringWriter()) { s.Write(heading); - printHeader(s, str); - - int requestId = str.readInt(); - s.Write("\nrequest id = " + requestId); - - byte replyStatus = str.readByte(); - s.Write("\nreply status = " + (int)replyStatus + ' '); - - switch(replyStatus) - { - case ReplyStatus.replyOK: - { - s.Write("(ok)"); - break; - } - - case ReplyStatus.replyUserException: - { - s.Write("(user exception)"); - break; - } - - case ReplyStatus.replyObjectNotExist: - case ReplyStatus.replyFacetNotExist: - case ReplyStatus.replyOperationNotExist: - { - switch(replyStatus) - { - case ReplyStatus.replyObjectNotExist: - { - s.Write("(object not exist)"); - break; - } - - case ReplyStatus.replyFacetNotExist: - { - s.Write("(facet not exist)"); - break; - } - - case ReplyStatus.replyOperationNotExist: - { - s.Write("(operation not exist)"); - break; - } - - default: - { - Debug.Assert(false); - break; - } - } - - printIdentityFacetOperation(s, str); - break; - } - - case ReplyStatus.replyUnknownException: - case ReplyStatus.replyUnknownLocalException: - case ReplyStatus.replyUnknownUserException: - { - switch(replyStatus) - { - case ReplyStatus.replyUnknownException: - { - s.Write("(unknown exception)"); - break; - } - - case ReplyStatus.replyUnknownLocalException: - { - s.Write("(unknown local exception)"); - break; - } - - case ReplyStatus.replyUnknownUserException: - { - s.Write("(unknown user exception)"); - break; - } - - default: - { - Debug.Assert(false); - break; - } - } - - string unknown = str.readString(); - s.Write("\nunknown = " + unknown); - break; - } - - default: - { - s.Write("(unknown)"); - break; - } - - } - + printMessage(s, str); + logger.trace(tl.protocolCat, s.ToString()); } str.pos(p); } } - + private static Set slicingIds; - + internal static void traceSlicing(string kind, string typeId, string slicingCat, Ice.Logger logger) { lock(typeof(IceInternal.TraceUtil)) @@ -222,23 +84,23 @@ namespace IceInternal } } } - + public static void dumpStream(BasicStream stream) { int pos = stream.pos(); stream.pos(0); - + byte[] data = new byte[stream.size()]; stream.readBlob(data); dumpOctets(data); - + stream.pos(pos); } - + public static void dumpOctets(byte[] data) { const int inc = 8; - + for(int i = 0; i < data.Length; i += inc) { for(int j = i; j - i < inc; j++) @@ -270,9 +132,9 @@ namespace IceInternal System.Console.Out.Write(" "); } } - + System.Console.Out.Write('"'); - + for(int j = i; j < data.Length && j - i < inc; j++) { // TODO: this needs fixing @@ -285,80 +147,206 @@ namespace IceInternal System.Console.Out.Write('.'); } } - + System.Console.Out.WriteLine('"'); } } - - private static void printIdentityFacetOperation(System.IO.StringWriter o, BasicStream stream) + + private static void printIdentityFacetOperation(System.IO.StringWriter s, BasicStream str) { try { Ice.Identity identity = new Ice.Identity(); - identity.read__(stream); - o.Write("\nidentity = " + stream.instance().identityToString(identity)); - - string[] facet = stream.readStringSeq(); - o.Write("\nfacet = "); + identity.read__(str); + s.Write("\nidentity = " + str.instance().identityToString(identity)); + + string[] facet = str.readStringSeq(); + s.Write("\nfacet = "); if(facet.Length > 0) { - o.Write(IceUtil.StringUtil.escapeString(facet[0], "")); + s.Write(IceUtil.StringUtil.escapeString(facet[0], "")); } - - string operation = stream.readString(); - o.Write("\noperation = " + operation); + + string operation = str.readString(); + s.Write("\noperation = " + operation); } catch(System.IO.IOException) { Debug.Assert(false); } } - - private static void printRequestHeader(System.IO.StringWriter o, BasicStream stream) + + private static void printRequest(System.IO.StringWriter s, BasicStream str) + { + int requestId = str.readInt(); + s.Write("\nrequest id = " + requestId); + if(requestId == 0) + { + s.Write(" (oneway)"); + } + + printRequestHeader(s, str); + } + + private static void printBatchRequest(System.IO.StringWriter s, BasicStream str) + { + int batchRequestNum = str.readInt(); + s.Write("\nnumber of requests = " + batchRequestNum); + + for(int i = 0; i < batchRequestNum; ++i) + { + s.Write("\nrequest #" + i + ':'); + printRequestHeader(s, str); + str.skipEncaps(); + } + } + + private static void printReply(System.IO.StringWriter s, BasicStream str) + { + int requestId = str.readInt(); + s.Write("\nrequest id = " + requestId); + + byte replyStatus = str.readByte(); + s.Write("\nreply status = " + (int)replyStatus + ' '); + + switch(replyStatus) + { + case ReplyStatus.replyOK: + { + s.Write("(ok)"); + break; + } + + case ReplyStatus.replyUserException: + { + s.Write("(user exception)"); + break; + } + + case ReplyStatus.replyObjectNotExist: + case ReplyStatus.replyFacetNotExist: + case ReplyStatus.replyOperationNotExist: + { + switch(replyStatus) + { + case ReplyStatus.replyObjectNotExist: + { + s.Write("(object not exist)"); + break; + } + + case ReplyStatus.replyFacetNotExist: + { + s.Write("(facet not exist)"); + break; + } + + case ReplyStatus.replyOperationNotExist: + { + s.Write("(operation not exist)"); + break; + } + + default: + { + Debug.Assert(false); + break; + } + } + + printIdentityFacetOperation(s, str); + break; + } + + case ReplyStatus.replyUnknownException: + case ReplyStatus.replyUnknownLocalException: + case ReplyStatus.replyUnknownUserException: + { + switch(replyStatus) + { + case ReplyStatus.replyUnknownException: + { + s.Write("(unknown exception)"); + break; + } + + case ReplyStatus.replyUnknownLocalException: + { + s.Write("(unknown local exception)"); + break; + } + + case ReplyStatus.replyUnknownUserException: + { + s.Write("(unknown user exception)"); + break; + } + + default: + { + Debug.Assert(false); + break; + } + } + + string unknown = str.readString(); + s.Write("\nunknown = " + unknown); + break; + } + + default: + { + s.Write("(unknown)"); + break; + } + } + } + + private static void printRequestHeader(System.IO.StringWriter s, BasicStream str) { - printIdentityFacetOperation(o, stream); - + printIdentityFacetOperation(s, str); + try { - byte mode = stream.readByte(); - o.Write("\nmode = " + (int)mode + ' '); + byte mode = str.readByte(); + s.Write("\nmode = " + (int)mode + ' '); switch((Ice.OperationMode)mode) { - case Ice.OperationMode.Normal: - { - o.Write("(normal)"); - break; - } - - case Ice.OperationMode.Nonmutating: - { - o.Write("(nonmutating)"); - break; - } - - case Ice.OperationMode.Idempotent: - { - o.Write("(idempotent)"); - break; - } - - default: - { - o.Write("(unknown)"); - break; - } + case Ice.OperationMode.Normal: + { + s.Write("(normal)"); + break; + } + + case Ice.OperationMode.Nonmutating: + { + s.Write("(nonmutating)"); + break; + } + + case Ice.OperationMode.Idempotent: + { + s.Write("(idempotent)"); + break; + } + + default: + { + s.Write("(unknown)"); + break; + } } - - int sz = stream.readSize(); - o.Write("\ncontext = "); + + int sz = str.readSize(); + s.Write("\ncontext = "); while(sz-- > 0) { - string key = stream.readString(); - string val = stream.readString(); - o.Write(key + '/' + val); + string key = str.readString(); + string val = str.readString(); + s.Write(key + '/' + val); if(sz > 0) { - o.Write(", "); + s.Write(", "); } } } @@ -367,100 +355,142 @@ namespace IceInternal Debug.Assert(false); } } - - private static void printHeader(System.IO.StringWriter o, BasicStream stream) + + private static byte printHeader(System.IO.StringWriter s, BasicStream str) { try { - stream.readByte(); // Don't bother printing the magic number - stream.readByte(); - stream.readByte(); - stream.readByte(); - - /* byte pMajor = */ stream.readByte(); - /* byte pMinor = */ stream.readByte(); - //o.Write("\nprotocol version = " + (int)pMajor + "." + (int)pMinor); - - /* byte eMajor = */ stream.readByte(); - /* byte eMinor = */ stream.readByte(); - //o.Write("\nencoding version = " + (int)eMajor + "." + (int)eMinor); - - byte type = stream.readByte(); - o.Write("\nmessage type = " + (int)type + ' '); - switch(type) + str.readByte(); // Don't bother printing the magic number + str.readByte(); + str.readByte(); + str.readByte(); + + /* byte pMajor = */ str.readByte(); + /* byte pMinor = */ str.readByte(); + //s.Write("\nprotocol version = " + (int)pMajor + "." + (int)pMinor); + + /* byte eMajor = */ str.readByte(); + /* byte eMinor = */ str.readByte(); + //s.Write("\nencoding version = " + (int)eMajor + "." + (int)eMinor); + + byte type = str.readByte(); + s.Write("\nmessage type = " + (int)type + " (" + getMessageTypeAsString(type) + ')'); + + byte compress = str.readByte(); + s.Write("\ncompression status = " + (int)compress + ' '); + switch(compress) { - case Protocol.requestMsg: - { - o.Write("(request)"); - break; - } - - case Protocol.requestBatchMsg: - { - o.Write("(batch request)"); - break; - } - - case Protocol.replyMsg: - { - o.Write("(reply)"); - break; - } - - case Protocol.closeConnectionMsg: - { - o.Write("(close connection)"); - break; - } - - case Protocol.validateConnectionMsg: - { - o.Write("(validate connection)"); - break; - } - - default: - { - o.Write("(unknown)"); - break; - } + case (byte)0: + { + s.Write("(not compressed; do not compress response, if any)"); + break; } - - byte compress = stream.readByte(); - o.Write("\ncompression status = " + (int)compress + ' '); - switch(compress) + + case (byte)1: { - case (byte)0: - { - o.Write("(not compressed; do not compress response, if any)"); - break; - } - - case (byte)1: - { - o.Write("(not compressed; compress response, if any)"); - break; - } - - case (byte)2: - { - o.Write("(compressed; compress response, if any)"); - break; - } - - default: - { - o.Write("(unknown)"); - break; - } + s.Write("(not compressed; compress response, if any)"); + break; + } + + case (byte)2: + { + s.Write("(compressed; compress response, if any)"); + break; } - - int size = stream.readInt(); - o.Write("\nmessage size = " + size); + + default: + { + s.Write("(unknown)"); + break; + } + } + + int size = str.readInt(); + s.Write("\nmessage size = " + size); + return type; } catch(System.IO.IOException) { Debug.Assert(false); + return 0; + } + } + + private static byte printMessage(System.IO.StringWriter s, BasicStream str) + { + byte type = printHeader(s, str); + + switch(type) + { + case Protocol.closeConnectionMsg: + case Protocol.validateConnectionMsg: + { + // We're done. + break; + } + + case Protocol.requestMsg: + { + printRequest(s, str); + break; + } + + case Protocol.requestBatchMsg: + { + printBatchRequest(s, str); + break; + } + + case Protocol.replyMsg: + { + printReply(s, str); + break; + } + + default: + { + s.Write("(unknown)"); + break; + } + } + + return type; + } + + internal static void traceHeader(string heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + { + if(tl.protocol >= 1) + { + int p = str.pos(); + str.pos(0); + + using(System.IO.StringWriter s = new System.IO.StringWriter()) + { + s.Write(heading); + printHeader(s, str); + + logger.trace(tl.protocolCat, s.ToString()); + } + str.pos(p); + } + } + + private static string getMessageTypeAsString(byte type) + { + switch(type) + { + case Protocol.requestMsg: + return "request"; + case Protocol.requestBatchMsg: + return "batch request"; + case Protocol.replyMsg: + return "reply"; + case Protocol.closeConnectionMsg: + return "close connection"; + case Protocol.validateConnectionMsg: + return "validate connection"; + default: + return "unknown"; } } diff --git a/cs/src/Ice/Transceiver.cs b/cs/src/Ice/Transceiver.cs index 17437890810..d7f2732ce7b 100644 --- a/cs/src/Ice/Transceiver.cs +++ b/cs/src/Ice/Transceiver.cs @@ -13,14 +13,50 @@ namespace IceInternal public interface Transceiver { System.Net.Sockets.Socket fd(); + + // + // Initialize the transceiver. + // + // Returns the status if the initialize operation. If timeout is != 0, + // the status will always be SocketStatus.Finished. If timeout is 0, + // the operation won't block and will return SocketStatus.NeedRead or + // SocketStatus.NeedWrite if the initialization couldn't be completed + // without blocking. This operation should be called again once the + // socket is ready for reading or writing and until it returns + // SocketStatus.Finished. + // + SocketStatus initialize(int timeout); + void close(); void shutdownWrite(); void shutdownReadWrite(); - void write(BasicStream stream, int timeout); - void read(BasicStream stream, int timeout); + + // + // Write data. + // + // Returns true if all the data was written, false otherwise. If + // timeout is -1, this operation will block until all the data is + // written. If timeout is 0, it will return when the write can't + // be completed without blocking. If the timeout is > 0, it will + // block until all the data is written or the specified timeout + // expires. + // + bool write(Buffer buf, int timeout); + + // + // Read data. + // + // Returns true if all the requested data was read, false otherwise. + // If timeout is -1, this operation will block until all the data + // is read. If timeout is 0, it will return when the read can't be + // completed without blocking. If the timeout is > 0, it will + // block until all the data is read or the specified timeout + // expires. + // + bool read(Buffer buf, int timeout); + string type(); - void initialize(int timeout); - void checkSendSize(BasicStream stream, int messageSizeMax); + void checkSendSize(Buffer buf, int messageSizeMax); } } diff --git a/cs/src/Ice/UdpConnector.cs b/cs/src/Ice/UdpConnector.cs index d74f6455076..1287cd9a634 100644 --- a/cs/src/Ice/UdpConnector.cs +++ b/cs/src/Ice/UdpConnector.cs @@ -11,11 +11,10 @@ namespace IceInternal { using System.Diagnostics; using System.Net; + using System.Net.Sockets; sealed class UdpConnector : Connector, System.IComparable { - internal const short TYPE = 3; - public Transceiver connect(int timeout) { return new UdpTransceiver(instance_, _addr, _mcastInterface, _mcastTtl); @@ -23,62 +22,7 @@ namespace IceInternal public short type() { - return TYPE; - } - - public override string ToString() - { - return Network.addrToString(_addr); - } - - internal bool equivalent(string host, int port) - { - IPEndPoint addr; - try - { - addr = Network.getAddress(host, port); - } - catch(Ice.DNSException) - { - return false; - } - return addr.Equals(_addr); - } - - // - // Only for use by TcpEndpoint - // - internal UdpConnector(Instance instance, IPEndPoint addr, string mcastInterface, int mcastTtl, - byte protocolMajor, byte protocolMinor, byte encodingMajor, byte encodingMinor, - string connectionId) - { - instance_ = instance; - _addr = addr; - _mcastInterface = mcastInterface; - _mcastTtl = mcastTtl; - _protocolMajor = protocolMajor; - _protocolMinor = protocolMinor; - _encodingMajor = encodingMajor; - _encodingMinor = encodingMinor; - _connectionId = connectionId; - - _hashCode = _addr.GetHashCode(); - _hashCode = 5 * _hashCode + _mcastInterface.GetHashCode(); - _hashCode = 5 * _hashCode + _mcastTtl.GetHashCode(); - _hashCode = 5 * _hashCode + _connectionId.GetHashCode(); - } - - public override int GetHashCode() - { - return _hashCode; - } - - // - // Compare endpoints for sorting purposes - // - public override bool Equals(object obj) - { - return CompareTo(obj) == 0; + return UdpEndpointI.TYPE; } public int CompareTo(object obj) @@ -166,6 +110,44 @@ namespace IceInternal return Network.compareAddress(_addr, p._addr); } + // + // Only for use by TcpEndpoint + // + internal UdpConnector(Instance instance, IPEndPoint addr, string mcastInterface, int mcastTtl, + byte protocolMajor, byte protocolMinor, byte encodingMajor, byte encodingMinor, + string connectionId) + { + instance_ = instance; + _addr = addr; + _mcastInterface = mcastInterface; + _mcastTtl = mcastTtl; + _protocolMajor = protocolMajor; + _protocolMinor = protocolMinor; + _encodingMajor = encodingMajor; + _encodingMinor = encodingMinor; + _connectionId = connectionId; + + _hashCode = _addr.GetHashCode(); + _hashCode = 5 * _hashCode + _mcastInterface.GetHashCode(); + _hashCode = 5 * _hashCode + _mcastTtl.GetHashCode(); + _hashCode = 5 * _hashCode + _connectionId.GetHashCode(); + } + + public override bool Equals(object obj) + { + return CompareTo(obj) == 0; + } + + public override string ToString() + { + return Network.addrToString(_addr); + } + + public override int GetHashCode() + { + return _hashCode; + } + private Instance instance_; private IPEndPoint _addr; private string _mcastInterface; @@ -176,7 +158,5 @@ namespace IceInternal private byte _encodingMinor; private string _connectionId; private int _hashCode; - } - } diff --git a/cs/src/Ice/UdpEndpointI.cs b/cs/src/Ice/UdpEndpointI.cs index bf9572472d2..1a0e08a426b 100644 --- a/cs/src/Ice/UdpEndpointI.cs +++ b/cs/src/Ice/UdpEndpointI.cs @@ -12,6 +12,8 @@ namespace IceInternal using System.Diagnostics; using System.Collections; + using System.Collections.Generic; + using System.Net; sealed class UdpEndpointI : EndpointI { @@ -524,23 +526,21 @@ namespace IceInternal _connectionId, _compress); return p; } - + // // Return a connector for this endpoint, or empty list if no connector // is available. // - public override ArrayList connectors() + public override List<Connector> connectors() { - ArrayList connectors = new ArrayList(); - System.Net.IPEndPoint[] addresses = Network.getAddresses(_host, _port); - for(int i = 0; i < addresses.Length; ++i) - { - connectors.Add(new UdpConnector(instance_, addresses[i], _mcastInterface, _mcastTtl, _protocolMajor, - _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); - } - return connectors; + return connectors(Network.getAddresses(_host, _port)); } - + + public override void connectors_async(EndpointI_connectors callback) + { + instance_.endpointHostResolver().resolve(_host, _port, this, callback); + } + // // Return an acceptor for this endpoint, or null if no acceptors // is available. In case an acceptor is created, this operation @@ -558,10 +558,10 @@ namespace IceInternal // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public override ArrayList + public override List<EndpointI> expand() { - ArrayList endps = new ArrayList(); + List<EndpointI> endps = new List<EndpointI>(); if(_host.Equals("0.0.0.0")) { string[] hosts = Network.getLocalHosts(); @@ -583,20 +583,20 @@ namespace IceInternal } // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - public override bool equivalent(Connector connector) + public override bool equivalent(EndpointI endpoint) { - UdpConnector udpConnector = null; + UdpEndpointI udpEndpointI = null; try { - udpConnector = (UdpConnector)connector; + udpEndpointI = (UdpEndpointI)endpoint; } catch(System.InvalidCastException) { return false; } - return udpConnector.equivalent(_host, _port); + return udpEndpointI._host.Equals(_host) && udpEndpointI._port == _port; } public override bool requiresThreadPerConnection() @@ -604,6 +604,17 @@ namespace IceInternal return false; } + public override List<Connector> connectors(List<IPEndPoint> addresses) + { + List<Connector> connectors = new List<Connector>(); + foreach(IPEndPoint addr in addresses) + { + connectors.Add(new UdpConnector(instance_, addr, _mcastInterface, _mcastTtl, _protocolMajor, + _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); + } + return connectors; + } + public override int GetHashCode() { return _hashCode; diff --git a/cs/src/Ice/UdpTransceiver.cs b/cs/src/Ice/UdpTransceiver.cs index a0e8a6ef089..e3514800ef0 100644 --- a/cs/src/Ice/UdpTransceiver.cs +++ b/cs/src/Ice/UdpTransceiver.cs @@ -24,7 +24,15 @@ namespace IceInternal Debug.Assert(_fd != null); return _fd; } - + + public SocketStatus initialize(int timeout) + { + // + // Nothing to do. + // + return SocketStatus.Finished; + } + public void close() { lock(this) @@ -34,7 +42,7 @@ namespace IceInternal string s = "closing udp connection\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } - + if(_fd != null) { try @@ -76,248 +84,254 @@ namespace IceInternal } catch(SocketException ex) { - if(Network.notConnected(ex)) + if(!Network.notConnected(ex)) { - return; + throw new Ice.SocketException(ex); } - throw new Ice.SocketException(ex); } - if(AssemblyUtil.platform_ == AssemblyUtil.Platform.Windows) - { - // - // On Windows, shutting down the socket doesn't unblock a call to - // receive or select. Setting an event wakes up the thread in - // read(). - // - _shutdownReadWriteEvent.Set(); - } - } - } - - public void write(BasicStream stream, int timeout) - { - Debug.Assert(_fd != null); - - ByteBuffer buf = stream.prepareWrite(); - - Debug.Assert(buf.position() == 0); - int packetSize = System.Math.Min(_maxPacketSize, _sndSize - _udpOverhead); - if(packetSize < buf.limit()) - { // - // We don't log a warning here because the client gets an exception anyway. + // On Windows and Mac OS X, shutting down the socket doesn't unblock a call to + // receive or select. Setting an event wakes up the thread in read(). // - throw new Ice.DatagramLimitException(); - } - - try - { - int remaining = buf.remaining(); - int ret; - try - { - ret = _fd.Send(buf.rawBytes(), 0, remaining, SocketFlags.None); - } - catch(Win32Exception e) - { - if(Network.wouldBlock(e)) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - ret = 0; - } - else - { - throw; - } - } - if(ret == 0) - { - if(!Network.doPoll(_fd, timeout, Network.PollMode.Write)) - { - throw new Ice.TimeoutException(); - } - ret = _fd.Send(buf.rawBytes(), 0, remaining, SocketFlags.None); - } - if(ret != remaining) - { - throw new Ice.DatagramLimitException(); - } - - if(_traceLevels.network >= 3) - { - string s = "sent " + ret + " bytes via udp\n" + ToString(); - _logger.trace(_traceLevels.networkCat, s); - } - - if(_stats != null) - { - _stats.bytesSent(type(), ret); - } - - buf.position(remaining); - } - catch(SocketException ex) - { - throw new Ice.SocketException(ex); - } - catch(Ice.LocalException) - { - throw; - } - catch(System.Exception ex) - { - throw new Ice.SyscallException(ex); + _shutdownReadWriteEvent.Set(); } } - public void read(BasicStream stream, int timeout) + public bool write(Buffer buf, int timeout) { - Debug.Assert(stream.pos() == 0); - - int packetSize = System.Math.Min(_maxPacketSize, _rcvSize - _udpOverhead); - if(packetSize < stream.size()) + Debug.Assert(buf.b.position() == 0); + int packetSize = System.Math.Min(_maxPacketSize, _sndSize - _udpOverhead); + if(packetSize < buf.size()) { // - // We log a warning here because this is the server side -- without the - // the warning, there would only be silence. + // We don't log a warning here because the client gets an exception anyway. // - if(_warn) - { - _logger.warning("DatagramLimitException: maximum size of " + packetSize + " exceeded"); - } throw new Ice.DatagramLimitException(); } - stream.resize(packetSize, true); - ByteBuffer buf = stream.prepareRead(); - buf.position(0); - if(AssemblyUtil.platform_ == AssemblyUtil.Platform.NonWindows) + while(buf.b.hasRemaining()) { - - repeat: - - // - // Check the shutdown flag. - // - lock(_shutdownReadWriteMutex) - { - if(_shutdownReadWrite) - { - throw new Ice.ConnectionLostException(); - } - } - try { + Debug.Assert(_fd != null); + int ret; - if(_connect) + try { - // - // If we must connect, then we connect to the first peer that - // sends us a packet. - // - EndPoint peerAddr = new IPEndPoint(IPAddress.Any, 0); - ret = _fd.ReceiveFrom(buf.rawBytes(), 0, buf.limit(), SocketFlags.None, ref peerAddr); + ret = _fd.Send(buf.b.rawBytes(), 0, buf.size(), SocketFlags.None); + } + catch(Win32Exception e) + { + if(Network.wouldBlock(e)) + { + if(timeout == 0) + { + return false; + } - Network.doConnect(_fd, peerAddr, -1); - _connect = false; // We're connected now + repeatPoll: + try + { + if(!Network.doPoll(_fd, timeout, Network.PollMode.Write)) + { + throw new Ice.TimeoutException(); + } + } + catch(Win32Exception ex) + { + if(Network.interrupted(ex)) + { + goto repeatPoll; + } + throw new Ice.SocketException(ex); + } - if(_traceLevels.network >= 1) - { - string s = "connected udp socket\n" + ToString(); - _logger.trace(_traceLevels.networkCat, s); + continue; } + throw; } - else - { - Debug.Assert(_fd != null); - ret = _fd.Receive(buf.rawBytes(), 0, buf.limit(), SocketFlags.None); - } + + Debug.Assert(ret > 0); if(_traceLevels.network >= 3) { - string s = "received " + ret + " bytes via udp\n" + ToString(); + string s = "sent " + ret + " bytes via udp\n" + ToString(); _logger.trace(_traceLevels.networkCat, s); } if(_stats != null) { - _stats.bytesReceived(type(), ret); + _stats.bytesSent(type(), ret); } - stream.resize(ret, true); + Debug.Assert(ret == buf.b.limit()); + break; } - catch(Win32Exception e) + catch(SocketException ex) { - if(Network.interrupted(e)) + if(Network.connectionLost(ex)) { - goto repeat; + throw new Ice.ConnectionLostException(ex); } - if(Network.wouldBlock(e)) - { - repeatPoll: - try - { - Network.doPoll(_fd, -1, Network.PollMode.Read); - } - catch(Win32Exception we) - { - if(Network.interrupted(we)) - { - goto repeatPoll; - } - throw new Ice.SocketException(we); - } - catch(System.Exception se) - { - throw new Ice.SyscallException(se); - } - - goto repeat; - } - - if(Network.recvTruncated(e)) - { - if(_warn) - { - _logger.warning("DatagramLimitException: maximum size of " + packetSize + " exceeded"); - } - throw new Ice.DatagramLimitException(); - } + throw new Ice.SocketException(ex); + } + } - if(Network.connectionLost(e)) - { - throw new Ice.ConnectionLostException(); - } + return true; + } - if(Network.connectionRefused(e)) - { - throw new Ice.ConnectionRefusedException(); - } + public bool read(Buffer buf, int timeout) + { + Debug.Assert(buf.b.position() == 0); - throw new Ice.SocketException(e); - } - catch(Ice.LocalException) - { - throw; - } - catch(System.Exception e) + int packetSize = System.Math.Min(_maxPacketSize, _rcvSize - _udpOverhead); + if(packetSize < buf.size()) + { + // + // We log a warning here because this is the server side -- without the + // the warning, there would only be silence. + // + if(_warn) { - throw new Ice.SyscallException(e); + _logger.warning("DatagramLimitException: maximum size of " + packetSize + " exceeded"); } + throw new Ice.DatagramLimitException(); } - else - { + buf.resize(packetSize, true); + buf.b.position(0); + +// if(AssemblyUtil.platform_ == AssemblyUtil.Platform.NonWindows) +// { +// int ret = 0; +// while(true) +// { +// // +// // Check for shutdown. +// // +// Socket fd = null; +// lock(_shutdownReadWriteMutex) +// { +// if(_shutdownReadWrite) +// { +// throw new Ice.ConnectionLostException(); +// } +// fd = _fd; +// } + +// try +// { +// EndPoint peerAddr = new IPEndPoint(IPAddress.Any, 0); +// try +// { +// ret = fd.ReceiveFrom(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None, ref peerAddr); +// } +// catch(Win32Exception e) +// { +// if(Network.interrupted(e)) +// { +// continue; +// } + +// if(Network.wouldBlock(e)) +// { +// if(timeout == 0) +// { +// return false; +// } + +// repeatPoll: +// try +// { +// if(!Network.doPoll(fd, timeout, Network.PollMode.Read)) +// { +// throw new Ice.TimeoutException(); +// } +// } +// catch(Win32Exception we) +// { +// if(Network.interrupted(we)) +// { +// goto repeatPoll; +// } +// throw new Ice.SocketException(we); +// } + +// continue; +// } + +// if(Network.recvTruncated(e)) +// { +// if(_warn) +// { +// _logger.warning("DatagramLimitException: maximum size of " + packetSize + +// " exceeded"); +// } +// throw new Ice.DatagramLimitException(); +// } + +// throw; +// } + +// Debug.Assert(ret > 0); + +// if(_connect) +// { +// // +// // If we must connect, then we connect to the first peer that +// // sends us a packet. +// // +// Network.doConnect(_fd, peerAddr, -1); +// _connect = false; // We're connected now + +// if(_traceLevels.network >= 1) +// { +// string s = "connected udp socket\n" + ToString(); +// _logger.trace(_traceLevels.networkCat, s); +// } +// } +// } +// catch(Win32Exception e) +// { +// if(Network.connectionLost(e)) +// { +// throw new Ice.ConnectionLostException(); +// } + +// if(Network.connectionRefused(e)) +// { +// throw new Ice.ConnectionRefusedException(); +// } + +// throw new Ice.SocketException(e); +// } + +// break; +// } + +// if(_traceLevels.network >= 3) +// { +// string s = "received " + ret + " bytes via udp\n" + ToString(); +// _logger.trace(_traceLevels.networkCat, s); +// } + +// if(_stats != null) +// { +// _stats.bytesReceived(type(), ret); +// } + +// buf.resize(ret, true); +// buf.b.position(ret); + +// return true; +// } +// else + { // - // On Windows, we use asynchronous I/O to properly handle a call to - // shutdownReadWrite. After calling BeginReceiveFrom, we wait for - // the receive to complete or for the _shutdownReadWriteEvent to be - // signaled. + // On Windows and Mac OS X, we use asynchronous I/O to properly handle a call to + // shutdownReadWrite. After calling BeginReceiveFrom, we wait for the receive to + // complete or for the _shutdownReadWriteEvent to be signaled. // WaitHandle[] handles = new WaitHandle[2]; @@ -336,12 +350,13 @@ namespace IceInternal } } + int ret = 0; try { - IAsyncResult ar = _fd.BeginReceiveFrom(buf.rawBytes(), 0, buf.limit(), SocketFlags.None, + IAsyncResult ar = _fd.BeginReceiveFrom(buf.b.rawBytes(), 0, buf.b.limit(), SocketFlags.None, ref peerAddr, null, null); handles[1] = ar.AsyncWaitHandle; - int num = WaitHandle.WaitAny(handles); + int num = WaitHandle.WaitAny(handles, timeout == 0 ? 1 : timeout, true); if(num == 0) { // @@ -349,38 +364,39 @@ namespace IceInternal // throw new Ice.ConnectionLostException(); } - else + else if(num == WaitHandle.WaitTimeout) { - int ret = _fd.EndReceiveFrom(ar, ref peerAddr); - - if(_connect) + if(timeout == 0) { - // - // If we must connect, then we connect to the first peer that - // sends us a packet. - // - Network.doConnect(_fd, peerAddr, -1); - _connect = false; // We're connected now - - if(_traceLevels.network >= 1) - { - string s = "connected udp socket\n" + ToString(); - _logger.trace(_traceLevels.networkCat, s); - } + return false; } - - if(_traceLevels.network >= 3) + throw new Ice.TimeoutException(); + } + else + { + ret = _fd.EndReceiveFrom(ar, ref peerAddr); + if(ret == 0) { - string s = "received " + ret + " bytes via udp\n" + ToString(); - _logger.trace(_traceLevels.networkCat, s); + throw new Ice.ConnectionLostException(); } + } - if(_stats != null) + Debug.Assert(ret > 0); + + if(_connect) + { + // + // If we must connect, then we connect to the first peer that + // sends us a packet. + // + Network.doConnect(_fd, peerAddr, -1); + _connect = false; // We're connected now + + if(_traceLevels.network >= 1) { - _stats.bytesReceived(type(), ret); + string s = "connected udp socket\n" + ToString(); + _logger.trace(_traceLevels.networkCat, s); } - - stream.resize(ret, true); } } catch(Win32Exception e) @@ -406,14 +422,22 @@ namespace IceInternal throw new Ice.SocketException(e); } - catch(Ice.LocalException) + + if(_traceLevels.network >= 3) { - throw; + string s = "received " + ret + " bytes via udp\n" + ToString(); + _logger.trace(_traceLevels.networkCat, s); } - catch(System.Exception e) + + if(_stats != null) { - throw new Ice.SyscallException(e); + _stats.bytesReceived(type(), ret); } + + buf.resize(ret, true); + buf.b.position(ret); + + return true; } } @@ -422,18 +446,14 @@ namespace IceInternal return "udp"; } - public void initialize(int timeout) - { - } - - public void checkSendSize(BasicStream stream, int messageSizeMax) + public void checkSendSize(Buffer buf, int messageSizeMax) { - if(stream.size() > messageSizeMax) + if(buf.size() > messageSizeMax) { throw new Ice.MemoryLimitException(); } int packetSize = System.Math.Min(_maxPacketSize, _sndSize - _udpOverhead); - if(packetSize < stream.size()) + if(packetSize < buf.size()) { throw new Ice.DatagramLimitException(); } @@ -450,12 +470,12 @@ namespace IceInternal return Network.fdToString(_fd); } } - + public int effectivePort() { return _addr.Port; } - + // // Only for use by UdpEndpoint // @@ -467,7 +487,7 @@ namespace IceInternal _connect = true; _warn = instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Datagrams") > 0; _addr = addr; - + try { _fd = Network.createSocket(true); @@ -489,7 +509,7 @@ namespace IceInternal Network.setMcastTtl(_fd, mcastTtl); } } - + if(_traceLevels.network >= 1) { string s = "starting to send udp packets\n" + ToString(); @@ -502,7 +522,7 @@ namespace IceInternal throw; } } - + // // Only for use by UdpEndpoint // @@ -514,7 +534,7 @@ namespace IceInternal _connect = connect; _warn = instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Datagrams") > 0; _shutdownReadWrite = false; - + try { _fd = Network.createSocket(true); @@ -563,7 +583,7 @@ namespace IceInternal } _addr = Network.doBind(_fd, _addr); } - + if(_traceLevels.network >= 1) { string s = "starting to receive udp packets\n" + ToString(); @@ -576,13 +596,13 @@ namespace IceInternal throw; } } - + private void setBufSize(Instance instance) { lock(this) { Debug.Assert(_fd != null); - + for (int i = 0; i < 2; ++i) { string direction; @@ -602,7 +622,7 @@ namespace IceInternal dfltSize = Network.getSendBufferSize(_fd); _sndSize = dfltSize; } - + // // Get property for buffer size and check for sanity. // @@ -613,7 +633,7 @@ namespace IceInternal _logger.warning("Invalid " + prop + " value of " + sizeRequested + " adjusted to " + dfltSize); sizeRequested = dfltSize; } - + if(sizeRequested != dfltSize) { // @@ -634,7 +654,7 @@ namespace IceInternal _sndSize = Network.getSendBufferSize(_fd); sizeSet = _sndSize; } - + // // Warn if the size that was set is less than the requested size. // @@ -658,7 +678,7 @@ namespace IceInternal private Socket _fd; private IPEndPoint _addr; private bool mcastServer = false; - + // // The maximum IP datagram size is 65535. Subtract 20 bytes for the IP header and 8 bytes for the UDP header // to get the maximum payload. diff --git a/cs/src/Ice/UnknownEndpointI.cs b/cs/src/Ice/UnknownEndpointI.cs index ad618fffaa6..4bf5e613023 100644 --- a/cs/src/Ice/UnknownEndpointI.cs +++ b/cs/src/Ice/UnknownEndpointI.cs @@ -11,6 +11,7 @@ namespace IceInternal { using System.Collections; + using System.Collections.Generic; sealed class UnknownEndpointI : EndpointI { @@ -225,16 +226,21 @@ namespace IceInternal endpoint = null; return null; } - + // // Return connectors for this endpoint, or empty list if no connector // is available. // - public override ArrayList connectors() + public override List<Connector> connectors() { - return new ArrayList(); + return new List<Connector>(); } - + + public override void connectors_async(EndpointI_connectors callback) + { + callback.connectors(new List<Connector>()); + } + // // Return an acceptor for this endpoint, or null if no acceptors // is available. In case an acceptor is created, this operation @@ -252,18 +258,18 @@ namespace IceInternal // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public override ArrayList + public override List<EndpointI> expand() { - ArrayList endps = new ArrayList(); + List<EndpointI> endps = new List<EndpointI>(); endps.Add(this); return endps; } // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - public override bool equivalent(Connector connector) + public override bool equivalent(EndpointI endpoint) { return false; } diff --git a/cs/src/Makefile.mak b/cs/src/Makefile.mak index 1b2aad5cc21..b5996ca6087 100644 --- a/cs/src/Makefile.mak +++ b/cs/src/Makefile.mak @@ -12,7 +12,7 @@ top_srcdir = .. !include $(top_srcdir)\config\Make.rules.mak.cs SUBDIRS = Ice IceStorm Glacier2 IcePatch2 IceGrid IceBox -SUBDIRS = $(SUBDIRS) IceSSL +SUBDIRS = $(SUBDIRS) #IceSSL $(EVERYTHING):: @for %i in ( $(SUBDIRS) ) do \ diff --git a/cs/test/Ice/Makefile b/cs/test/Ice/Makefile index 1fcd711470d..883e2e1b58d 100644 --- a/cs/test/Ice/Makefile +++ b/cs/test/Ice/Makefile @@ -32,7 +32,8 @@ SUBDIRS = application \ interceptor \ threads \ dictMapping \ - seqMapping + seqMapping \ + background $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cs/test/Ice/Makefile.mak b/cs/test/Ice/Makefile.mak index ce4b52efafd..2803dcb6294 100755 --- a/cs/test/Ice/Makefile.mak +++ b/cs/test/Ice/Makefile.mak @@ -32,7 +32,8 @@ SUBDIRS = application \ interceptor \ threads \ dictMapping \ - seqMapping + seqMapping \ + background $(EVERYTHING):: @for %i in ( $(SUBDIRS) ) do \ diff --git a/cs/test/Ice/background/.depend b/cs/test/Ice/background/.depend new file mode 100644 index 00000000000..4f6f1041841 --- /dev/null +++ b/cs/test/Ice/background/.depend @@ -0,0 +1 @@ +Test.cs: ./Test.ice $(slicedir)/Ice/BuiltinSequences.ice diff --git a/cs/test/Ice/background/Acceptor.cs b/cs/test/Ice/background/Acceptor.cs new file mode 100644 index 00000000000..e792ad715fb --- /dev/null +++ b/cs/test/Ice/background/Acceptor.cs @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System.Net.Sockets; + +internal class Acceptor : IceInternal.Acceptor +{ + public Socket fd() + { + return _acceptor.fd(); + } + + public void close() + { + _acceptor.close(); + } + + public void listen() + { + _acceptor.listen(); + } + + public IceInternal.Transceiver accept(int timeout) + { + return new Transceiver(_acceptor.accept(timeout)); + } + + public void connectToSelf() + { + _acceptor.connectToSelf(); + } + + public override string ToString() + { + return _acceptor.ToString(); + } + + internal Acceptor(IceInternal.Acceptor acceptor) + { + _acceptor = acceptor; + } + + private IceInternal.Acceptor _acceptor; +} diff --git a/cs/test/Ice/background/AllTests.cs b/cs/test/Ice/background/AllTests.cs new file mode 100644 index 00000000000..7a040a4ea05 --- /dev/null +++ b/cs/test/Ice/background/AllTests.cs @@ -0,0 +1,1131 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using Test; +using System; +using System.Diagnostics; +using System.Threading; + +public class AllTests +{ + private static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + private class Callback + { + internal Callback() + { + _called = false; + } + + public virtual bool check(bool wait) + { + lock(this) + { + if(wait) + { + while(!_called) + { + Monitor.Wait(this, TimeSpan.FromMilliseconds(5000)); + + if(!_called) + { + return false; // Must be timeout. + } + } + + _called = false; + return true; + } + return _called; + } + } + + public virtual void called() + { + lock(this) + { + Debug.Assert(!_called); + _called = true; + Monitor.Pulse(this); + } + } + + private bool _called; + } + + private class OpThread + { + internal OpThread(BackgroundPrx background) + { + _background = BackgroundPrxHelper.uncheckedCast(background.ice_oneway()); + Start(); + } + + public void Join() + { + _thread.Join(); + } + + public void Start() + { + _thread = new Thread(new ThreadStart(Run)); + _thread.Start(); + } + + public void Run() + { + int count = 0; + while(true) + { + lock(this) + { + if(_destroyed) + { + return; + } + } + + try + { + if(++count == 10) // Don't blast the connection with only oneway's + { + count = 0; + _background.ice_twoway().ice_ping(); + } + _background.op(); + Thread.Sleep(1); + } + catch(Ice.LocalException) + { + } + } + } + + public void destroy() + { + lock(this) + { + _destroyed = true; + } + } + + private bool _destroyed = false; + private BackgroundPrx _background = null; + private Thread _thread; + } + + private class OpAMICallback : Test.AMI_Background_op + { + public override void ice_response() + { + callback.called(); + } + + public override void ice_exception(Ice.Exception ex) + { + Console.Error.WriteLine(ex); + test(false); + } + + public bool response(bool wait) + { + return callback.check(wait); + } + + private Callback callback = new Callback(); + } + + private class OpExAMICallback : Test.AMI_Background_op + { + public override void ice_response() + { + test(false); + } + + public override void ice_exception(Ice.Exception ex) + { + callback.called(); + } + + public bool exception(bool wait) + { + return callback.check(wait); + } + + private Callback callback = new Callback(); + } + + private class OpWithPayloadOnewayAMICallback : Test.AMI_Background_opWithPayload + { + public override void ice_response() + { + test(false); + } + + public override void ice_exception(Ice.Exception ex) + { + test(false); + } + } + + private class FlushBatchRequestsCallback : Ice.AMI_Object_ice_flushBatchRequests + { + public override void ice_exception(Ice.LocalException ex) + { + test(false); + } + } + + public static Test.BackgroundPrx allTests(Ice.Communicator communicator) + { + string sref = "background:default -p 12010 -t 10000"; + Ice.ObjectPrx obj = communicator.stringToProxy(sref); + test(obj != null); + + BackgroundPrx background = BackgroundPrxHelper.uncheckedCast(obj); + + sref = "backgroundController:tcp -p 12011 -t 10000"; + obj = communicator.stringToProxy(sref); + test(obj != null); + + BackgroundControllerPrx backgroundController = BackgroundControllerPrxHelper.uncheckedCast(obj); + + Configuration configuration = Configuration.getInstance(); + + Console.Write("testing connect... "); + Console.Out.Flush(); + { + connectTests(configuration, background); + } + Console.Out.WriteLine("ok"); + + Console.Write("testing initialization... "); + Console.Out.Flush(); + { + initializeTests(configuration, background, backgroundController); + } + Console.Out.WriteLine("ok"); + + Console.Write("testing connection validation... "); + Console.Out.Flush(); + { + validationTests(configuration, background, backgroundController); + } + Console.Out.WriteLine("ok"); + + Console.Write("testing read/write... "); + Console.Out.Flush(); + { + readWriteTests(configuration, background, backgroundController); + } + Console.Out.WriteLine("ok"); + + Console.Write("testing locator... "); + Console.Out.Flush(); + { + Ice.LocatorPrx locator; + obj = communicator.stringToProxy("locator:default -p 12010 -t 500"); + locator = Ice.LocatorPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_locator(locator).ice_oneway(); + backgroundController.pauseCall("findAdapterById"); + try + { + obj.ice_ping(); + test(false); + } + catch(Ice.TimeoutException) + { + } + backgroundController.resumeCall("findAdapterById"); + + obj = communicator.stringToProxy("locator:default -p 12010 -t 10000"); + locator = Ice.LocatorPrxHelper.uncheckedCast(obj); + obj = obj.ice_locator(locator); + obj.ice_ping(); + + obj = communicator.stringToProxy("background@Test").ice_locator(locator); + BackgroundPrx bg = BackgroundPrxHelper.uncheckedCast(obj); + + backgroundController.pauseCall("findAdapterById"); + OpAMICallback cb = new OpAMICallback(); + bg.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + bg.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + backgroundController.resumeCall("findAdapterById"); + test(cb.response(true)); + test(cb2.response(true)); + } + Console.Out.WriteLine("ok"); + + Console.Write("testing router... "); + Console.Out.Flush(); + { + Ice.RouterPrx router; + + obj = communicator.stringToProxy("router:default -p 12010 -t 500"); + router = Ice.RouterPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_router(router).ice_oneway(); + backgroundController.pauseCall("getClientProxy"); + try + { + obj.ice_ping(); + test(false); + } + catch(Ice.TimeoutException) + { + } + backgroundController.resumeCall("getClientProxy"); + + obj = communicator.stringToProxy("router:default -p 12010 -t 10000"); + router = Ice.RouterPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_router(router); + BackgroundPrx bg = BackgroundPrxHelper.uncheckedCast(obj); + test(bg.ice_getRouter() != null); + + backgroundController.pauseCall("getClientProxy"); + OpAMICallback cb = new OpAMICallback(); + bg.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + bg.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + backgroundController.resumeCall("getClientProxy"); + test(cb.response(true)); + test(cb2.response(true)); + } + Console.Out.WriteLine("ok"); + + return background; + } + + private static void connectTests(Configuration configuration, Test.BackgroundPrx background) + { + try + { + background.op(); + } + catch(Ice.LocalException) + { + test(false); + } + background.ice_getConnection().close(false); + + OpExAMICallback cbEx = new OpExAMICallback(); + + try + { + configuration.connectorsException(new Ice.DNSException()); + background.op(); + test(false); + } + catch(Ice.DNSException) + { + configuration.connectorsException(null); + } + + configuration.connectorsException(new Ice.DNSException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectorsException(null); + + configuration.connectorsException(new Ice.DNSException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectorsException(null); + + try + { + configuration.connectException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.connectException(null); + } + + configuration.connectException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectException(null); + + configuration.connectException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectException(null); + + for(int i = 0; i < 10; i++) + { + try + { + BackgroundPrxHelper.uncheckedCast(background.ice_timeout(0)).op(); + background.ice_getConnection().close(false); + } + catch(Ice.ConnectTimeoutException) + { + } + catch(Ice.TimeoutException) + { + } + } + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + test(false); + } + + configuration.connectException(new Ice.SocketException()); + background.ice_getCachedConnection().close(true); + Thread.Sleep(10); + configuration.connectException(null); + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + } + } + + thread1.destroy(); + thread2.destroy(); + + thread1.Join(); + thread2.Join(); + } + + private static void initializeTests(Configuration configuration, Test.BackgroundPrx background, + Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.initializeException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.initializeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + + configuration.initializeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedConnect); + background.op(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + background.op(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + // + // Now run the same tests with the server side. + // + + try + { + ctl.initializeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.initializeException(false); + } + catch(Ice.SecurityException) + { + ctl.initializeException(false); + } + + try + { + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.NeedWrite); + background.op(); + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.NeedWrite); + ctl.initializeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.initializeException(false); + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.Finished); + } + catch(Ice.SecurityException) + { + ctl.initializeException(false); + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.Finished); + } + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + test(false); + } + + configuration.initializeException(new Ice.SocketException()); + background.ice_getCachedConnection().close(true); + Thread.Sleep(10); + configuration.initializeException(null); + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + } + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + test(false); + } + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + background.ice_getCachedConnection().close(true); + background.ice_ping(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + ctl.initializeException(true); + background.ice_getCachedConnection().close(true); + Thread.Sleep(10); + ctl.initializeException(false); + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + } + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + test(false); + } + + try + { + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.NeedWrite); + background.ice_getCachedConnection().close(true); + background.op(); + ctl.initializeSocketStatus((int)IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + test(false); + } + } + + thread1.destroy(); + thread2.destroy(); + + thread1.Join(); + thread2.Join(); + } + + private static void validationTests(Configuration configuration, Test.BackgroundPrx background, + Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the read() of connection validation to throw right away. + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.readException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + configuration.readException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + if(!background.ice_getCommunicator().getProperties().getProperty("Ice.Default.Protocol").Equals("test-ssl")) + { + try + { + // Get the read() of the connection validation to return "would block" + configuration.readReady(false); + background.op(); + configuration.readReady(true); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the read() of the connection validation to return "would block" and then throw. + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.readException(null); + configuration.readReady(true); + } + + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + } + + ctl.holdAdapter(); // Hold to block in connection validation + OpAMICallback cb = new OpAMICallback(); + background.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + background.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + ctl.resumeAdapter(); + test(cb.response(true)); + test(cb2.response(true)); + + try + { + // Get the write() of connection validation to throw right away. + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.writeException(false); + } + + try + { + // Get the write() of the connection validation to return "would block" + ctl.writeReady(false); + background.op(); + ctl.writeReady(true); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the write() of the connection validation to return "would block" and then throw. + ctl.writeReady(false); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.writeException(false); + ctl.writeReady(true); + } + + byte[] seq = new byte[512 * 1024]; + + BackgroundPrx backgroundBatchOneway = BackgroundPrxHelper.uncheckedCast(background.ice_batchOneway()); + + // + // First send small requests to test without auto-flushing. + // + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests(); + + // + // Send bigger requests to test with auto-flushing. + // + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests(); + + // + // Then try the same thing with async flush. + // + + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests_async(new FlushBatchRequestsCallback()); + backgroundBatchOneway.ice_getConnection().close(false); + + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + ctl.resumeAdapter(); + FlushBatchRequestsCallback fcb = new FlushBatchRequestsCallback(); + backgroundBatchOneway.ice_flushBatchRequests_async(fcb); + // + // We can't close the connection before ensuring all the batches have been sent since + // with auto-flushing the close connection message might be sent once the first call + // opWithPayload is sent and before the flushBatchRequests (this would therefore result + // in the flush to report a CloseConnectionException). Instead we flush a second time + // with the same callback to wait for the first flush to complete. + // + //backgroundBatchOneway.ice_getConnection().close(false); + backgroundBatchOneway.ice_flushBatchRequests_async(fcb); + backgroundBatchOneway.ice_getConnection().close(false); + } + + private static void readWriteTests(Configuration configuration, Test.BackgroundPrx background, + Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + test(false); + } + + try + { + background.ice_ping(); + configuration.writeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.writeException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.writeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + + configuration.writeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + + try + { + background.ice_ping(); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.readException(null); + } + + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + try + { + background.ice_ping(); + configuration.writeReady(false); + background.op(); + configuration.writeReady(true); + } + catch(Ice.LocalException) + { + test(false); + } + + try + { + background.ice_ping(); + configuration.readReady(false); + background.op(); + configuration.readReady(true); + } + catch(Ice.LocalException) + { + test(false); + } + + try + { + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.writeReady(true); + configuration.writeException(null); + } + + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + configuration.writeReady(true); + + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + configuration.writeReady(true); + + try + { + background.ice_ping(); + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException) + { + configuration.readException(null); + configuration.readReady(true); + } + + background.ice_ping(); + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + + background.ice_ping(); // Establish the connection + + BackgroundPrx backgroundOneway = BackgroundPrxHelper.uncheckedCast(background.ice_oneway()); + test(backgroundOneway.ice_getConnection() == background.ice_getConnection()); + + ctl.holdAdapter(); // Hold to block in request send. + + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + OpAMICallback cb = new OpAMICallback(); + background.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + background.op_async(cb2); + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + test(!cb.response(false)); + test(!cb2.response(false)); + ctl.resumeAdapter(); + test(cb.response(true)); + test(cb2.response(true)); + + try + { + background.ice_ping(); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.writeException(false); + } + + try + { + background.ice_ping(); + ctl.readException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.readException(false); + } + + try + { + background.ice_ping(); + ctl.writeReady(false); + background.op(); + ctl.writeReady(true); + } + catch(Ice.LocalException) + { + test(false); + } + + try + { + background.ice_ping(); + ctl.readReady(false); + background.op(); + ctl.readReady(true); + } + catch(Ice.LocalException) + { + test(false); + } + + try + { + background.ice_ping(); + ctl.writeReady(false); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.writeException(false); + ctl.writeReady(true); + } + + try + { + background.ice_ping(); + ctl.readReady(false); + ctl.readException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException) + { + ctl.readException(false); + ctl.readReady(true); + } + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException) + { + test(false); + } + + Thread.Sleep(10); + configuration.writeException(new Ice.SocketException()); + try + { + background.op(); + } + catch(Ice.LocalException) + { + } + configuration.writeException(null); + + Thread.Sleep(10); + + background.ice_ping(); + background.ice_getCachedConnection().close(true); + Thread.Sleep(10); + + background.ice_getCachedConnection().close(true); + } + + thread1.destroy(); + thread2.destroy(); + + thread1.Join(); + thread2.Join(); + } +} diff --git a/cs/test/Ice/background/BackgroundControllerI.cs b/cs/test/Ice/background/BackgroundControllerI.cs new file mode 100644 index 00000000000..296cd548f93 --- /dev/null +++ b/cs/test/Ice/background/BackgroundControllerI.cs @@ -0,0 +1,93 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using Test; +using System.Threading; + +internal class BackgroundControllerI : BackgroundControllerDisp_ +{ + public override void pauseCall(string opName, Ice.Current current) + { + lock(this) + { + _pausedCalls.Add(opName); + } + } + + public override void resumeCall(string opName, Ice.Current current) + { + lock(this) + { + _pausedCalls.Remove(opName); + Monitor.PulseAll(this); + } + } + + internal void checkCallPause(Ice.Current current) + { + lock(this) + { + while(_pausedCalls.Contains(current.operation)) + { + Monitor.Wait(this); + break; + } + } + } + + public override void holdAdapter(Ice.Current current) + { + _adapter.hold(); + } + + public override void resumeAdapter(Ice.Current current) + { + _adapter.activate(); + } + + public override void initializeSocketStatus(int status, Ice.Current current) + { + _configuration.initializeSocketStatus((IceInternal.SocketStatus)status); + } + + public override void initializeException(bool enable, Ice.Current current) + { + _configuration.initializeException(enable ? new Ice.SocketException() : null); + } + + public override void readReady(bool enable, Ice.Current current) + { + _configuration.readReady(enable); + } + + public override void readException(bool enable, Ice.Current current) + { + _configuration.readException(enable ? new Ice.SocketException() : null); + } + + public override void writeReady(bool enable, Ice.Current current) + { + _configuration.writeReady(enable); + } + + public override void writeException(bool enable, Ice.Current current) + { + _configuration.writeException(enable ? new Ice.SocketException() : null); + } + + internal BackgroundControllerI(Ice.ObjectAdapter adapter) + { + _adapter = adapter; + _configuration = Configuration.getInstance(); + } + + private Ice.ObjectAdapter _adapter; + private IceUtil.Set _pausedCalls = new IceUtil.Set(); + private Configuration _configuration; +} diff --git a/cs/test/Ice/background/BackgroundI.cs b/cs/test/Ice/background/BackgroundI.cs new file mode 100644 index 00000000000..a898d1359b3 --- /dev/null +++ b/cs/test/Ice/background/BackgroundI.cs @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using Test; + +internal class BackgroundI : BackgroundDisp_ +{ + public override void op(Ice.Current current) + { + _controller.checkCallPause(current); + } + + public override void opWithPayload(byte[] seq, Ice.Current current) + { + _controller.checkCallPause(current); + } + + public override void shutdown(Ice.Current current) + { + current.adapter.getCommunicator().shutdown(); + } + + internal BackgroundI(BackgroundControllerI controller) + { + _controller = controller; + } + + private BackgroundControllerI _controller; +} diff --git a/cs/test/Ice/background/Client.cs b/cs/test/Ice/background/Client.cs new file mode 100644 index 00000000000..932a8d3bc84 --- /dev/null +++ b/cs/test/Ice/background/Client.cs @@ -0,0 +1,78 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System; + +public class Client +{ + public static int run(string[] args, Ice.Communicator communicator) + { + Test.BackgroundPrx background = AllTests.allTests(communicator); + background.shutdown(); + return 0; + } + + public static void Main(string[] args) + { + int status = 0; + Ice.Communicator communicator = null; + + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(ref args); + + // + // For this test, we want to disable retries. + // + initData.properties.setProperty("Ice.RetryIntervals", "-1"); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + string defaultProtocol = initData.properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties.setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice.Util.initialize(ref args, initData); + PluginI plugin = new PluginI(communicator); + plugin.initialize(); + communicator.getPluginManager().addPlugin("Test", plugin); + + status = run(args, communicator); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + + if(communicator != null) + { + try + { + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + } + + if(status != 0) + { + System.Environment.Exit(status); + } + } +} diff --git a/cs/test/Ice/background/Configuration.cs b/cs/test/Ice/background/Configuration.cs new file mode 100644 index 00000000000..3dbf7c1d839 --- /dev/null +++ b/cs/test/Ice/background/Configuration.cs @@ -0,0 +1,192 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +internal class Configuration +{ + public void connectorsException(Ice.LocalException ex) + { + lock(this) + { + _connectorsException = ex; + } + } + + public void checkConnectorsException() + { + lock(this) + { + if(_connectorsException != null) + { + throw _connectorsException; + } + } + } + + public void connectException(Ice.LocalException ex) + { + lock(this) + { + _connectException = ex; + } + } + + public void checkConnectException() + { + lock(this) + { + if(_connectException != null) + { + throw _connectException; + } + } + } + + public void initializeSocketStatus(IceInternal.SocketStatus status) + { + lock(this) + { + if(status == IceInternal.SocketStatus.Finished) + { + _initializeResetCount = 0; + return; + } + _initializeResetCount = 10; + _initializeSocketStatus = status; + } + } + + public void initializeException(Ice.LocalException ex) + { + lock(this) + { + _initializeException = ex; + } + } + + public IceInternal.SocketStatus initializeSocketStatus() + { + lock(this) + { + if(_initializeResetCount == 0) + { + return IceInternal.SocketStatus.Finished; + } + --_initializeResetCount; + return _initializeSocketStatus; + } + } + + public void checkInitializeException() + { + lock(this) + { + if(_initializeException != null) + { + throw _initializeException; + } + } + } + + public void readReady(bool ready) + { + lock(this) + { + _readReadyCount = ready ? 0 : 10; + } + } + + public void readException(Ice.LocalException ex) + { + lock(this) + { + _readException = ex; + } + } + + public bool readReady() + { + lock(this) + { + if(_readReadyCount == 0) + { + return true; + } + --_readReadyCount; + return false; + } + } + + public void checkReadException() + { + lock(this) + { + if(_readException != null) + { + throw _readException; + } + } + } + + public void writeReady(bool ready) + { + lock(this) + { + _writeReadyCount = ready ? 0 : 10; + } + } + + public void writeException(Ice.LocalException ex) + { + lock(this) + { + _writeException = ex; + } + } + + public bool writeReady() + { + lock(this) + { + if(_writeReadyCount == 0) + { + return true; + } + --_writeReadyCount; + return false; + } + } + + public void checkWriteException() + { + lock(this) + { + if(_writeException != null) + { + throw _writeException; + } + } + } + + static public Configuration getInstance() + { + return _instance; + } + + private Ice.LocalException _connectorsException; + private Ice.LocalException _connectException; + private IceInternal.SocketStatus _initializeSocketStatus; + private int _initializeResetCount; + private Ice.LocalException _initializeException; + private int _readReadyCount; + private Ice.LocalException _readException; + private int _writeReadyCount; + private Ice.LocalException _writeException; + + private static Configuration _instance = new Configuration(); +} diff --git a/cs/test/Ice/background/Connector.cs b/cs/test/Ice/background/Connector.cs new file mode 100644 index 00000000000..b09530b52e1 --- /dev/null +++ b/cs/test/Ice/background/Connector.cs @@ -0,0 +1,81 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System.Diagnostics; +using System.Net.Sockets; + +internal class Connector : IceInternal.Connector +{ + public IceInternal.Transceiver connect(int timeout) + { + _configuration.checkConnectException(); + return new Transceiver(_connector.connect(timeout)); + } + + public short type() + { + return (short)(EndpointI.TYPE_BASE + _connector.type()); + } + + public int CompareTo(object obj) + { + Connector p = null; + + try + { + p = (Connector)obj; + } + catch(System.InvalidCastException) + { + try + { + IceInternal.Connector c = (IceInternal.Connector)obj; + return type() < c.type() ? -1 : 1; + } + catch(System.InvalidCastException) + { + Debug.Assert(false); + } + } + + if(this == p) + { + return 0; + } + + return _connector.CompareTo(p._connector); + } + + // + // Only for use by Endpoint + // + internal Connector(IceInternal.Connector connector) + { + _configuration = Configuration.getInstance(); + _connector = connector; + } + + public override bool Equals(object obj) + { + return CompareTo(obj) == 0; + } + + public override string ToString() + { + return _connector.ToString(); + } + + public override int GetHashCode() + { + return _connector.GetHashCode(); + } + + private IceInternal.Connector _connector; + private Configuration _configuration; +} diff --git a/cs/test/Ice/background/EndpointFactory.cs b/cs/test/Ice/background/EndpointFactory.cs new file mode 100644 index 00000000000..9a9788a065a --- /dev/null +++ b/cs/test/Ice/background/EndpointFactory.cs @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +internal class EndpointFactory : IceInternal.EndpointFactory +{ + internal EndpointFactory(IceInternal.EndpointFactory factory) + { + _factory = factory; + } + + public short type() + { + return (short)(EndpointI.TYPE_BASE + _factory.type()); + } + + public string protocol() + { + return "test-" + _factory.protocol(); + } + + public IceInternal.EndpointI create(string str, bool server) + { + return new EndpointI(_factory.create(str, server)); + } + + public IceInternal.EndpointI read(IceInternal.BasicStream s) + { + s.readShort(); + return new EndpointI(_factory.read(s)); + } + + public void destroy() + { + } + + private IceInternal.EndpointFactory _factory; +} diff --git a/cs/test/Ice/background/EndpointI.cs b/cs/test/Ice/background/EndpointI.cs new file mode 100755 index 00000000000..725e5d7fb55 --- /dev/null +++ b/cs/test/Ice/background/EndpointI.cs @@ -0,0 +1,304 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System.Collections.Generic; +using System.Diagnostics; + +internal class EndpointI : IceInternal.EndpointI +{ + internal static short TYPE_BASE = 100; + + internal EndpointI(IceInternal.EndpointI endpoint) + { + _endpoint = endpoint; + _configuration = Configuration.getInstance(); + } + + // + // Marshal the endpoint + // + public override void streamWrite(IceInternal.BasicStream s) + { + s.writeShort(type()); + _endpoint.streamWrite(s); + } + + // + // Convert the endpoint to its string form + // + public override string ice_toString_() + { + return "test-" + _endpoint.ToString(); + } + + // + // Return the endpoint type + // + public override short type() + { + return (short)(TYPE_BASE + _endpoint.type()); + } + + // + // Return the timeout for the endpoint in milliseconds. 0 means + // non-blocking, -1 means no timeout. + // + public override int timeout() + { + return _endpoint.timeout(); + } + + // + // Return a new endpoint with a different timeout value, provided + // that timeouts are supported by the endpoint. Otherwise the same + // endpoint is returned. + // + public override IceInternal.EndpointI timeout(int timeout) + { + IceInternal.EndpointI endpoint = _endpoint.timeout(timeout); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return a new endpoint with a different connection id. + // + public override IceInternal.EndpointI connectionId(string connectionId) + { + IceInternal.EndpointI endpoint = _endpoint.connectionId(connectionId); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return true if the endpoints support bzip2 compress, or false + // otherwise. + // + public override bool compress() + { + return _endpoint.compress(); + } + + // + // Return a new endpoint with a different compression value, + // provided that compression is supported by the + // endpoint. Otherwise the same endpoint is returned. + // + public override IceInternal.EndpointI compress(bool compress) + { + IceInternal.EndpointI endpoint = _endpoint.compress(compress); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return true if the endpoint is datagram-based. + // + public override bool datagram() + { + return _endpoint.datagram(); + } + + // + // Return true if the endpoint is secure. + // + public override bool secure() + { + return _endpoint.secure(); + } + + // + // Return true if the endpoint type is unknown. + // + public override bool unknown() + { + return _endpoint.unknown(); + } + + // + // Return a server side transceiver for this endpoint, or null if a + // transceiver can only be created by an acceptor. In case a + // transceiver is created, this operation also returns a new + // "effective" endpoint, which might differ from this endpoint, + // for example, if a dynamic port number is assigned. + // + public override IceInternal.Transceiver transceiver(ref IceInternal.EndpointI endpoint) + { + IceInternal.Transceiver transceiver = _endpoint.transceiver(ref endpoint); + if(endpoint == _endpoint) + { + endpoint = this; + } + else + { + endpoint = new EndpointI(endpoint); + } + + if(transceiver != null) + { + return new Transceiver(transceiver); + } + else + { + return null; + } + } + + // + // Return connectors for this endpoint, or empty list if no connector + // is available. + // + public override List<IceInternal.Connector> connectors() + { + _configuration.checkConnectorsException(); + List<IceInternal.Connector> connectors = new List<IceInternal.Connector>(); + foreach(IceInternal.Connector connector in _endpoint.connectors()) + { + connectors.Add(new Connector(connector)); + } + return connectors; + } + + private class ConnectorsCallback : IceInternal.EndpointI_connectors + { + internal ConnectorsCallback(IceInternal.EndpointI_connectors cb) + { + _callback = cb; + } + + public void connectors(List<IceInternal.Connector> cons) + { + List<IceInternal.Connector> connectors = new List<IceInternal.Connector>(); + foreach(IceInternal.Connector connector in cons) + { + connectors.Add(new Connector(connector)); + } + _callback.connectors(connectors); + } + + public void exception(Ice.LocalException exception) + { + _callback.exception(exception); + } + + private IceInternal.EndpointI_connectors _callback; + } + + public override void connectors_async(IceInternal.EndpointI_connectors cb) + { + try + { + _configuration.checkConnectorsException(); + _endpoint.connectors_async(new ConnectorsCallback(cb)); + } + catch(Ice.LocalException ex) + { + cb.exception(ex); + } + } + + public override IceInternal.Acceptor acceptor(ref IceInternal.EndpointI endpoint, string adapterName) + { + Acceptor p = new Acceptor(_endpoint.acceptor(ref endpoint, adapterName)); + endpoint = new EndpointI(endpoint); + return p; + } + + public override List<IceInternal.EndpointI> expand() + { + List<IceInternal.EndpointI> endps = new List<IceInternal.EndpointI>(); + foreach(IceInternal.EndpointI endpt in _endpoint.expand()) + { + endps.Add(endpt == _endpoint ? this : new EndpointI(endpt)); + } + return endps; + } + + public override bool equivalent(IceInternal.EndpointI endpoint) + { + EndpointI testEndpoint = null; + try + { + testEndpoint = (EndpointI)endpoint; + } + catch(System.InvalidCastException) + { + return false; + } + return testEndpoint._endpoint.equivalent(_endpoint); + } + + public override int GetHashCode() + { + return _endpoint.GetHashCode(); + } + + // + // Compare endpoints for sorting purposes + // + public override bool Equals(object obj) + { + return CompareTo(obj) == 0; + } + + public override int CompareTo(object obj) + { + EndpointI p = null; + + try + { + p = (EndpointI)obj; + } + catch(System.InvalidCastException) + { + try + { + IceInternal.EndpointI e = (IceInternal.EndpointI)obj; + return type() < e.type() ? -1 : 1; + } + catch(System.InvalidCastException) + { + Debug.Assert(false); + } + } + + if(this == p) + { + return 0; + } + + return _endpoint.CompareTo(p._endpoint); + } + + public override bool requiresThreadPerConnection() + { + return _endpoint.requiresThreadPerConnection(); + } + + private IceInternal.EndpointI _endpoint; + private Configuration _configuration; +} diff --git a/cs/test/Ice/background/Makefile b/cs/test/Ice/background/Makefile new file mode 100644 index 00000000000..713652413a2 --- /dev/null +++ b/cs/test/Ice/background/Makefile @@ -0,0 +1,36 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +TARGETS = client.exe server.exe + +COMMON_SRCS = Acceptor.cs Configuration.cs Connector.cs EndpointFactory.cs EndpointI.cs PluginI.cs Transceiver.cs +C_SRCS = AllTests.cs Client.cs $(COMMON_SRCS) +S_SRCS = BackgroundControllerI.cs BackgroundI.cs Server.cs $(COMMON_SRCS) + +SLICE_SRCS = $(SDIR)/Test.ice + +SDIR = . + +GDIR = generated + +include $(top_srcdir)/config/Make.rules.cs + +MCSFLAGS := $(MCSFLAGS) -target:exe + +SLICE2CSFLAGS := $(SLICE2CSFLAGS) --ice -I. -I$(slicedir) + +client.exe: $(C_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ $(call ref,icecs) $(subst /,$(DSEP),$^) + +server.exe: $(S_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ $(call ref,icecs) $(subst /,$(DSEP),$^) + +include .depend diff --git a/cs/test/Ice/background/Makefile.mak b/cs/test/Ice/background/Makefile.mak new file mode 100644 index 00000000000..11e7b7727aa --- /dev/null +++ b/cs/test/Ice/background/Makefile.mak @@ -0,0 +1,37 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +top_srcdir = ..\..\.. + +TARGETS = client.exe server.exe + +COMMON_SRCS = Acceptor.cs Configuration.cs Connector.cs EndpointFactory.cs EndpointI.cs PluginI.cs Transceiver.cs +C_SRCS = AllTests.cs Client.cs $(COMMON_SRCS) +S_SRCS = BackgroundControllerI.cs BackgroundI.cs Server.cs $(COMMON_SRCS) + +GEN_SRCS = $(GDIR)\Test.cs +GEN_AMD_SRCS = $(GDIR)\TestAMD.cs + +SDIR = . + +GDIR = generated + +!include $(top_srcdir)\config\Make.rules.mak.cs + +MCSFLAGS = $(MCSFLAGS) -target:exe + +SLICE2CSFLAGS = $(SLICE2CSFLAGS) --ice -I. -I$(slicedir) + +client.exe: $(C_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ -r:$(bindir)\icecs.dll $(C_SRCS) $(GEN_SRCS) + +server.exe: $(S_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ -r:$(bindir)\icecs.dll $(S_SRCS) $(GEN_SRCS) + +!include .depend diff --git a/cs/test/Ice/background/PluginI.cs b/cs/test/Ice/background/PluginI.cs new file mode 100644 index 00000000000..da66ed9d842 --- /dev/null +++ b/cs/test/Ice/background/PluginI.cs @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +internal class PluginI : Ice.Plugin +{ + internal PluginI(Ice.Communicator communicator) + { + _communicator = communicator; + } + + public void initialize() + { + IceInternal.ProtocolPluginFacade facade = Ice.Util.getProtocolPluginFacade(_communicator); + for(short s = 0; s < 100; ++s) + { + IceInternal.EndpointFactory factory = facade.getEndpointFactory(s); + if(factory != null) + { + facade.addEndpointFactory(new EndpointFactory(factory)); + } + } + } + + public void destroy() + { + } + + private Ice.Communicator _communicator; +} diff --git a/cs/test/Ice/background/Server.cs b/cs/test/Ice/background/Server.cs new file mode 100644 index 00000000000..b4c92b88047 --- /dev/null +++ b/cs/test/Ice/background/Server.cs @@ -0,0 +1,162 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System; +using System.IO; + +public class Server +{ + internal class LocatorI : Ice.LocatorDisp_ + { + public override void findAdapterById_async(Ice.AMD_Locator_findAdapterById response, string adapter, + Ice.Current current) + { + _controller.checkCallPause(current); + Ice.Communicator communicator = current.adapter.getCommunicator(); + response.ice_response(current.adapter.createDirectProxy(communicator.stringToIdentity("dummy"))); + } + + public override void findObjectById_async(Ice.AMD_Locator_findObjectById response, Ice.Identity id, + Ice.Current current) + { + _controller.checkCallPause(current); + response.ice_response(current.adapter.createDirectProxy(id)); + } + + public override Ice.LocatorRegistryPrx getRegistry(Ice.Current current) + { + return null; + } + + internal LocatorI(BackgroundControllerI controller) + { + _controller = controller; + } + + private BackgroundControllerI _controller; + } + + internal class RouterI : Ice.RouterDisp_ + { + public override Ice.ObjectPrx getClientProxy(Ice.Current current) + { + _controller.checkCallPause(current); + return null; + } + + public override Ice.ObjectPrx getServerProxy(Ice.Current current) + { + _controller.checkCallPause(current); + return null; + } + + public override void addProxy(Ice.ObjectPrx proxy, Ice.Current current) + { + } + + public override Ice.ObjectPrx[] addProxies(Ice.ObjectPrx[] proxies, Ice.Current current) + { + return new Ice.ObjectPrx[0]; + } + + internal RouterI(BackgroundControllerI controller) + { + _controller = controller; + } + + private BackgroundControllerI _controller; + } + + public static int run(string[] args, Ice.Communicator communicator, TextWriter @out) + { + // + // When running as a MIDlet the properties for the server may be + // overridden by configuration. If it isn't then we assume + // defaults. + // + if(communicator.getProperties().getProperty("TestAdapter.Endpoints").Length == 0) + { + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); + } + if(communicator.getProperties().getProperty("ControllerAdapter.Endpoints").Length == 0) + { + communicator.getProperties().setProperty("ControllerAdapter.Endpoints", "tcp -p 12011"); + communicator.getProperties().setProperty("ControllerAdapter.ThreadPool.Size", "1"); + } + + Ice.ObjectAdapter adapter = communicator.createObjectAdapter("TestAdapter"); + Ice.ObjectAdapter adapter2 = communicator.createObjectAdapter("ControllerAdapter"); + + BackgroundControllerI backgroundController = new BackgroundControllerI(adapter); + + adapter.add(new BackgroundI(backgroundController), communicator.stringToIdentity("background")); + adapter.add(new LocatorI(backgroundController), communicator.stringToIdentity("locator")); + adapter.add(new RouterI(backgroundController), communicator.stringToIdentity("router")); + adapter.activate(); + + adapter2.add(backgroundController, communicator.stringToIdentity("backgroundController")); + adapter2.activate(); + + communicator.waitForShutdown(); + return 0; + } + + public static void Main(string[] args) + { + int status = 0; + Ice.Communicator communicator = null; + + try + { + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(ref args); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + string defaultProtocol = initData.properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties.setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice.Util.initialize(ref args, initData); + PluginI plugin = new PluginI(communicator); + plugin.initialize(); + communicator.getPluginManager().addPlugin("Test", plugin); + + status = run(args, communicator, Console.Out); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + + if(communicator != null) + { + try + { + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + } + + if(status != 0) + { + System.Environment.Exit(status); + } + } +} diff --git a/cs/test/Ice/background/Test.ice b/cs/test/Ice/background/Test.ice new file mode 100644 index 00000000000..f85b9ac0065 --- /dev/null +++ b/cs/test/Ice/background/Test.ice @@ -0,0 +1,46 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Background +{ + ["ami"] void op(); + ["ami"] void opWithPayload(Ice::ByteSeq seq); + + void shutdown(); +}; + +interface BackgroundController +{ + void pauseCall(string call); + void resumeCall(string call); + + void holdAdapter(); + void resumeAdapter(); + + void initializeSocketStatus(int status); + void initializeException(bool enable); + + void readReady(bool enable); + void readException(bool enable); + + void writeReady(bool enable); + void writeException(bool enable); +}; + +}; + +#endif diff --git a/cs/test/Ice/background/Transceiver.cs b/cs/test/Ice/background/Transceiver.cs new file mode 100644 index 00000000000..5d2c0cf43b2 --- /dev/null +++ b/cs/test/Ice/background/Transceiver.cs @@ -0,0 +1,137 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System.Net.Sockets; + +internal class Transceiver : IceInternal.Transceiver +{ + public Socket fd() + { + return _transceiver.fd(); + } + + public IceInternal.SocketStatus initialize(int timeout) + { + if(timeout == 0) + { + IceInternal.SocketStatus status = _configuration.initializeSocketStatus(); + if(status == IceInternal.SocketStatus.NeedConnect) + { + return status; + } + else if(status == IceInternal.SocketStatus.NeedWrite) + { + if(!_initialized) + { + status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + _initialized = true; + } + return IceInternal.SocketStatus.NeedWrite; + } + else if(status == IceInternal.SocketStatus.NeedRead) + { + return status; + } + } + _configuration.checkInitializeException(); + if(!_initialized) + { + IceInternal.SocketStatus status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + _initialized = true; + } + return IceInternal.SocketStatus.Finished; + } + + public void close() + { + _transceiver.close(); + } + + public void shutdownWrite() + { + _transceiver.shutdownWrite(); + } + + public void shutdownReadWrite() + { + _transceiver.shutdownReadWrite(); + } + + public bool write(IceInternal.Buffer buf, int timeout) + { + if(!_initialized) + { + throw new Ice.SocketException(); + } + + if(timeout == 0) + { + if(!_configuration.writeReady()) + { + return false; + } + } + _configuration.checkWriteException(); + return _transceiver.write(buf, timeout); + } + + public bool read(IceInternal.Buffer buf, int timeout) + { + if(!_initialized) + { + throw new Ice.SocketException(); + } + + if(timeout == 0) + { + if(!_configuration.readReady()) + { + return false; + } + } + _configuration.checkReadException(); + return _transceiver.read(buf, timeout); + } + + public string type() + { + return "test-" + _transceiver.type(); + } + + public override string ToString() + { + return _transceiver.ToString(); + } + + public void checkSendSize(IceInternal.Buffer buf, int messageSizeMax) + { + _transceiver.checkSendSize(buf, messageSizeMax); + } + + // + // Only for use by Connector, Acceptor + // + internal Transceiver(IceInternal.Transceiver transceiver) + { + _transceiver = transceiver; + _configuration = Configuration.getInstance(); + } + + private IceInternal.Transceiver _transceiver; + private Configuration _configuration; + private bool _initialized = false; +} diff --git a/cs/test/Ice/background/client.exe.config b/cs/test/Ice/background/client.exe.config new file mode 100755 index 00000000000..1eeb15fea8f --- /dev/null +++ b/cs/test/Ice/background/client.exe.config @@ -0,0 +1,35 @@ +<?xml version="1.0"?> + <configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="glacier2cs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/glacier2cs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icecs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icecs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icepatch2cs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icepatch2cs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icestormcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icestormcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="iceboxcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/iceboxcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icegridcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icegridcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icesslcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icesslcs.dll"/> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/cs/test/Ice/background/generated/.gitignore b/cs/test/Ice/background/generated/.gitignore new file mode 100644 index 00000000000..39af5887579 --- /dev/null +++ b/cs/test/Ice/background/generated/.gitignore @@ -0,0 +1 @@ +# Dummy file, so that git retains this otherwise empty directory. diff --git a/cs/test/Ice/background/run.py b/cs/test/Ice/background/run.py new file mode 100755 index 00000000000..591afce1d95 --- /dev/null +++ b/cs/test/Ice/background/run.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +import os, sys, getopt + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")): + break +else: + raise "can't find toplevel directory!" + +sys.path.append(os.path.join(toplevel, "config")) +import TestUtil + +name = os.path.join("Ice", "background") + +TestUtil.clientServerTest(name) +sys.exit(0) diff --git a/cs/test/Ice/background/server.exe.config b/cs/test/Ice/background/server.exe.config new file mode 100755 index 00000000000..1eeb15fea8f --- /dev/null +++ b/cs/test/Ice/background/server.exe.config @@ -0,0 +1,35 @@ +<?xml version="1.0"?> + <configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="glacier2cs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/glacier2cs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icecs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icecs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icepatch2cs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icepatch2cs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icestormcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icestormcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="iceboxcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/iceboxcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icegridcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icegridcs.dll"/> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="icesslcs" culture="neutral" publicKeyToken="1f998c50fec78381"/> + <codeBase version="3.3.0.0" href="../../../bin/icesslcs.dll"/> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration> diff --git a/cs/test/Ice/operations/AllTests.cs b/cs/test/Ice/operations/AllTests.cs index e1d4ac23358..d78cbd06ac3 100755 --- a/cs/test/Ice/operations/AllTests.cs +++ b/cs/test/Ice/operations/AllTests.cs @@ -18,14 +18,19 @@ public class AllTests Ice.ObjectPrx baseProxy = communicator.stringToProxy(rf); Test.MyClassPrx cl = Test.MyClassPrxHelper.checkedCast(baseProxy); Test.MyDerivedClassPrx derivedProxy = Test.MyDerivedClassPrxHelper.checkedCast(cl); - + Console.Out.Write("testing twoway operations... "); Console.Out.Flush(); Twoways.twoways(communicator, cl); Twoways.twoways(communicator, derivedProxy); derivedProxy.opDerived(); Console.Out.WriteLine("ok"); - + + Console.Out.Write("testing oneway operations... "); + Console.Out.Flush(); + Oneways.oneways(communicator, cl); + Console.Out.WriteLine("ok"); + if(!collocated) { Console.Out.Write("testing twoway operations with AMI... "); @@ -34,13 +39,18 @@ public class AllTests TwowaysAMI.twowaysAMI(communicator, derivedProxy); Console.Out.WriteLine("ok"); + Console.Out.Write("testing oneway operations with AMI... "); + Console.Out.Flush(); + OnewaysAMI.onewaysAMI(communicator, cl); + Console.Out.WriteLine("ok"); + Console.Out.Write("testing batch oneway operations... "); Console.Out.Flush(); BatchOneways.batchOneways(cl); BatchOneways.batchOneways(derivedProxy); Console.Out.WriteLine("ok"); } - + return cl; } } diff --git a/cs/test/Ice/operations/Makefile b/cs/test/Ice/operations/Makefile index 34501e55d60..b7ca8df7ee5 100644 --- a/cs/test/Ice/operations/Makefile +++ b/cs/test/Ice/operations/Makefile @@ -11,9 +11,10 @@ top_srcdir = ../../.. TARGETS = client.exe server.exe collocated.exe serveramd.exe -C_SRCS = AllTests.cs Client.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs +C_SRCS = AllTests.cs Client.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs Oneways.cs OnewaysAMI.cs S_SRCS = MyDerivedClassI.cs Server.cs -COL_SRCS = AllTests.cs Collocated.cs MyDerivedClassI.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs +COL_SRCS = AllTests.cs Collocated.cs MyDerivedClassI.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs Oneways.cs \ + OnewaysAMI.cs SAMD_SRCS = MyDerivedClassAMDI.cs Server.cs SLICE_SRCS = $(SDIR)/Test.ice diff --git a/cs/test/Ice/operations/Makefile.mak b/cs/test/Ice/operations/Makefile.mak index de063129f65..7426b1e1fbc 100644 --- a/cs/test/Ice/operations/Makefile.mak +++ b/cs/test/Ice/operations/Makefile.mak @@ -11,9 +11,10 @@ top_srcdir = ..\..\.. TARGETS = client.exe server.exe collocated.exe serveramd.exe -C_SRCS = AllTests.cs Client.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs +C_SRCS = AllTests.cs Client.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs Oneways.cs OnewaysAMI.cs S_SRCS = MyDerivedClassI.cs Server.cs -COL_SRCS = AllTests.cs Collocated.cs MyDerivedClassI.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs +COL_SRCS = AllTests.cs Collocated.cs MyDerivedClassI.cs Twoways.cs TwowaysAMI.cs BatchOneways.cs Oneways.cs \ + OnewaysAMI.cs SAMD_SRCS = MyDerivedClassAMDI.cs Server.cs GEN_SRCS = $(GDIR)\Test.cs diff --git a/cs/test/Ice/operations/Oneways.cs b/cs/test/Ice/operations/Oneways.cs new file mode 100644 index 00000000000..f55221026af --- /dev/null +++ b/cs/test/Ice/operations/Oneways.cs @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +class Oneways +{ + private static void test(bool b) + { + if(!b) + { + throw new System.SystemException(); + } + } + + internal static void oneways(Ice.Communicator communicator, Test.MyClassPrx p) + { + p = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + + { + p.opVoid(); + } + + { + byte b; + try + { + p.opByte((byte)0xff, (byte)0x0f, out b); + test(false); + } + catch(Ice.TwowayOnlyException) + { + } + } + } +} diff --git a/cs/test/Ice/operations/OnewaysAMI.cs b/cs/test/Ice/operations/OnewaysAMI.cs new file mode 100644 index 00000000000..71d301bb658 --- /dev/null +++ b/cs/test/Ice/operations/OnewaysAMI.cs @@ -0,0 +1,151 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +using System; +using System.Diagnostics; +using System.Threading; + +class OnewaysAMI +{ + private static void test(bool b) + { + if(!b) + { + throw new System.SystemException(); + } + } + + private class Callback + { + internal Callback() + { + _called = false; + } + + public bool check() + { + lock(this) + { + while(!_called) + { + Monitor.Wait(this, TimeSpan.FromMilliseconds(5000)); + + if(!_called) + { + return false; // Must be timeout. + } + } + + _called = false; + return true; + } + } + + public void called() + { + lock(this) + { + Debug.Assert(!_called); + _called = true; + Monitor.Pulse(this); + } + } + + private bool _called; + } + + private class AMI_MyClass_opVoidI : Test.AMI_MyClass_opVoid + { + public override void ice_response() + { + test(false); + } + + public override void ice_exception(Ice.Exception ex) + { + test(false); + } + } + + private class AMI_MyClass_opVoidExI : Test.AMI_MyClass_opVoid + { + public override void ice_response() + { + test(false); + } + + public override void ice_exception(Ice.Exception ex) + { + test(ex is Ice.NoEndpointException); + callback.called(); + } + + public bool check() + { + return callback.check(); + } + + private Callback callback = new Callback(); + } + + private class AMI_MyClass_opByteExI : Test.AMI_MyClass_opByte + { + public override void ice_response(byte r, byte b) + { + test(false); + } + + public override void ice_exception(Ice.Exception ex) + { + test(ex is Ice.TwowayOnlyException); + callback.called(); + } + + public bool check() + { + return callback.check(); + } + + private Callback callback = new Callback(); + } + + internal static void onewaysAMI(Ice.Communicator communicator, Test.MyClassPrx p) + { + p = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + + { + AMI_MyClass_opVoidI cb = new AMI_MyClass_opVoidI(); + p.opVoid_async(cb); + // Let's check if we can reuse the same callback object for another call. + p.opVoid_async(cb); + } + + { + // Check that a call to a void operation raises NoEndpointException + // in the ice_exception() callback instead of at the point of call. + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); + AMI_MyClass_opVoidExI cb = new AMI_MyClass_opVoidExI(); + try + { + indirect.opVoid_async(cb); + } + catch(System.Exception) + { + test(false); + } + test(cb.check()); + } + + { + AMI_MyClass_opByteExI cb = new AMI_MyClass_opByteExI(); + p.opByte_async(cb, (byte)0xff, (byte)0x0f); + test(cb.check()); + } + } +} diff --git a/cs/test/Ice/operations/TwowaysAMI.cs b/cs/test/Ice/operations/TwowaysAMI.cs index e7cd9197d70..5527509b149 100755 --- a/cs/test/Ice/operations/TwowaysAMI.cs +++ b/cs/test/Ice/operations/TwowaysAMI.cs @@ -89,7 +89,7 @@ public class TwowaysAMI public override void ice_exception(Ice.Exception ex) { - test(ex is Ice.TwowayOnlyException); + test(ex is Ice.NoEndpointException); callback.called(); } @@ -132,7 +132,7 @@ public class TwowaysAMI public override void ice_exception(Ice.Exception ex) { - test(ex is Ice.TwowayOnlyException); + test(ex is Ice.NoEndpointException); callback.called(); } @@ -963,13 +963,13 @@ public class TwowaysAMI internal static void twowaysAMI(Ice.Communicator communicator, Test.MyClassPrx p) { { - // Check that a call to a void operation raises TwowayOnlyException + // Check that a call to a void operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test.MyClassPrx oneway = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); AMI_MyClass_opVoidExI cb = new AMI_MyClass_opVoidExI(); try { - oneway.opVoid_async(cb); + indirect.opVoid_async(cb); } catch(Ice.Exception) { @@ -979,13 +979,13 @@ public class TwowaysAMI } { - // Check that a call to a twoway operation raises TwowayOnlyException + // Check that a call to a twoway operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test.MyClassPrx oneway = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); AMI_MyClass_opByteExI cb = new AMI_MyClass_opByteExI(); try { - oneway.opByte_async(cb, (byte)0, (byte)0); + indirect.opByte_async(cb, (byte)0, (byte)0); } catch(Ice.Exception) { diff --git a/cs/test/Makefile.mak b/cs/test/Makefile.mak index eb073fc0b50..85b57822a66 100755 --- a/cs/test/Makefile.mak +++ b/cs/test/Makefile.mak @@ -11,7 +11,7 @@ top_srcdir = .. !include $(top_srcdir)\config\Make.rules.mak.cs -SUBDIRS = Slice IceUtil Ice Glacier2 IceGrid IceSSL +SUBDIRS = Slice IceUtil Ice Glacier2 IceGrid #IceSSL $(EVERYTHING):: @for %i in ( $(SUBDIRS) ) do \ diff --git a/java/allTests.py b/java/allTests.py index a8a563a91ed..b55804006a1 100755 --- a/java/allTests.py +++ b/java/allTests.py @@ -45,6 +45,7 @@ tests = [ "Ice/hold", "Ice/retry", "Ice/timeout", + "Ice/background", "Ice/servantLocator", "Ice/threads", "Ice/interceptor", diff --git a/java/src/Freeze/ObjectStore.java b/java/src/Freeze/ObjectStore.java index bf176a36dff..df7593db2c2 100644 --- a/java/src/Freeze/ObjectStore.java +++ b/java/src/Freeze/ObjectStore.java @@ -313,9 +313,9 @@ class ObjectStore implements IceUtil.Store { IceInternal.BasicStream os = new IceInternal.BasicStream(Ice.Util.getInstance(communicator)); v.__write(os); - java.nio.ByteBuffer buf = os.prepareWrite(); - byte[] r = new byte[buf.limit()]; - buf.get(r); + IceInternal.Buffer buf = os.prepareWrite(); + byte[] r = new byte[buf.size()]; + buf.b.get(r); return r; } @@ -324,10 +324,10 @@ class ObjectStore implements IceUtil.Store { IceInternal.BasicStream is = new IceInternal.BasicStream(Ice.Util.getInstance(communicator)); is.resize(b.length, true); - java.nio.ByteBuffer buf = is.prepareRead(); - buf.position(0); - buf.put(b); - buf.position(0); + IceInternal.Buffer buf = is.getBuffer(); + buf.b.position(0); + buf.b.put(b); + buf.b.position(0); Ice.Identity key = new Ice.Identity(); key.__read(is); return key; @@ -341,9 +341,9 @@ class ObjectStore implements IceUtil.Store v.__write(os); os.writePendingObjects(); os.endWriteEncaps(); - java.nio.ByteBuffer buf = os.prepareWrite(); - byte[] r = new byte[buf.limit()]; - buf.get(r); + IceInternal.Buffer buf = os.prepareWrite(); + byte[] r = new byte[buf.size()]; + buf.b.get(r); return r; } @@ -353,10 +353,10 @@ class ObjectStore implements IceUtil.Store IceInternal.BasicStream is = new IceInternal.BasicStream(Ice.Util.getInstance(communicator)); is.sliceObjects(false); is.resize(b.length, true); - java.nio.ByteBuffer buf = is.prepareRead(); - buf.position(0); - buf.put(b); - buf.position(0); + IceInternal.Buffer buf = is.getBuffer(); + buf.b.position(0); + buf.b.put(b); + buf.b.position(0); ObjectRecord rec= new ObjectRecord(); is.startReadEncaps(); rec.__read(is); diff --git a/java/src/Ice/AMI_Object_ice_flushBatchRequests.java b/java/src/Ice/AMI_Object_ice_flushBatchRequests.java new file mode 100644 index 00000000000..ca68d1c2382 --- /dev/null +++ b/java/src/Ice/AMI_Object_ice_flushBatchRequests.java @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package Ice; + +public abstract class AMI_Object_ice_flushBatchRequests extends IceInternal.BatchOutgoingAsync +{ + public abstract void ice_exception(LocalException ex); + + public final void __invoke(Ice.ObjectPrx prx) + { + Ice._ObjectDel delegate; + IceInternal.RequestHandler handler; + try + { + Ice.ObjectPrxHelperBase proxy = (Ice.ObjectPrxHelperBase)prx; + __prepare(proxy.__reference().getInstance()); + delegate = proxy.__getDelegate(true); + handler = delegate.__getRequestHandler(); + } + catch(Ice.LocalException ex) + { + __finished(ex); + return; + } + + handler.flushAsyncBatchRequests(this); + } +} diff --git a/java/src/Ice/ConnectionI.java b/java/src/Ice/ConnectionI.java index e1990c041a7..efdb68da8c1 100644 --- a/java/src/Ice/ConnectionI.java +++ b/java/src/Ice/ConnectionI.java @@ -9,68 +9,118 @@ package Ice; -public final class ConnectionI extends IceInternal.EventHandler implements Connection +public final class ConnectionI extends IceInternal.EventHandler + implements Connection, IceInternal.SelectorThread.SocketReadyCallback { + public interface StartCallback + { + void connectionStartCompleted(ConnectionI connection); + void connectionStartFailed(ConnectionI connection, Ice.LocalException ex); + } + public void - validate() + start(StartCallback callback) { - if(!_endpoint.datagram()) // Datagram connections are always implicitly validated. + try { - boolean active; - synchronized(this) { - if(_thread != null && _thread != Thread.currentThread()) + _startCallback = callback; + + // + // The connection might already be closed if the communicator was destroyed. + // + if(_state == StateClosed) { - // - // In thread per connection mode, this connection's thread - // will take care of connection validation. Therefore all we - // have to do here is to wait until this thread has completed - // validation. - // - while(_state == StateNotValidated) + assert(_exception != null); + throw _exception; + } + + // + // In thread per connection mode, we create the thread for the connection. The + // intialization and validation of the connection is taken care of by the thread + // per connection. If a callback is given, no need to wait, the thread will notify + // the callback, otherwise wait until the connection is validated. + // + if(_threadPerConnection) + { + try { - try + _thread = new ThreadPerConnection(); + _thread.start(); + } + catch(java.lang.Exception ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + _logger.error("cannot create thread for connection:\n" + sw.toString()); + + // + // Clean up. + // + _thread = null; + _state = StateClosed; + + Ice.SyscallException e = new Ice.SyscallException(); + e.initCause(ex); + throw e; + } + + if(callback == null) // Wait for the connection to be validated. + { + while(_state <= StateNotValidated) { - wait(); + try + { + wait(); + } + catch(InterruptedException ex) + { + } } - catch(InterruptedException ex) + + if(_state >= StateClosing) { + assert(_exception != null); + throw _exception; } } - - if(_state >= StateClosing) - { - assert(_exception != null); - throw _exception; - } - - return; + return; // We're done. } + } - // - // The connection might already be closed (e.g.: the communicator - // was destroyed or object adapter deactivated.) - // - assert(_state == StateNotValidated || _state == StateClosed); + assert(!_threadPerConnection); + + // + // Initialize the connection transceiver and then validate the connection. + // + IceInternal.SocketStatus status = initialize(); + if(status == IceInternal.SocketStatus.Finished) + { + status = validate(); + } + + if(status == IceInternal.SocketStatus.Finished) + { + finishStart(null); + return; // We're done! + } + + // + // If the initialization or validation couldn't be completed without potentially + // blocking, we register the connection with the selector thread and return. + // + + synchronized(this) + { if(_state == StateClosed) { assert(_exception != null); throw _exception; } - - if(_adapter != null) - { - active = true; // The server side has the active role for connection validation. - } - else - { - active = false; // The client side has the passive role for connection validation. - } - } - try - { int timeout; IceInternal.DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); if(defaultsAndOverrides.overrideConnectTimeout) @@ -81,159 +131,76 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { timeout = _endpoint.timeout(); } + + _sendInProgress = true; + _selectorThread._register(_transceiver.fd(), this, status, timeout); + } + } + catch(Ice.LocalException ex) + { + synchronized(this) + { + setState(StateClosed, ex); - if(active) + // + // If start is called with a callback, the callback is notified either by the + // thread per conncetion or the thread pool. + // + if(callback != null) { - synchronized(_sendMutex) + if(!_threadPerConnection) { - if(_transceiver == null) // Has the transceiver already been closed? - { - assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } - - IceInternal.BasicStream os = new IceInternal.BasicStream(_instance); - os.writeBlob(IceInternal.Protocol.magic); - os.writeByte(IceInternal.Protocol.protocolMajor); - os.writeByte(IceInternal.Protocol.protocolMinor); - os.writeByte(IceInternal.Protocol.encodingMajor); - os.writeByte(IceInternal.Protocol.encodingMinor); - os.writeByte(IceInternal.Protocol.validateConnectionMsg); - os.writeByte((byte)0); // Compression status (always zero for validate connection). - os.writeInt(IceInternal.Protocol.headerSize); // Message size. - IceInternal.TraceUtil.traceHeader("sending validate connection", os, _logger, _traceLevels); - try - { - _transceiver.write(os, timeout); - } - catch(Ice.TimeoutException ex) - { - throw new Ice.ConnectTimeoutException(); - } + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. } + return; } - else + + // + // Close the transceiver if there's no thread per connection. Otherwise, wait + // for the thread per connection to take care of it. + // + if(_thread == null && _transceiver != null) { - IceInternal.BasicStream is = new IceInternal.BasicStream(_instance); - is.resize(IceInternal.Protocol.headerSize, true); - is.pos(0); try { - _transceiver.read(is, timeout); - } - catch(Ice.TimeoutException ex) - { - throw new Ice.ConnectTimeoutException(); - } - assert(is.pos() == IceInternal.Protocol.headerSize); - is.pos(0); - byte[] m = is.readBlob(4); - if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || - m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) - { - BadMagicException ex = new BadMagicException(); - ex.badMagic = m; - throw ex; - } - byte pMajor = is.readByte(); - byte pMinor = is.readByte(); - if(pMajor != IceInternal.Protocol.protocolMajor) - { - UnsupportedProtocolException e = new UnsupportedProtocolException(); - e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; - e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; - e.major = IceInternal.Protocol.protocolMajor; - e.minor = IceInternal.Protocol.protocolMinor; - throw e; - } - byte eMajor = is.readByte(); - byte eMinor = is.readByte(); - if(eMajor != IceInternal.Protocol.encodingMajor) - { - UnsupportedEncodingException e = new UnsupportedEncodingException(); - e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; - e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; - e.major = IceInternal.Protocol.encodingMajor; - e.minor = IceInternal.Protocol.encodingMinor; - throw e; - } - byte messageType = is.readByte(); - if(messageType != IceInternal.Protocol.validateConnectionMsg) - { - throw new ConnectionNotValidatedException(); + _transceiver.close(); } - byte compress = is.readByte(); // Ignore compression status for validate connection. - int size = is.readInt(); - if(size != IceInternal.Protocol.headerSize) + catch(LocalException e) { - throw new IllegalMessageSizeException(); + // Here we ignore any exceptions in close(). } - IceInternal.TraceUtil.traceHeader("received validate connection", is, _logger, _traceLevels); - } - } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - synchronized(this) - { - setState(StateClosed, ex.get()); - assert(_exception != null); - throw _exception; - } - } - catch(LocalException ex) - { - synchronized(this) - { - setState(StateClosed, ex); - assert(_exception != null); - throw _exception; + _transceiver = null; } } - } - - synchronized(this) - { - if(_acmTimeout > 0) - { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; - } - - // - // We start out in holding state. - // - setState(StateHolding); + + waitUntilFinished(); + throw ex; } } public synchronized void activate() { - while(_state == StateNotValidated) + if(_state <= StateNotValidated) { - try - { - wait(); - } - catch(InterruptedException ex) - { - } + return; } + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + setState(StateActive); } public synchronized void hold() { - while(_state == StateNotValidated) + if(_state <= StateNotValidated) { - try - { - wait(); - } - catch(InterruptedException ex) - { - } + return; } setState(StateHolding); @@ -243,60 +210,92 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne public final static int ObjectAdapterDeactivated = 0; public final static int CommunicatorDestroyed = 1; - public synchronized void + public void destroy(int reason) { - switch(reason) + boolean send = false; + synchronized(this) { - case ObjectAdapterDeactivated: + switch(reason) { - setState(StateClosing, new ObjectAdapterDeactivatedException()); - break; + case ObjectAdapterDeactivated: + { + send = setState(StateClosing, new ObjectAdapterDeactivatedException()); + break; + } + + case CommunicatorDestroyed: + { + send = setState(StateClosing, new CommunicatorDestroyedException()); + break; + } } - - case CommunicatorDestroyed: + } + + if(send) + { + try { - setState(StateClosing, new CommunicatorDestroyedException()); - break; + finishSendMessage(); + } + catch(Ice.LocalException ex) + { + // Ignore. } } } - public synchronized void + public void close(boolean force) { - if(force) - { - setState(StateClosed, new ForcedCloseConnectionException()); - } - else + boolean send = false; + synchronized(this) { - // - // If we do a graceful shutdown, then we wait until all - // outstanding requests have been completed. Otherwise, - // the CloseConnectionException will cause all outstanding - // requests to be retried, regardless of whether the - // server has processed them or not. - // - while(!_requests.isEmpty() || !_asyncRequests.isEmpty()) + if(force) { - try - { - wait(); - } - catch(InterruptedException ex) + setState(StateClosed, new ForcedCloseConnectionException()); + } + else + { + // + // If we do a graceful shutdown, then we wait until all + // outstanding requests have been completed. Otherwise, + // the CloseConnectionException will cause all outstanding + // requests to be retried, regardless of whether the + // server has processed them or not. + // + while(!_requests.isEmpty() || !_asyncRequests.isEmpty()) { + try + { + wait(); + } + catch(InterruptedException ex) + { + } } + + send = setState(StateClosing, new CloseConnectionException()); } + } - setState(StateClosing, new CloseConnectionException()); + if(send) + { + try + { + finishSendMessage(); + } + catch(Ice.LocalException ex) + { + // Ignore. + } } } public synchronized boolean - isDestroyed() + isActiveOrHolding() { - return _state >= StateClosing; + return _state > StateNotValidated && _state < StateClosing; } public boolean @@ -461,56 +460,57 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } } - public synchronized void + public void monitor() { - if(_state != StateActive) + boolean send = false; + synchronized(this) { - return; - } + if(_state != StateActive) + { + return; + } - // - // Check for timed out async requests. - // - java.util.Iterator i = _asyncRequests.entryIterator(); - while(i.hasNext()) - { - IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); - IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); - if(out.__timedOut()) + // + // Active connection management for idle connections. + // + if(_acmTimeout <= 0 || + !_requests.isEmpty() || !_asyncRequests.isEmpty() || + _batchStreamInUse || !_batchStream.isEmpty() || + _sendInProgress || _dispatchCount > 0) { - setState(StateClosed, new TimeoutException()); return; } + + if(IceInternal.Time.currentMonotonicTimeMillis() >= _acmAbsoluteTimeoutMillis) + { + send = setState(StateClosing, new ConnectionTimeoutException()); + } } - // - // Active connection management for idle connections. - // - if(_acmTimeout > 0 && - _requests.isEmpty() && _asyncRequests.isEmpty() && - !_batchStreamInUse && _batchStream.isEmpty() && - _dispatchCount == 0) + if(send) { - if(IceInternal.Time.currentMonotonicTimeMillis() >= _acmAbsoluteTimeoutMillis) + try { - setState(StateClosing, new ConnectionTimeoutException()); - return; + finishSendMessage(); } - } + catch(Ice.LocalException ex) + { + // Ignore. + } + } } - public void - sendRequest(IceInternal.BasicStream os, IceInternal.Outgoing out, boolean compress) + public boolean + sendRequest(IceInternal.Outgoing out, boolean compress, boolean response) throws IceInternal.LocalExceptionWrapper { int requestId = 0; - IceInternal.BasicStream stream = null; + final IceInternal.BasicStream os = out.os(); + boolean send = false; synchronized(this) { - assert(!(out != null && _endpoint.datagram())); // Twoway requests cannot be datagrams. - if(_exception != null) { // @@ -524,10 +524,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne assert(_state > StateNotValidated); assert(_state < StateClosing); - // - // Only add to the request map if this is a twoway call. - // - if(out != null) + if(response) { // // Create a new unique request ID. @@ -544,127 +541,67 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // os.pos(IceInternal.Protocol.headerSize); os.writeInt(requestId); + } + + // + // Send the message. If it can't be sent without blocking the message is added + // to _sendStreams and it will be sent by the selector thread or by this thread + // if flush is true. + // + try + { + send = sendMessage(new OutgoingMessage(out, out.os(), compress, response), false); + } + catch(Ice.LocalException ex) + { + setState(StateClosed, ex); + assert(_exception != null); + throw _exception; + } + if(response) + { // // Add to the requests map. // _requests.put(requestId, out); } - stream = doCompress(os, _overrideCompress ? _overrideCompressValue : compress); - - if(_acmTimeout > 0) + if(!send) { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + return !_sendInProgress && _queuedStreams.isEmpty(); // The request was sent if it's not queued! } } - try + if(send) { - synchronized(_sendMutex) - { - if(_transceiver == null) // Has the transceiver already been closed? - { - assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } - - // - // Send the request. - // - IceInternal.TraceUtil.traceRequest("sending request", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); - } - } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - synchronized(this) + try { - setState(StateClosed, ex.get()); - assert(_exception != null); - - if(out != null) - { - // - // If the request has already been removed from - // the request map, we are out of luck. It would - // mean that finished() has been called already, - // and therefore the exception has been set using - // the Outgoing::finished() callback. In this - // case, we cannot throw the exception here, - // because we must not both raise an exception and - // have Outgoing::finished() called with an - // exception. This means that in some rare cases, - // a request will not be retried even though it - // could. But I honestly don't know how I could - // avoid this, without a very elaborate and - // complex design, which would be bad for - // performance. - // - IceInternal.Outgoing o = (IceInternal.Outgoing)_requests.remove(requestId); - if(o != null) - { - assert(o == out); - throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); - } - } - else - { - throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); - } + finishSendMessage(); } - } - catch(LocalException ex) - { - synchronized(this) + catch(Ice.LocalException ex) { - setState(StateClosed, ex); assert(_exception != null); - - if(out != null) - { - // - // If the request has already been removed from - // the request map, we are out of luck. It would - // mean that finished() has been called already, - // and therefore the exception has been set using - // the Outgoing::finished() callback. In this - // case, we cannot throw the exception here, - // because we must not both raise an exception and - // have Outgoing::finished() called with an - // exception. This means that in some rare cases, - // a request will not be retried even though it - // could. But I honestly don't know how I could - // avoid this, without a very elaborate and - // complex design, which would be bad for - // performance. - // - IceInternal.Outgoing o = (IceInternal.Outgoing)_requests.remove(requestId); - if(o != null) - { - assert(o == out); - throw _exception; - } - } - else + if(!response) // Twoway calls are notified through finished() { - throw _exception; + throw ex; } } } + + return true; // The request was sent. } public void - sendAsyncRequest(IceInternal.BasicStream os, IceInternal.OutgoingAsync out, boolean compress) + sendAsyncRequest(IceInternal.OutgoingAsync out, boolean compress, boolean response) throws IceInternal.LocalExceptionWrapper { int requestId = 0; - IceInternal.BasicStream stream = null; + final IceInternal.BasicStream os = out.__os(); + boolean send; synchronized(this) { - assert(!_endpoint.datagram()); // Twoway requests cannot be datagrams, and async implies twoway. - if(_exception != null) { // @@ -678,109 +615,57 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne assert(_state > StateNotValidated); assert(_state < StateClosing); - // - // Create a new unique request ID. - // - requestId = _nextRequestId++; - if(requestId <= 0) + if(response) { - _nextRequestId = 1; + // + // Create a new unique request ID. + // requestId = _nextRequestId++; + if(requestId <= 0) + { + _nextRequestId = 1; + requestId = _nextRequestId++; + } + + // + // Fill in the request ID. + // + os.pos(IceInternal.Protocol.headerSize); + os.writeInt(requestId); } - - // - // Fill in the request ID. - // - os.pos(IceInternal.Protocol.headerSize); - os.writeInt(requestId); - - // - // Add to the async requests map. - // - _asyncRequests.put(requestId, out); - - stream = doCompress(os, _overrideCompress ? _overrideCompressValue : compress); - if(_acmTimeout > 0) + try { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + send = sendMessage(new OutgoingMessage(out, out.__os(), compress, response), false); } - } - - try - { - synchronized(_sendMutex) + catch(Ice.LocalException ex) { - if(_transceiver == null) // Has the transceiver already been closed? - { - assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } + setState(StateClosed, ex); + assert(_exception != null); + throw _exception; + } + if(response) + { // - // Send the request. + // Add to the async requests map. // - IceInternal.TraceUtil.traceRequest("sending asynchronous request", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + _asyncRequests.put(requestId, out); } } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + + if(send) { - synchronized(this) + try { - setState(StateClosed, ex.get()); - assert(_exception != null); - - // - // If the request has already been removed from the - // async request map, we are out of luck. It would - // mean that finished() has been called already, and - // therefore the exception has been set using the - // OutgoingAsync::__finished() callback. In this case, - // we cannot throw the exception here, because we must - // not both raise an exception and have - // OutgoingAsync::__finished() called with an - // exception. This means that in some rare cases, a - // request will not be retried even though it - // could. But I honestly don't know how I could avoid - // this, without a very elaborate and complex design, - // which would be bad for performance. - // - IceInternal.OutgoingAsync o = (IceInternal.OutgoingAsync)_asyncRequests.remove(requestId); - if(o != null) - { - assert(o == out); - throw new IceInternal.LocalExceptionWrapper(_exception, ex.retry()); - } + finishSendMessage(); } - } - catch(LocalException ex) - { - synchronized(this) + catch(Ice.LocalException ex) { - setState(StateClosed, ex); assert(_exception != null); - - // - // If the request has already been removed from the - // async request map, we are out of luck. It would - // mean that finished() has been called already, and - // therefore the exception has been set using the - // OutgoingAsync::__finished() callback. In this case, - // we cannot throw the exception here, because we must - // not both raise an exception and have - // OutgoingAsync::__finished() called with an - // exception. This means that in some rare cases, a - // request will not be retried even though it - // could. But I honestly don't know how I could avoid - // this, without a very elaborate and complex design, - // which would be bad for performance. - // - IceInternal.OutgoingAsync o = (IceInternal.OutgoingAsync)_asyncRequests.remove(requestId); - if(o != null) + if(!response) // Twoway calls are notified through finished() { - assert(o == out); - throw _exception; + throw ex; } } } @@ -789,6 +674,9 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne public synchronized void prepareBatchRequest(IceInternal.BasicStream os) { + // + // Wait if flushing is currently in progress. + // while(_batchStreamInUse && _exception == null) { try @@ -834,60 +722,110 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne public void finishBatchRequest(IceInternal.BasicStream os, boolean compress) { - boolean autoflush = false; - byte[] lastRequest = null; - - synchronized(this) + boolean send = false; + try { - // - // Get the batch stream back. - // - _batchStream.swap(os); - - if(_batchAutoFlush) + synchronized(this) { - synchronized(_sendMutex) + // + // Get the batch stream back. + // + _batchStream.swap(os); + + if(_exception != null) + { + throw _exception; + } + + boolean flush = false; + if(_batchAutoFlush) { - if(_transceiver == null) - { - assert(_exception != null); - throw _exception; // The exception is immutable at this point. - } // - // Throw memory limit exception if the first - // message added causes us to go over - // limit. Otherwise put aside the marshalled - // message that caused limit to be exceeded and - // rollback stream to the marker. + // Throw memory limit exception if the first message added causes us to go over + // limit. Otherwise put aside the marshalled message that caused limit to be + // exceeded and rollback stream to the marker. try { - _transceiver.checkSendSize(_batchStream, _instance.messageSizeMax()); + _transceiver.checkSendSize(_batchStream.getBuffer(), _instance.messageSizeMax()); } catch(Ice.LocalException ex) { - if(_batchRequestNum == 0) + if(_batchRequestNum > 0) + { + flush = true; + } + else { - resetBatch(true); throw ex; } + } + } + + if(flush) + { + // + // Temporarily save the last request. + // + byte[] lastRequest = new byte[_batchStream.size() - _batchMarker]; + IceInternal.Buffer buffer = _batchStream.getBuffer(); + buffer.b.position(_batchMarker); + buffer.b.get(lastRequest); + _batchStream.resize(_batchMarker, false); - lastRequest = new byte[_batchStream.size() - _batchMarker]; - java.nio.ByteBuffer buffer = _batchStream.prepareRead(); - buffer.position(_batchMarker); - buffer.get(lastRequest); - _batchStream.resize(_batchMarker, false); - autoflush = true; + try + { + // + // Fill in the number of requests in the batch. + // + _batchStream.pos(IceInternal.Protocol.headerSize); + _batchStream.writeInt(_batchRequestNum); + + OutgoingMessage message = new OutgoingMessage(_batchStream, _batchRequestCompress, true); + send = sendMessage(message, false); + if(send) + { + // + // If the request can't be sent immediately and this is a foreground send, + // we adopt the stream to be able to re-use _batchStream immediately. + // + message.adopt(); + } + } + catch(Ice.LocalException ex) + { + setState(StateClosed, ex); + assert(_exception != null); + throw _exception; } + + // + // Reset the batch stream. + // + _batchStream = new IceInternal.BasicStream(_instance, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + // + // Check again if the last request doesn't exceed the maximum message size. + // + if(IceInternal.Protocol.requestBatchHdr.length + lastRequest.length > _instance.messageSizeMax()) + { + throw new MemoryLimitException(); + } + + // + // Start a new batch with the last message that caused us to go over the limit. + // + _batchStream.writeBlob(IceInternal.Protocol.requestBatchHdr); + _batchStream.writeBlob(lastRequest); } - } - if(!autoflush) - { // // Increment the number of requests in the batch. // ++_batchRequestNum; - + // // We compress the whole batch if there is at least one compressed // message. @@ -905,258 +843,247 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne notifyAll(); } } - - if(autoflush) + catch(Ice.LocalException ex) { - // - // We have to keep _batchStreamInUse set until after we insert the - // saved marshalled data into a new stream. - // - flushBatchRequestsInternal(true); - - synchronized(this) + abortBatchRequest(); + if(send) { - // - // Throw memory limit exception if the message that caused us to go over - // limit causes us to exceed the limit by itself. - // - if(IceInternal.Protocol.requestBatchHdr.length + lastRequest.length > _instance.messageSizeMax()) - { - resetBatch(true); - throw new MemoryLimitException(); - } - - // - // Start a new batch with the last message that caused us to - // go over the limit. - // - try - { - _batchStream.writeBlob(IceInternal.Protocol.requestBatchHdr); - _batchStream.writeBlob(lastRequest); - } - catch(LocalException ex) - { - setState(StateClosed, ex); - throw ex; - } - - if(compress) - { - _batchRequestCompress = true; - } - - // - // Notify that the batch stream not in use anymore. - // - ++_batchRequestNum; - _batchStreamInUse = false; - notifyAll(); + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. } + throw ex; + } + + if(send) + { + finishSendMessage(); // Let exceptions go through to report auto-flush failures to the caller. } } public synchronized void abortBatchRequest() { - // - // Reset the batch stream. We cannot save old requests - // in the batch stream, as they might be corrupted due to - // incomplete marshaling. - // - resetBatch(true); + _batchStream = new IceInternal.BasicStream(_instance, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + assert(_batchStreamInUse); + _batchStreamInUse = false; + notifyAll(); } public void flushBatchRequests() { - flushBatchRequestsInternal(false); + IceInternal.BatchOutgoing out = new IceInternal.BatchOutgoing(this, _instance); + out.invoke(); } - private void - flushBatchRequestsInternal(boolean ignoreInUse) + public boolean + flushBatchRequests(IceInternal.BatchOutgoing out) { - IceInternal.BasicStream stream = null; - + boolean send = false; synchronized(this) { - if(!ignoreInUse) + while(_batchStreamInUse && _exception == null) { - while(_batchStreamInUse && _exception == null) + try + { + wait(); + } + catch(InterruptedException ex) { - try - { - wait(); - } - catch(InterruptedException ex) - { - } } } - + if(_exception != null) { throw _exception; } - if(_batchStream.isEmpty()) + if(_batchRequestNum == 0) { - return; // Nothing to do. + return true; } - assert(_state > StateNotValidated); - assert(_state < StateClosing); - - // - // Fill in the message size. - // - _batchStream.pos(10); - _batchStream.writeInt(_batchStream.size()); - // // Fill in the number of requests in the batch. // + _batchStream.pos(IceInternal.Protocol.headerSize); _batchStream.writeInt(_batchRequestNum); + + _batchStream.swap(out.os()); - stream = doCompress(_batchStream, _overrideCompress ? _overrideCompressValue : _batchRequestCompress); - - if(_acmTimeout > 0) + try { - _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + OutgoingMessage message = new OutgoingMessage(out, out.os(), _batchRequestCompress, false); + send = sendMessage(message, false); } - + catch(Ice.LocalException ex) + { + setState(StateClosed, ex); + assert(_exception != null); + throw _exception; + } + // - // Prevent that new batch requests are added while we are - // flushing. + // Reset the batch stream. // - _batchStreamInUse = true; + _batchStream = new IceInternal.BasicStream(_instance, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; + + if(!send) + { + return !_sendInProgress && _queuedStreams.isEmpty(); // The request was sent if it's not queued! + } } - try + if(send) { - synchronized(_sendMutex) + finishSendMessage(); + } + return true; + } + + public void + flushAsyncBatchRequests(IceInternal.BatchOutgoingAsync outAsync) + { + boolean send = false; + synchronized(this) + { + while(_batchStreamInUse && _exception == null) { - if(_transceiver == null) // Has the transceiver already been closed? + try + { + wait(); + } + catch(InterruptedException ex) { - assert(_exception != null); - throw _exception; // The exception is immutable at this point. } - - // - // Send the batch request. - // - IceInternal.TraceUtil.traceBatchRequest("sending batch request", _batchStream, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); } - } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - synchronized(this) + + if(_exception != null) { - setState(StateClosed, ex.get()); - assert(_exception != null); - - // - // Since batch requests are all oneways (or datagrams), we - // must report the exception to the caller. - // throw _exception; } - } - catch(LocalException ex) - { - synchronized(this) + + if(_batchRequestNum == 0) + { + return; + } + + // + // Fill in the number of requests in the batch. + // + _batchStream.pos(IceInternal.Protocol.headerSize); + _batchStream.writeInt(_batchRequestNum); + + _batchStream.swap(outAsync.__os()); + + try + { + OutgoingMessage message = new OutgoingMessage(outAsync, outAsync.__os(), _batchRequestCompress, false); + send = sendMessage(message, false); + } + catch(Ice.LocalException ex) { setState(StateClosed, ex); assert(_exception != null); - - // - // Since batch requests are all oneways (or datagrams), we - // must report the exception to the caller. - // throw _exception; } - } - - synchronized(this) - { + // - // Reset the batch stream, and notify that flushing is over. + // Reset the batch stream. // - resetBatch(!ignoreInUse); + _batchStream = new IceInternal.BasicStream(_instance, _batchAutoFlush); + _batchRequestNum = 0; + _batchRequestCompress = false; + _batchMarker = 0; } - } - private void - resetBatch(boolean resetInUse) - { - _batchStream = new IceInternal.BasicStream(_instance, _batchAutoFlush); - _batchRequestNum = 0; - _batchRequestCompress = false; - - // - // Notify about the batch stream not being in use anymore. - // - if(resetInUse) + if(send) { - assert(_batchStreamInUse); - _batchStreamInUse = false; - notifyAll(); + finishSendMessage(); } } public void sendResponse(IceInternal.BasicStream os, byte compressFlag) { - IceInternal.BasicStream stream = null; - try + boolean send = false; + synchronized(this) { - synchronized(_sendMutex) + assert(_state > StateNotValidated); + + try { - if(_transceiver == null) // Has the transceiver already been closed? + if(--_dispatchCount == 0) + { + notifyAll(); + } + + if(_state == StateClosed) { assert(_exception != null); - throw _exception; // The exception is immutable at this point. + throw _exception; } - stream = doCompress(os, compressFlag != 0); + send = sendMessage(new OutgoingMessage(os, compressFlag != 0, true), false); + + if(_state == StateClosing && _dispatchCount == 0) + { + initiateShutdown(true); + } - // - // Send the reply. - // - IceInternal.TraceUtil.traceReply("sending reply", os, _logger, _traceLevels); - _transceiver.write(stream, _endpoint.timeout()); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } } - } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - synchronized(this) + catch(LocalException ex) { - setState(StateClosed, ex.get()); + setState(StateClosed, ex); } } - catch(LocalException ex) + + if(send) { - synchronized(this) + try { - setState(StateClosed, ex); + finishSendMessage(); + } + catch(Ice.LocalException ex) + { + // Ignore. } } + } + public void + sendNoResponse() + { + boolean send = false; synchronized(this) { assert(_state > StateNotValidated); - try { if(--_dispatchCount == 0) { notifyAll(); } - + + if(_state == StateClosed) + { + assert(_exception != null); + throw _exception; + } + if(_state == StateClosing && _dispatchCount == 0) { - initiateShutdown(); + send = initiateShutdown(false); } if(_acmTimeout > 0) @@ -1164,49 +1091,29 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; } } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - setState(StateClosed, ex.get()); - } catch(LocalException ex) { setState(StateClosed, ex); } } - } - public synchronized void - sendNoResponse() - { - assert(_state > StateNotValidated); - - try + if(send) { - if(--_dispatchCount == 0) + try { - notifyAll(); + finishSendMessage(); } - - if(_state == StateClosing && _dispatchCount == 0) + catch(Ice.LocalException ex) { - initiateShutdown(); + // Ignore. } } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - setState(StateClosed, ex.get()); - } - catch(LocalException ex) - { - setState(StateClosed, ex); - } } public IceInternal.EndpointI endpoint() { - // No mutex protection necessary, _endpoint is immutable. - return _endpoint; + return _endpoint; // No mutex protection necessary, _endpoint is immutable. } public boolean @@ -1218,11 +1125,15 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne public synchronized void setAdapter(ObjectAdapter adapter) { - if(_exception != null) + if(_state == StateClosing || _state == StateClosed) { + assert(_exception != null); throw _exception; } - + else if(_state <= StateNotValidated) + { + return; + } assert(_state < StateClosing); _adapter = adapter; @@ -1253,7 +1164,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne return _adapter; } - public synchronized ObjectPrx + public ObjectPrx createProxy(Identity ident) { // @@ -1262,9 +1173,8 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // ConnectionI[] connections = new ConnectionI[1]; connections[0] = this; - IceInternal.Reference ref = - _instance.referenceFactory().create(ident, _instance.getDefaultContext(), "", - IceInternal.Reference.ModeTwoway, connections); + IceInternal.Reference ref = _instance.referenceFactory().create(ident, _instance.getDefaultContext(), "", + IceInternal.Reference.ModeTwoway, connections); return _instance.proxyFactory().referenceToProxy(ref); } @@ -1291,7 +1201,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { assert(!_threadPerConnection); // Only for use with a thread pool. - return _transceiver.read(stream, 0); + return _transceiver.read(stream.getBuffer(), 0, _hasMoreData); // // Updating _acmAbsoluteTimeoutMillis is too expensive here, @@ -1301,6 +1211,12 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // } + public boolean + hasMoreData() + { + return _hasMoreData.value; + } + public void message(IceInternal.BasicStream stream, IceInternal.ThreadPool threadPool) { @@ -1355,69 +1271,58 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne assert(!_threadPerConnection); // Only for use with a thread pool. threadPool.promoteFollower(); - - LocalException localEx = null; - - IceInternal.IntMap requests = null; - IceInternal.IntMap asyncRequests = null; + + Ice.LocalException localEx = null; synchronized(this) { --_finishedCount; - if(_finishedCount == 0 && _state == StateClosed) + if(_finishedCount > 0 || _state != StateClosed || _sendInProgress) { - // - // We must make sure that nobody is sending when we - // close the transceiver. - // - synchronized(_sendMutex) - { - try - { - _transceiver.close(); - } - catch(LocalException ex) - { - localEx = ex; - } - - _transceiver = null; - notifyAll(); - } + return; } - - if(_state == StateClosed || _state == StateClosing) + + try { - requests = _requests; - _requests = new IceInternal.IntMap(); - - asyncRequests = _asyncRequests; - _asyncRequests = new IceInternal.IntMap(); + _transceiver.close(); } + catch(LocalException ex) + { + localEx = ex; + } + + _transceiver = null; + notifyAll(); } + + finishStart(_exception); - if(requests != null) + java.util.Iterator i = _queuedStreams.iterator(); + while(i.hasNext()) { - java.util.Iterator i = requests.entryIterator(); - while(i.hasNext()) - { - IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); - IceInternal.Outgoing out = (IceInternal.Outgoing)e.getValue(); - out.finished(_exception); // The exception is immutable at this point. - } + OutgoingMessage message = (OutgoingMessage)i.next(); + message.finished(_exception); } + _queuedStreams.clear(); - if(asyncRequests != null) + i = _requests.entryIterator(); // _requests is immutable at this point. + while(i.hasNext()) { - java.util.Iterator i = asyncRequests.entryIterator(); - while(i.hasNext()) - { - IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); - IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); - out.__finished(_exception); // The exception is immutable at this point. - } + IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); + IceInternal.Outgoing out = (IceInternal.Outgoing)e.getValue(); + out.finished(_exception); // The exception is immutable at this point. } + _requests.clear(); + i = _asyncRequests.entryIterator(); // _asyncRequests is immutable at this point. + while(i.hasNext()) + { + IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); + IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); + out.__finished(_exception); // The exception is immutable at this point. + } + _asyncRequests.clear(); + if(localEx != null) { throw localEx; @@ -1477,6 +1382,147 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } // + // Operations from SocketReadyCallback + // + public IceInternal.SocketStatus + socketReady(boolean finished) + { + if(!finished) + { + try + { + // + // First, we check if there's something to send. If that's the case, the connection + // must be active and the only thing to do is send the queued streams. + // + if(!_sendStreams.isEmpty()) + { + if(!send(0)) + { + return IceInternal.SocketStatus.NeedWrite; + } + assert(_sendStreams.isEmpty()); + } + else + { + // + // If there's nothing to send, we're still validating the connection. + // + int state; + synchronized(this) + { + assert(_state == StateClosed || _state <= StateNotValidated); + + if(_state == StateClosed) + { + assert(_exception != null); + throw _exception; + } + + state = _state; + } + + if(state == StateNotInitialized) + { + IceInternal.SocketStatus status = initialize(); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + } + + if(state <= StateNotValidated) + { + IceInternal.SocketStatus status = validate(); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + } + + finishStart(null); + } + } + catch(Ice.LocalException ex) + { + synchronized(this) + { + setState(StateClosed, ex); + } + } + } + + // + // If there's no more data to send or if connection validation is finished, we checkout + // the connection state to figure out whether or not it's time to unregister with the + // selector thread. + // + + synchronized(this) + { + assert(_sendInProgress); + if(_state == StateClosed) + { + assert(_startCallback == null || (!_threadPerConnection && !_registeredWithPool)); + + _queuedStreams.addAll(0, _sendStreams); + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + notifyAll(); + return IceInternal.SocketStatus.Finished; + } + else if(_waitingForSend > 0) + { + _sendInProgress = false; + notifyAll(); + return IceInternal.SocketStatus.Finished; + } + else if(_queuedStreams.isEmpty()) + { + _sendInProgress = false; + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + return IceInternal.SocketStatus.Finished; + } + else + { + java.util.LinkedList streams = _queuedStreams; + _queuedStreams = _sendStreams; + _sendStreams = streams; + return IceInternal.SocketStatus.NeedWrite; // We're not finished yet, there's more data to send! + } + } + } + + public void + socketTimeout() + { + synchronized(this) + { + if(_state <= StateNotValidated) + { + setState(StateClosed, new ConnectTimeoutException()); + } + else if(_state <= StateClosing) + { + setState(StateClosed, new TimeoutException()); + } + } + } + + // // Only used by the SSL plug-in. // // The external party has to synchronize the connection, since the @@ -1492,29 +1538,32 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne IceInternal.EndpointI endpoint, ObjectAdapter adapter, boolean threadPerConnection) { super(instance); + + final Ice.InitializationData initData = instance.initializationData(); _threadPerConnection = threadPerConnection; _transceiver = transceiver; _desc = transceiver.toString(); _type = transceiver.type(); _endpoint = endpoint; _adapter = adapter; - _logger = instance.initializationData().logger; // Cached for better performance. + _logger = initData.logger; // Cached for better performance. _traceLevels = instance.traceLevels(); // Cached for better performance. _registeredWithPool = false; _finishedCount = 0; - _warn = _instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Connections") > 0 ? true : false; - _cacheBuffers = _instance.initializationData().properties.getPropertyAsIntWithDefault( - "Ice.CacheMessageBuffers", 1) == 1; + _warn = initData.properties.getPropertyAsInt("Ice.Warn.Connections") > 0 ? true : false; + _cacheBuffers = initData.properties.getPropertyAsIntWithDefault("Ice.CacheMessageBuffers", 1) == 1; _acmAbsoluteTimeoutMillis = 0; _nextRequestId = 1; - _batchAutoFlush = _instance.initializationData().properties.getPropertyAsIntWithDefault( - "Ice.BatchAutoFlush", 1) > 0 ? true : false; + _batchAutoFlush = initData.properties.getPropertyAsIntWithDefault("Ice.BatchAutoFlush", 1) > 0 ? true : false; _batchStream = new IceInternal.BasicStream(instance, _batchAutoFlush); _batchStreamInUse = false; _batchRequestNum = 0; _batchRequestCompress = false; + _batchMarker = 0; + _sendInProgress = false; + _waitingForSend = 0; _dispatchCount = 0; - _state = StateNotValidated; + _state = StateNotInitialized; _stateTime = IceInternal.Time.currentMonotonicTimeMillis(); if(_endpoint.datagram()) @@ -1533,8 +1582,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } } - int compressionLevel = - _instance.initializationData().properties.getPropertyAsIntWithDefault("Ice.Compression.Level", 1); + int compressionLevel = initData.properties.getPropertyAsIntWithDefault("Ice.Compression.Level", 1); if(compressionLevel < 1) { compressionLevel = 1; @@ -1553,17 +1601,17 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { _servantManager = null; } - - if(!threadPerConnection) + + try { - // - // Only set _threadPool if we really need it, i.e., if we are - // not in thread per connection mode. Thread pools have lazy - // initialization in Instance, and we don't want them to be - // created if they are not needed. - // - try + if(!threadPerConnection) { + // + // Only set _threadPool if we really need it, i.e., if we are + // not in thread per connection mode. Thread pools have lazy + // initialization in Instance, and we don't want them to be + // created if they are not needed. + // if(_adapter != null) { _threadPool = ((ObjectAdapterI)_adapter).getThreadPool(); @@ -1573,94 +1621,52 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne _threadPool = _instance.clientThreadPool(); } } - catch(java.lang.Exception ex) + else { - try - { - _transceiver.close(); - } - catch(LocalException e) - { - // Here we ignore any exceptions in close(). - } - - Ice.SyscallException e = new Ice.SyscallException(); - e.initCause(ex); - throw e; + _threadPool = null; // To satisfy the compiler. } + + _selectorThread = _instance.selectorThread(); + + _overrideCompress = _instance.defaultsAndOverrides().overrideCompress; + _overrideCompressValue = _instance.defaultsAndOverrides().overrideCompressValue; } - else + catch(Ice.LocalException ex) { - _threadPool = null; // To satisfy the compiler. + throw ex; + } + catch(java.lang.Exception ex) + { + Ice.SyscallException e = new Ice.SyscallException(); + e.initCause(ex); + throw e; } - - _overrideCompress = _instance.defaultsAndOverrides().overrideCompress; - _overrideCompressValue = _instance.defaultsAndOverrides().overrideCompressValue; } protected synchronized void finalize() throws Throwable { + IceUtil.Assert.FinalizerAssert(_startCallback == null); IceUtil.Assert.FinalizerAssert(_state == StateClosed); IceUtil.Assert.FinalizerAssert(_transceiver == null); IceUtil.Assert.FinalizerAssert(_dispatchCount == 0); IceUtil.Assert.FinalizerAssert(_thread == null); + IceUtil.Assert.FinalizerAssert(_queuedStreams.isEmpty()); + IceUtil.Assert.FinalizerAssert(_requests.isEmpty()); + IceUtil.Assert.FinalizerAssert(_asyncRequests.isEmpty()); super.finalize(); } - public void - start() - { - // - // If we are in thread per connection mode, create the thread for this connection. - // - if(_threadPerConnection) - { - try - { - _thread = new ThreadPerConnection(); - _thread.start(); - } - catch(java.lang.Exception ex) - { - java.io.StringWriter sw = new java.io.StringWriter(); - java.io.PrintWriter pw = new java.io.PrintWriter(sw); - ex.printStackTrace(pw); - pw.flush(); - _logger.error("cannot create thread for connection:\n" + sw.toString()); + private static final int StateNotInitialized = 0; + private static final int StateNotValidated = 1; + private static final int StateActive = 2; + private static final int StateHolding = 3; + private static final int StateClosing = 4; + private static final int StateClosed = 5; - try - { - _transceiver.close(); - } - catch(LocalException e) - { - // Here we ignore any exceptions in close(). - } - - // - // Clean up. - // - _transceiver = null; - _thread = null; - _state = StateClosed; - - Ice.SyscallException e = new Ice.SyscallException(); - e.initCause(ex); - throw e; - } - } - } - - private static final int StateNotValidated = 0; - private static final int StateActive = 1; - private static final int StateHolding = 2; - private static final int StateClosing = 3; - private static final int StateClosed = 4; - - private void + private boolean setState(int state, LocalException ex) { // @@ -1671,7 +1677,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne if(_state == state) // Don't switch twice. { - return; + return false; } if(_exception == null) @@ -1706,10 +1712,10 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // exceptions. Otherwise new requests may retry on a // connection that is not yet marked as closed or closing. // - setState(state); + return setState(state); } - private void + private boolean setState(int state) { // @@ -1724,24 +1730,34 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // // Skip graceful shutdown if we are destroyed before validation. // - if(_state == StateNotValidated && state == StateClosing) + if(_state <= StateNotValidated && state == StateClosing) { state = StateClosed; } if(_state == state) // Don't switch twice. { - return; + return false; } switch(state) { - case StateNotValidated: + case StateNotInitialized: { assert(false); break; } + case StateNotValidated: + { + if(_state != StateNotInitialized) + { + assert(_state == StateClosed); + return false; + } + break; + } + case StateActive: { // @@ -1750,7 +1766,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // if(_state != StateHolding && _state != StateNotValidated) { - return; + return false; } if(!_threadPerConnection) { @@ -1767,7 +1783,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // if(_state != StateActive && _state != StateNotValidated) { - return; + return false; } if(!_threadPerConnection) { @@ -1783,7 +1799,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // if(_state == StateClosed) { - return; + return false; } if(!_threadPerConnection) { @@ -1794,60 +1810,43 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne case StateClosed: { - if(_threadPerConnection) - { - // - // If we are in thread per connection mode, we - // shutdown both for reading and writing. This will - // unblock and read call with an exception. The thread - // per connection then closes the transceiver. - // - _transceiver.shutdownReadWrite(); - } - else if(_state == StateNotValidated) + if(_sendInProgress) { // - // If we change from not validated, we can close right - // away. - // - assert(!_registeredWithPool); - + // Unregister with both the pool and the selector thread. We unregister with + // the pool to ensure that it stops reading on the socket (otherwise, if the + // socket is closed the thread pool would spin always reading 0 from the FD). + // The selector thread will register again the FD with the pool once it's + // done. // - // We must make sure that nobody is sending when we - // close the transceiver. - // - synchronized(_sendMutex) + _selectorThread.unregister(_transceiver.fd()); + if(!_threadPerConnection) { - try - { - _transceiver.close(); - } - catch(LocalException ex) - { - // Here we ignore any exceptions in close(). - } + unregisterWithPool(); + } - _transceiver = null; - //notifyAll(); // We notify already below. + if(_state >= StateNotValidated) + { + _transceiver.shutdownWrite(); } } - else + else if(_startCallback == null && _state <= StateNotValidated || _threadPerConnection) { // - // Otherwise we first must make sure that we are - // registered, then we unregister, and let finished() - // do the close. + // If we are in thread per connection mode and the thread is started, we + // shutdown both for reading and writing. This will unblock the read call + // with an exception. The thread per connection closes the transceiver. // + _transceiver.shutdownReadWrite(); + } + else + { registerWithPool(); - unregisterWithPool(); - - // - // We must prevent any further writes when _state == StateClosed. - // However, functions such as sendResponse cannot acquire the main - // mutex in order to check _state. Therefore we shut down the write - // end of the transceiver, which causes subsequent write attempts - // to fail with an exception. + unregisterWithPool(); // Let finished() do the close. + // + // Prevent further writes. + // _transceiver.shutdownWrite(); } break; @@ -1882,58 +1881,536 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { try { - initiateShutdown(); - } - catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). - { - setState(StateClosed, ex.get()); + return initiateShutdown(false); } catch(LocalException ex) { setState(StateClosed, ex); } } + + return false; } - private void - initiateShutdown() - throws IceInternal.LocalExceptionWrapper // Java-specific workaround in Transceiver.write(). + private boolean + initiateShutdown(boolean queue) { assert(_state == StateClosing); assert(_dispatchCount == 0); if(!_endpoint.datagram()) { - synchronized(_sendMutex) + // + // Before we shut down, we send a close connection + // message. + // + IceInternal.BasicStream os = new IceInternal.BasicStream(_instance); + os.writeBlob(IceInternal.Protocol.magic); + os.writeByte(IceInternal.Protocol.protocolMajor); + os.writeByte(IceInternal.Protocol.protocolMinor); + os.writeByte(IceInternal.Protocol.encodingMajor); + os.writeByte(IceInternal.Protocol.encodingMinor); + os.writeByte(IceInternal.Protocol.closeConnectionMsg); + os.writeByte(_compressionSupported ? (byte)1 : (byte)0); + os.writeInt(IceInternal.Protocol.headerSize); // Message size. + + return sendMessage(new OutgoingMessage(os, false, false), queue); + + // + // The CloseConnection message should be sufficient. Closing the write + // end of the socket is probably an artifact of how things were done + // in IIOP. In fact, shutting down the write end of the socket causes + // problems on Windows by preventing the peer from using the socket. + // For example, the peer is no longer able to continue writing a large + // message after the socket is shutdown. + // + //_transceiver.shutdownWrite(); + } + + return false; + } + + private IceInternal.SocketStatus + initialize() + { + int timeout = 0; + if(_startCallback == null || _threadPerConnection) + { + IceInternal.DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideConnectTimeout) { - // - // Before we shut down, we send a close connection - // message. - // - IceInternal.BasicStream os = new IceInternal.BasicStream(_instance); - os.writeBlob(IceInternal.Protocol.magic); - os.writeByte(IceInternal.Protocol.protocolMajor); - os.writeByte(IceInternal.Protocol.protocolMinor); - os.writeByte(IceInternal.Protocol.encodingMajor); - os.writeByte(IceInternal.Protocol.encodingMinor); - os.writeByte(IceInternal.Protocol.closeConnectionMsg); - os.writeByte(_compressionSupported ? (byte)1 : (byte)0); - os.writeInt(IceInternal.Protocol.headerSize); // Message size. + timeout = defaultsAndOverrides.overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint.timeout(); + } + } + + try + { + IceInternal.SocketStatus status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return status; + } + } + catch(Ice.TimeoutException ex) + { + throw new Ice.ConnectTimeoutException(); + } + + synchronized(this) + { + if(_state == StateClosed) + { + assert(_exception != null); + throw _exception; + } + + // + // Update the connection description once the transceiver is initialized. + // + _desc = _transceiver.toString(); + + setState(StateNotValidated); + } + + return IceInternal.SocketStatus.Finished; + } + + private IceInternal.SocketStatus + validate() + { + if(!_endpoint.datagram()) // Datagram connections are always implicitly validated. + { + int timeout = 0; + if(_startCallback == null || _threadPerConnection) + { + IceInternal.DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideConnectTimeout) + { + timeout = defaultsAndOverrides.overrideConnectTimeoutValue; + } + else + { + timeout = _endpoint.timeout(); + } + } + + if(_adapter != null) // The server side has the active role for connection validation. + { + IceInternal.BasicStream os = _stream; + if(os.size() == 0) + { + os.writeBlob(IceInternal.Protocol.magic); + os.writeByte(IceInternal.Protocol.protocolMajor); + os.writeByte(IceInternal.Protocol.protocolMinor); + os.writeByte(IceInternal.Protocol.encodingMajor); + os.writeByte(IceInternal.Protocol.encodingMinor); + os.writeByte(IceInternal.Protocol.validateConnectionMsg); + os.writeByte((byte)0); // Compression status (always zero for validate connection). + os.writeInt(IceInternal.Protocol.headerSize); // Message size. + IceInternal.TraceUtil.traceSend(os, _logger, _traceLevels); + os.prepareWrite(); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + assert(_startCallback != null && !_threadPerConnection); + } + try + { + if(!_transceiver.write(os.getBuffer(), timeout)) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return IceInternal.SocketStatus.NeedWrite; + } + } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + throw ex.get(); + } + catch(Ice.TimeoutException ex) + { + throw new Ice.ConnectTimeoutException(); + } + } + else // The client side has the passive role for connection validation. + { + IceInternal.BasicStream is = _stream; + if(is.size() == 0) + { + is.resize(IceInternal.Protocol.headerSize, true); + is.pos(0); + } + else + { + // The stream can only be non-empty if we're doing a non-blocking connection validation. + assert(_startCallback != null && !_threadPerConnection); + } + + try + { + if(!_transceiver.read(is.getBuffer(), timeout, _hasMoreData)) + { + if(_startCallback == null || _threadPerConnection) + { + throw new Ice.TimeoutException(); + } + return IceInternal.SocketStatus.NeedRead; + } + } + catch(Ice.TimeoutException ex) + { + throw new Ice.ConnectTimeoutException(); + } + + assert(is.pos() == IceInternal.Protocol.headerSize); + is.pos(0); + byte[] m = is.readBlob(4); + if(m[0] != IceInternal.Protocol.magic[0] || m[1] != IceInternal.Protocol.magic[1] || + m[2] != IceInternal.Protocol.magic[2] || m[3] != IceInternal.Protocol.magic[3]) + { + BadMagicException ex = new BadMagicException(); + ex.badMagic = m; + throw ex; + } + byte pMajor = is.readByte(); + byte pMinor = is.readByte(); + if(pMajor != IceInternal.Protocol.protocolMajor) + { + UnsupportedProtocolException e = new UnsupportedProtocolException(); + e.badMajor = pMajor < 0 ? pMajor + 255 : pMajor; + e.badMinor = pMinor < 0 ? pMinor + 255 : pMinor; + e.major = IceInternal.Protocol.protocolMajor; + e.minor = IceInternal.Protocol.protocolMinor; + throw e; + } + byte eMajor = is.readByte(); + byte eMinor = is.readByte(); + if(eMajor != IceInternal.Protocol.encodingMajor) + { + UnsupportedEncodingException e = new UnsupportedEncodingException(); + e.badMajor = eMajor < 0 ? eMajor + 255 : eMajor; + e.badMinor = eMinor < 0 ? eMinor + 255 : eMinor; + e.major = IceInternal.Protocol.encodingMajor; + e.minor = IceInternal.Protocol.encodingMinor; + throw e; + } + byte messageType = is.readByte(); + if(messageType != IceInternal.Protocol.validateConnectionMsg) + { + throw new ConnectionNotValidatedException(); + } + byte compress = is.readByte(); // Ignore compression status for validate connection. + int size = is.readInt(); + if(size != IceInternal.Protocol.headerSize) + { + throw new IllegalMessageSizeException(); + } + IceInternal.TraceUtil.traceRecv(is, _logger, _traceLevels); + } + } + + synchronized(this) + { + _stream.reset(); + + if(_state == StateClosed) + { + assert(_exception != null); + throw _exception; + } + + // + // We start out in holding state. + // + setState(StateHolding); + } + + return IceInternal.SocketStatus.Finished; + } + + private boolean + send(int timeout) + { + assert(_transceiver != null); + assert(!_sendStreams.isEmpty()); + + while(!_sendStreams.isEmpty()) + { + OutgoingMessage message = (OutgoingMessage)_sendStreams.getFirst(); + if(!message.prepared) + { + IceInternal.BasicStream stream = message.stream; + + boolean compress = _overrideCompress ? _overrideCompressValue : message.compress; + message.stream = doCompress(stream, compress); + message.stream.prepareWrite(); + message.prepared = true; + + if(message.outAsync != null) + { + IceInternal.TraceUtil.trace("sending asynchronous request", stream, _logger, _traceLevels); + } + else + { + IceInternal.TraceUtil.traceSend(stream, _logger, _traceLevels); + } + + } + + try + { + if(!_transceiver.write(message.stream.getBuffer(), timeout)) + { + assert(timeout == 0); + return false; + } + } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + if(!ex.retry()) + { + message.sent(this, timeout == 0); + } + throw ex.get(); + } + + message.sent(this, timeout == 0); // timeout == 0 indicates that this is called by the selector thread. + _sendStreams.removeFirst(); + } + + return true; + } + + private boolean + sendMessage(OutgoingMessage message, boolean queue) + { + assert(_state != StateClosed); + + // + // TODO: Remove support for foreground send? If set to true, messages are sent + // by the calling thread. Foreground send might still be useful for transports + // that don't support non-blocking send. + // + boolean foreground = false; + + // + // If another thread is currently sending messages, we queue the message in _queuedStreams + // if we're not required to send the message in the foreground. If we're required to send + // the request in the foreground we wait until no more threads send messages. + // + if(_sendInProgress) + { + if(!foreground) + { + message.adopt(); + _queuedStreams.addLast(message); + return false; + } + else if(queue) + { // - // Send the message. - // - IceInternal.TraceUtil.traceHeader("sending close connection", os, _logger, _traceLevels); - _transceiver.write(os, _endpoint.timeout()); - // - // The CloseConnection message should be sufficient. Closing the write - // end of the socket is probably an artifact of how things were done - // in IIOP. In fact, shutting down the write end of the socket causes - // problems on Windows by preventing the peer from using the socket. - // For example, the peer is no longer able to continue writing a large - // message after the socket is shutdown. + // Add the message to _sendStreams if requested, this is useful for sendResponse() to + // send the close connection message after sending the response. // - //_transceiver.shutdownWrite(); + _sendStreams.addLast(message); + return true; // The calling thread must send the messages by calling finishSendMessage() + } + else + { + ++_waitingForSend; + while(_sendInProgress) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + --_waitingForSend; + + if(_state == StateClosed) + { + assert(_exception != null); + throw _exception; + } + } + } + + assert(!_sendInProgress); + + // + // Attempt to send the message without blocking. If the send blocks, we register + // the connection with the selector thread or we request the caller to call + // finishSendMessage() outside the synchronization. + // + + assert(!message.prepared); + + IceInternal.BasicStream stream = message.stream; + + boolean compress = _overrideCompress ? _overrideCompressValue : message.compress; + message.stream = doCompress(stream, compress); + message.stream.prepareWrite(); + message.prepared = true; + + if(message.outAsync != null) + { + IceInternal.TraceUtil.trace("sending asynchronous request", stream, _logger, _traceLevels); + } + else + { + IceInternal.TraceUtil.traceSend(stream, _logger, _traceLevels); + } + + try + { + if(!foreground && _transceiver.write(message.stream.getBuffer(), 0)) + { + message.sent(this, false); + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + return false; + } + } + catch(IceInternal.LocalExceptionWrapper ex) // Java-specific workaround in Transceiver.write(). + { + if(!ex.retry()) + { + message.sent(this, false); + } + throw ex.get(); + } + + _sendStreams.addLast(message); + _sendInProgress = true; + if(!foreground) + { + message.adopt(); + _selectorThread._register(_transceiver.fd(), this, IceInternal.SocketStatus.NeedWrite, _endpoint.timeout()); + return false; // The selector thread will send the message. + } + else + { + return true; // The calling thread must send the message by calling finishSendMessage() + } + } + + private void + finishSendMessage() + { + try + { + // + // Send the queued messages with a blocking write(). + // + boolean finished = send(_endpoint.timeout()); + assert(finished); + } + catch(Ice.LocalException ex) + { + synchronized(this) + { + setState(StateClosed, ex); + + _sendStreams.clear(); + _sendInProgress = false; + + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + + notifyAll(); + + assert(_exception != null); + throw _exception; + } + } + + synchronized(this) + { + assert(_sendStreams.isEmpty()); + if(_state == StateClosed) + { + _sendInProgress = false; + if(_threadPerConnection) + { + _transceiver.shutdownReadWrite(); + } + else + { + registerWithPool(); + unregisterWithPool(); // Let finished() do the close. + } + notifyAll(); + } + if(_waitingForSend > 0) + { + _sendInProgress = false; + notifyAll(); + } + else if(_queuedStreams.isEmpty()) + { + if(_acmTimeout > 0) + { + _acmAbsoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + _acmTimeout * 1000; + } + _sendInProgress = false; + } + else + { + _selectorThread._register(_transceiver.fd(), this, IceInternal.SocketStatus.NeedWrite, + _endpoint.timeout()); + } + } + } + + private void + finishStart(Ice.LocalException ex) + { + // + // We set _startCallback to null to break potential cyclic reference count + // and because the finalizer checks for it to ensure that we always invoke + // on the callback. + // + + StartCallback callback = null; + synchronized(this) + { + callback = _startCallback; + _startCallback = null; + } + + if(callback != null) + { + if(ex == null) + { + callback.connectionStartCompleted(this); + } + else + { + callback.connectionStartFailed(this, ex); } } } @@ -2075,7 +2552,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { case IceInternal.Protocol.closeConnectionMsg: { - IceInternal.TraceUtil.traceHeader("received close connection", info.stream, _logger, _traceLevels); + IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels); if(_endpoint.datagram()) { if(_warn) @@ -2094,13 +2571,13 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { if(_state == StateClosing) { - IceInternal.TraceUtil.traceRequest("received request during closing\n" + - "(ignored by server, client will retry)", - info.stream, _logger, _traceLevels); + IceInternal.TraceUtil.trace("received request during closing\n" + + "(ignored by server, client will retry)", + info.stream, _logger, _traceLevels); } else { - IceInternal.TraceUtil.traceRequest("received request", info.stream, _logger, _traceLevels); + IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels); info.requestId = info.stream.readInt(); info.invokeNum = 1; info.servantManager = _servantManager; @@ -2114,14 +2591,13 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { if(_state == StateClosing) { - IceInternal.TraceUtil.traceBatchRequest("received batch request during closing\n" + - "(ignored by server, client will retry)", - info.stream, _logger, _traceLevels); + IceInternal.TraceUtil.trace("received batch request during closing\n" + + "(ignored by server, client will retry)", + info.stream, _logger, _traceLevels); } else { - IceInternal.TraceUtil.traceBatchRequest("received batch request", info.stream, _logger, - _traceLevels); + IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels); info.invokeNum = info.stream.readInt(); if(info.invokeNum < 0) { @@ -2137,7 +2613,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne case IceInternal.Protocol.replyMsg: { - IceInternal.TraceUtil.traceReply("received reply", info.stream, _logger, _traceLevels); + IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels); info.requestId = info.stream.readInt(); IceInternal.Outgoing out = (IceInternal.Outgoing)_requests.remove(info.requestId); if(out != null) @@ -2157,8 +2633,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne case IceInternal.Protocol.validateConnectionMsg: { - IceInternal.TraceUtil.traceHeader("received validate connection", info.stream, _logger, - _traceLevels); + IceInternal.TraceUtil.traceRecv(info.stream, _logger, _traceLevels); if(_warn) { _logger.warning("ignoring unexpected validate connection message:\n" + _desc); @@ -2168,9 +2643,8 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne default: { - IceInternal.TraceUtil.traceHeader("received unknown message\n" + - "(invalid, closing connection)", info.stream, _logger, - _traceLevels); + IceInternal.TraceUtil.trace("received unknown message\n(invalid, closing connection)", + info.stream, _logger, _traceLevels); throw new UnknownMessageException(); } } @@ -2274,63 +2748,58 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne private void run() { - // - // For non-datagram connections, the thread-per-connection - // must validate and activate this connection, and not in the - // connection factory. Please see the comments in the - // connection factory for details. - // - if(!_endpoint.datagram()) + try { - try - { - validate(); - } - catch(LocalException ex) + // + // Initialize the connection transceiver and validate the connection using + // blocking operations. + // + + IceInternal.SocketStatus status; + + status = initialize(); + assert(status == IceInternal.SocketStatus.Finished); + + status = validate(); + assert(status == IceInternal.SocketStatus.Finished); + } + catch(LocalException ex) + { + synchronized(this) { - synchronized(this) + setState(StateClosed, ex); + + if(_transceiver != null) { - assert(_state == StateClosed); - - // - // We must make sure that nobody is sending when - // we close the transceiver. - // - synchronized(_sendMutex) + try { - if(_transceiver != null) - { - try - { - _transceiver.close(); - } - catch(LocalException e) - { - // Here we ignore any exceptions in close(). - } - - _transceiver = null; - } - notifyAll(); + _transceiver.close(); + } + catch(LocalException e) + { + // Here we ignore any exceptions in close(). } + + _transceiver = null; } - return; + notifyAll(); } - - activate(); + + finishStart(_exception); + return; } + finishStart(null); + boolean warnUdp = _instance.initializationData().properties.getPropertyAsInt("Ice.Warn.Datagrams") > 0; boolean closed = false; IceInternal.BasicStream stream = new IceInternal.BasicStream(_instance); - while(!closed) { // - // We must accept new connections outside the thread - // synchronization, because we use blocking accept. + // We must read new messages outside the thread synchronization because we use blocking reads. // try @@ -2339,7 +2808,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { stream.resize(IceInternal.Protocol.headerSize, true); stream.pos(0); - _transceiver.read(stream, -1); + _transceiver.read(stream.getBuffer(), -1, _hasMoreData); int pos = stream.pos(); if(pos < IceInternal.Protocol.headerSize) @@ -2409,7 +2878,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } else { - _transceiver.read(stream, -1); + _transceiver.read(stream.getBuffer(), -1, _hasMoreData); assert(stream.pos() == stream.size()); } } @@ -2442,9 +2911,6 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne LocalException localEx = null; - IceInternal.IntMap requests = null; - IceInternal.IntMap asyncRequests = null; - synchronized(this) { while(_state == StateHolding) @@ -2469,25 +2935,38 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // if(_state == StateClosed) { + if(_sendInProgress) + { + _selectorThread.unregister(_transceiver.fd()); + } + // - // We must make sure that nobody is sending when we close - // the transceiver. + // Prevent further writes. // - synchronized(_sendMutex) + _transceiver.shutdownWrite(); + + while(_sendInProgress) { try { - _transceiver.close(); + wait(); } - catch(LocalException ex) + catch(java.lang.Exception ex) { - localEx = ex; } - - _transceiver = null; - notifyAll(); } + try + { + _transceiver.close(); + } + catch(LocalException ex) + { + localEx = ex; + } + _transceiver = null; + notifyAll(); + // // We cannot simply return here. We have to make sure // that all requests (regular and async) are notified @@ -2495,15 +2974,6 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // closed = true; } - - if(_state == StateClosed || _state == StateClosing) - { - requests = _requests; - _requests = new IceInternal.IntMap(); - - asyncRequests = _asyncRequests; - _asyncRequests = new IceInternal.IntMap(); - } } // @@ -2520,29 +2990,36 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne // must be done outside the thread synchronization, so that nested // calls are possible. // - invokeAll(info.stream, info.invokeNum, info.requestId, info.compress, info.servantManager, + invokeAll(info.stream, info.invokeNum, info.requestId, info.compress, info.servantManager, info.adapter); - if(requests != null) + if(closed) { - java.util.Iterator i = requests.entryIterator(); + java.util.Iterator i = _queuedStreams.iterator(); + while(i.hasNext()) + { + OutgoingMessage message = (OutgoingMessage)i.next(); + message.finished(_exception); + } + _queuedStreams.clear(); + + i = _requests.entryIterator(); while(i.hasNext()) { IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); IceInternal.Outgoing out = (IceInternal.Outgoing)e.getValue(); out.finished(_exception); // The exception is immutable at this point. } - } + _requests.clear(); - if(asyncRequests != null) - { - java.util.Iterator i = asyncRequests.entryIterator(); + i = _asyncRequests.entryIterator(); while(i.hasNext()) { IceInternal.IntMap.Entry e = (IceInternal.IntMap.Entry)i.next(); IceInternal.OutgoingAsync out = (IceInternal.OutgoingAsync)e.getValue(); out.__finished(_exception); // The exception is immutable at this point. } + _asyncRequests.clear(); } if(localEx != null) @@ -2628,8 +3105,7 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } public IceInternal.Outgoing - getOutgoing(IceInternal.Reference reference, String operation, OperationMode mode, java.util.Map context, - boolean compress) + getOutgoing(IceInternal.RequestHandler handler, String operation, OperationMode mode, java.util.Map context) throws IceInternal.LocalExceptionWrapper { IceInternal.Outgoing out = null; @@ -2640,20 +3116,20 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne { if(_outgoingCache == null) { - out = new IceInternal.Outgoing(this, reference, operation, mode, context, compress); + out = new IceInternal.Outgoing(handler, operation, mode, context); } else { out = _outgoingCache; _outgoingCache = _outgoingCache.next; - out.reset(reference, operation, mode, context, compress); + out.reset(handler, operation, mode, context); out.next = null; } } } else { - out = new IceInternal.Outgoing(this, reference, operation, mode, context, compress); + out = new IceInternal.Outgoing(handler, operation, mode, context); } return out; @@ -2704,11 +3180,96 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne } } } + + private static class OutgoingMessage + { + OutgoingMessage(IceInternal.BasicStream stream, boolean compress, boolean adopt) + { + this.stream = stream; + this.compress = compress; + this.adopt = adopt; + } + + OutgoingMessage(IceInternal.OutgoingMessageCallback out, IceInternal.BasicStream stream, boolean compress, + boolean resp) + { + this.stream = stream; + this.compress = compress; + this.out = out; + this.response = resp; + } + + OutgoingMessage(IceInternal.OutgoingAsyncMessageCallback out, IceInternal.BasicStream stream, boolean compress, + boolean resp) + { + this.stream = stream; + this.compress = compress; + this.outAsync = out; + this.response = resp; + } + + public void + adopt() + { + if(adopt) + { + IceInternal.BasicStream stream = new IceInternal.BasicStream(this.stream.instance()); + stream.swap(this.stream); + this.stream = stream; + adopt = false; + } + } + + public void + sent(ConnectionI connection, boolean notify) + { + if(out != null) + { + out.sent(notify); // true = notify the waiting thread that the request was sent. + } + else if(outAsync != null) + { + outAsync.__sent(connection); + } + } + + public void + finished(Ice.LocalException ex) + { + // + // Only notify oneway requests. The connection keeps track of twoway + // requests in the _requests/_asyncRequests maps and will notify them + // of the connection exceptions. + // + if(!response) + { + if(out != null) + { + out.finished(ex); + } + else if(outAsync != null) + { + outAsync.__finished(ex); + } + } + } + + public IceInternal.BasicStream stream; + public IceInternal.OutgoingMessageCallback out; + public IceInternal.OutgoingAsyncMessageCallback outAsync; + public boolean compress; + public boolean response; + boolean adopt; + boolean prepared; + } + private Thread _thread; private final boolean _threadPerConnection; private IceInternal.Transceiver _transceiver; - private final String _desc; + private Ice.BooleanHolder _hasMoreData = new Ice.BooleanHolder(false); + + private String _desc; private final String _type; private final IceInternal.EndpointI _endpoint; @@ -2721,6 +3282,9 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne private boolean _registeredWithPool; private int _finishedCount; private final IceInternal.ThreadPool _threadPool; + private final IceInternal.SelectorThread _selectorThread; + + private StartCallback _startCallback = null; private final boolean _warn; @@ -2743,17 +3307,16 @@ public final class ConnectionI extends IceInternal.EventHandler implements Conne private boolean _batchRequestCompress; private int _batchMarker; + private java.util.LinkedList _queuedStreams = new java.util.LinkedList(); + private java.util.LinkedList _sendStreams = new java.util.LinkedList(); + private boolean _sendInProgress; + private int _waitingForSend; + private int _dispatchCount; private int _state; // The current state. private long _stateTime; // The last time when the state was changed. - // - // We have a separate mutex for sending, so that we don't block - // the whole connection when we do a blocking send. - // - private java.lang.Object _sendMutex = new java.lang.Object(); - private IceInternal.Incoming _incomingCache; private java.lang.Object _incomingCacheMutex = new java.lang.Object(); diff --git a/java/src/Ice/InputStreamI.java b/java/src/Ice/InputStreamI.java index 4cd30cbd4aa..eaa75550cf9 100644 --- a/java/src/Ice/InputStreamI.java +++ b/java/src/Ice/InputStreamI.java @@ -19,10 +19,10 @@ public class InputStreamI implements InputStream _is = new IceInternal.BasicStream(Util.getInstance(communicator)); _is.closure(this); _is.resize(data.length, true); - java.nio.ByteBuffer buf = _is.prepareRead(); - buf.position(0); - buf.put(data); - buf.position(0); + IceInternal.Buffer buf = _is.getBuffer(); + buf.b.position(0); + buf.b.put(data); + buf.b.position(0); } public Communicator diff --git a/java/src/Ice/ObjectAdapterI.java b/java/src/Ice/ObjectAdapterI.java index 8d3e8bf8779..adb890ae473 100644 --- a/java/src/Ice/ObjectAdapterI.java +++ b/java/src/Ice/ObjectAdapterI.java @@ -370,7 +370,6 @@ public final class ObjectAdapterI implements ObjectAdapter _routerInfo = null; _publishedEndpoints = null; _locatorInfo = null; - _connectors = null; objectAdapterFactory = _objectAdapterFactory; _objectAdapterFactory = null; @@ -538,22 +537,17 @@ public final class ObjectAdapterI implements ObjectAdapter { IceInternal.IncomingConnectionFactory factory = (IceInternal.IncomingConnectionFactory)_incomingConnectionFactories.get(i); - ConnectionI[] conns = factory.connections(); - for(int j = 0; j < conns.length; ++j) - { - connections.add(conns[j]); - } + connections.addAll(factory.connections()); } // // Create a reference and return a reverse proxy for this // reference. // - IceInternal.EndpointI[] endpoints = new IceInternal.EndpointI[0]; ConnectionI[] arr = new ConnectionI[connections.size()]; connections.toArray(arr); IceInternal.Reference ref = - _instance.referenceFactory().create(ident, _instance.getDefaultContext(), "", + _instance.referenceFactory().create(ident, _instance.getDefaultContext(), "", IceInternal.Reference.ModeTwoway, arr); return _instance.proxyFactory().referenceToProxy(ref); } @@ -580,14 +574,6 @@ public final class ObjectAdapterI implements ObjectAdapter oldPublishedEndpoints = _publishedEndpoints; _publishedEndpoints = parsePublishedEndpoints(); - _connectors.clear(); - java.util.Iterator p = _incomingConnectionFactories.iterator(); - while(p.hasNext()) - { - IceInternal.IncomingConnectionFactory factory = (IceInternal.IncomingConnectionFactory)p.next(); - _connectors.addAll(factory.endpoint().connectors()); - } - locatorInfo = _locatorInfo; if(!_noConfig) { @@ -654,7 +640,6 @@ public final class ObjectAdapterI implements ObjectAdapter endpoints = ref.getEndpoints(); } - synchronized(this) { checkForDeactivation(); @@ -666,15 +651,24 @@ public final class ObjectAdapterI implements ObjectAdapter // for(int i = 0; i < endpoints.length; ++i) { - final int sz = _connectors.size(); - for(int j = 0; j < sz; j++) + java.util.Iterator p; + p = _publishedEndpoints.iterator(); + while(p.hasNext()) + { + if(endpoints[i].equivalent((IceInternal.EndpointI)p.next())) + { + return true; + } + } + p = _incomingConnectionFactories.iterator(); + while(p.hasNext()) { - IceInternal.Connector connector = (IceInternal.Connector)_connectors.get(j); - if(endpoints[i].equivalent(connector)) + if(endpoints[i].equivalent(((IceInternal.IncomingConnectionFactory)p.next()).endpoint())) { return true; } } + } // @@ -842,7 +836,7 @@ public final class ObjectAdapterI implements ObjectAdapter _id = properties.getProperty(_name + ".AdapterId"); _replicaGroupId = properties.getProperty(_name + ".ReplicaGroupId"); - + try { _threadPerConnection = properties.getPropertyAsInt(_name + ".ThreadPerConnection") > 0; @@ -932,9 +926,8 @@ public final class ObjectAdapterI implements ObjectAdapter else { // - // Parse the endpoints, but don't store them in the adapter. - // The connection factory might change it, for example, to - // fill in the real port number. + // Parse the endpoints, but don't store them in the adapter. The connection + // factory might change it, for example, to fill in the real port number. // java.util.ArrayList endpoints; if(endpointInfo.length() == 0) @@ -957,11 +950,10 @@ public final class ObjectAdapterI implements ObjectAdapter ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endp.toString(); throw ex; } + IceInternal.IncomingConnectionFactory factory = new IceInternal.IncomingConnectionFactory(instance, endp, this, _name); _incomingConnectionFactories.add(factory); - - _connectors.addAll(factory.endpoint().connectors()); } if(endpoints.size() == 0) { @@ -1193,7 +1185,7 @@ public final class ObjectAdapterI implements ObjectAdapter while(p.hasNext()) { IceInternal.EndpointI endp = (IceInternal.EndpointI)p.next(); - java.util.ArrayList endps = endp.expand(); + java.util.List endps = endp.expand(); expandedEndpoints.addAll(endps); } return expandedEndpoints; @@ -1373,7 +1365,6 @@ public final class ObjectAdapterI implements ObjectAdapter final private String _id; final private String _replicaGroupId; private java.util.ArrayList _incomingConnectionFactories = new java.util.ArrayList(); - private java.util.ArrayList _connectors = new java.util.ArrayList(); private java.util.ArrayList _routerEndpoints = new java.util.ArrayList(); private IceInternal.RouterInfo _routerInfo = null; private java.util.ArrayList _publishedEndpoints = new java.util.ArrayList(); diff --git a/java/src/Ice/ObjectPrx.java b/java/src/Ice/ObjectPrx.java index b0f187de430..a33669161df 100644 --- a/java/src/Ice/ObjectPrx.java +++ b/java/src/Ice/ObjectPrx.java @@ -138,5 +138,8 @@ public interface ObjectPrx Connection ice_getConnection(); Connection ice_getCachedConnection(); + void ice_flushBatchRequests(); + void ice_flushBatchRequests_async(AMI_Object_ice_flushBatchRequests cb); + boolean equals(java.lang.Object r); } diff --git a/java/src/Ice/ObjectPrxHelperBase.java b/java/src/Ice/ObjectPrxHelperBase.java index 72df0844773..87c3b86f3d2 100644 --- a/java/src/Ice/ObjectPrxHelperBase.java +++ b/java/src/Ice/ObjectPrxHelperBase.java @@ -82,7 +82,7 @@ public class ObjectPrxHelperBase implements ObjectPrx try { __checkTwowayOnly("ice_isA"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del.ice_isA(__id, __context); } catch(IceInternal.LocalExceptionWrapper __ex) @@ -122,7 +122,7 @@ public class ObjectPrxHelperBase implements ObjectPrx _ObjectDel __del = null; try { - __del = __getDelegate(); + __del = __getDelegate(false); __del.ice_ping(__context); return; } @@ -164,7 +164,7 @@ public class ObjectPrxHelperBase implements ObjectPrx try { __checkTwowayOnly("ice_ids"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del.ice_ids(__context); } catch(IceInternal.LocalExceptionWrapper __ex) @@ -205,7 +205,7 @@ public class ObjectPrxHelperBase implements ObjectPrx try { __checkTwowayOnly("ice_id"); - __del = __getDelegate(); + __del = __getDelegate(false); return __del.ice_id(__context); } catch(IceInternal.LocalExceptionWrapper __ex) @@ -247,7 +247,7 @@ public class ObjectPrxHelperBase implements ObjectPrx _ObjectDel __del = null; try { - __del = __getDelegate(); + __del = __getDelegate(false); return __del.ice_invoke(operation, mode, inParams, outParams, context); } catch(IceInternal.LocalExceptionWrapper __ex) @@ -776,8 +776,8 @@ public class ObjectPrxHelperBase implements ObjectPrx **/ public final Connection ice_connection() - { - return ice_getConnection(); + { + return ice_getConnection(); } public final Connection @@ -789,8 +789,9 @@ public class ObjectPrxHelperBase implements ObjectPrx _ObjectDel __del = null; try { - __del = __getDelegate(); - return __del.__getConnection(new BooleanHolder()); + __del = __getDelegate(false); + // Wait for the connection to be established. + return __del.__getRequestHandler().getConnection(true); } catch(LocalException __ex) { @@ -812,7 +813,8 @@ public class ObjectPrxHelperBase implements ObjectPrx { try { - return __del.__getConnection(new BooleanHolder()); + // Don't wait for the connection to be established. + return __del.__getRequestHandler().getConnection(false); } catch(CollocationOptimizationException ex) { @@ -821,6 +823,36 @@ public class ObjectPrxHelperBase implements ObjectPrx return null; } + public void + ice_flushBatchRequests() + { + int __cnt = 0; + while(true) + { + _ObjectDel __del = null; + try + { + __del = __getDelegate(false); + __del.ice_flushBatchRequests(); + return; + } + catch(IceInternal.LocalExceptionWrapper __ex) + { + __handleExceptionWrapper(__del, __ex); + } + catch(LocalException __ex) + { + __cnt = __handleException(__del, __ex, __cnt); + } + } + } + + public void + ice_flushBatchRequests_async(AMI_Object_ice_flushBatchRequests cb) + { + cb.__invoke(this); + } + public final boolean equals(java.lang.Object r) { @@ -988,7 +1020,7 @@ public class ObjectPrxHelperBase implements ObjectPrx } public final synchronized _ObjectDel - __getDelegate() + __getDelegate(boolean async) { if(_delegate != null) { @@ -1010,19 +1042,8 @@ public class ObjectPrxHelperBase implements ObjectPrx if(delegate == null) { _ObjectDelM d = __createDelegateM(); - d.setup(_reference); + d.setup(_reference, this, async); delegate = d; - - // - // If this proxy is for a non-local object, and we are - // using a router, then add this proxy to the router info - // object. - // - IceInternal.RouterInfo ri = _reference.getRouterInfo(); - if(ri != null) - { - ri.addProxy(this); - } } if(_reference.getCacheConnection()) @@ -1038,6 +1059,24 @@ public class ObjectPrxHelperBase implements ObjectPrx return delegate; } + synchronized public void + __setRequestHandler(_ObjectDel delegate, IceInternal.RequestHandler handler) + { + if(delegate == _delegate) + { + if(_delegate instanceof _ObjectDelM) + { + _delegate = __createDelegateM(); + _delegate.__setRequestHandler(handler); + } + else if(_delegate instanceof _ObjectDelD) + { + _delegate = __createDelegateD(); + _delegate.__setRequestHandler(handler); + } + } + } + protected _ObjectDelM __createDelegateM() { diff --git a/java/src/Ice/OutputStreamI.java b/java/src/Ice/OutputStreamI.java index 2a0884014ef..0393caf4689 100644 --- a/java/src/Ice/OutputStreamI.java +++ b/java/src/Ice/OutputStreamI.java @@ -190,9 +190,9 @@ public class OutputStreamI implements OutputStream public byte[] finished() { - java.nio.ByteBuffer buf = _os.prepareWrite(); - byte[] result = new byte[buf.limit()]; - buf.get(result); + IceInternal.Buffer buf = _os.prepareWrite(); + byte[] result = new byte[buf.b.limit()]; + buf.b.get(result); return result; } diff --git a/java/src/Ice/_ObjectDel.java b/java/src/Ice/_ObjectDel.java index e17416dfe8a..8eefc506fca 100644 --- a/java/src/Ice/_ObjectDel.java +++ b/java/src/Ice/_ObjectDel.java @@ -27,5 +27,9 @@ public interface _ObjectDel java.util.Map context) throws IceInternal.LocalExceptionWrapper; - ConnectionI __getConnection(BooleanHolder compress); + void ice_flushBatchRequests() + throws IceInternal.LocalExceptionWrapper; + + IceInternal.RequestHandler __getRequestHandler(); + void __setRequestHandler(IceInternal.RequestHandler handler); } diff --git a/java/src/Ice/_ObjectDelD.java b/java/src/Ice/_ObjectDelD.java index 7caece078cd..0248419607d 100644 --- a/java/src/Ice/_ObjectDelD.java +++ b/java/src/Ice/_ObjectDelD.java @@ -215,8 +215,20 @@ public class _ObjectDelD implements _ObjectDel throw new CollocationOptimizationException(); } - public ConnectionI - __getConnection(BooleanHolder compress) + public void + ice_flushBatchRequests() + { + throw new CollocationOptimizationException(); + } + + public IceInternal.RequestHandler + __getRequestHandler() + { + throw new CollocationOptimizationException(); + } + + public void + __setRequestHandler(IceInternal.RequestHandler handler) { throw new CollocationOptimizationException(); } diff --git a/java/src/Ice/_ObjectDelM.java b/java/src/Ice/_ObjectDelM.java index b37bd91733e..8bc56496b33 100644 --- a/java/src/Ice/_ObjectDelM.java +++ b/java/src/Ice/_ObjectDelM.java @@ -15,8 +15,7 @@ public class _ObjectDelM implements _ObjectDel ice_isA(String __id, java.util.Map __context) throws IceInternal.LocalExceptionWrapper { - IceInternal.Outgoing __og = __connection.getOutgoing(__reference, "ice_isA", OperationMode.Nonmutating, - __context, __compress); + IceInternal.Outgoing __og = __handler.getOutgoing("ice_isA", OperationMode.Nonmutating, __context); try { try @@ -52,7 +51,7 @@ public class _ObjectDelM implements _ObjectDel } finally { - __connection.reclaimOutgoing(__og); + __handler.reclaimOutgoing(__og); } } @@ -60,8 +59,7 @@ public class _ObjectDelM implements _ObjectDel ice_ping(java.util.Map __context) throws IceInternal.LocalExceptionWrapper { - IceInternal.Outgoing __og = __connection.getOutgoing(__reference, "ice_ping", OperationMode.Nonmutating, - __context, __compress); + IceInternal.Outgoing __og = __handler.getOutgoing("ice_ping", OperationMode.Nonmutating, __context); try { boolean __ok = __og.invoke(); @@ -87,7 +85,7 @@ public class _ObjectDelM implements _ObjectDel } finally { - __connection.reclaimOutgoing(__og); + __handler.reclaimOutgoing(__og); } } @@ -95,8 +93,7 @@ public class _ObjectDelM implements _ObjectDel ice_ids(java.util.Map __context) throws IceInternal.LocalExceptionWrapper { - IceInternal.Outgoing __og = __connection.getOutgoing(__reference, "ice_ids", OperationMode.Nonmutating, - __context, __compress); + IceInternal.Outgoing __og = __handler.getOutgoing("ice_ids", OperationMode.Nonmutating, __context); try { boolean __ok = __og.invoke(); @@ -123,7 +120,7 @@ public class _ObjectDelM implements _ObjectDel } finally { - __connection.reclaimOutgoing(__og); + __handler.reclaimOutgoing(__og); } } @@ -131,8 +128,7 @@ public class _ObjectDelM implements _ObjectDel ice_id(java.util.Map __context) throws IceInternal.LocalExceptionWrapper { - IceInternal.Outgoing __og = __connection.getOutgoing(__reference, "ice_id", OperationMode.Nonmutating, - __context, __compress); + IceInternal.Outgoing __og = __handler.getOutgoing("ice_id", OperationMode.Nonmutating, __context); try { boolean __ok = __og.invoke(); @@ -159,7 +155,7 @@ public class _ObjectDelM implements _ObjectDel } finally { - __connection.reclaimOutgoing(__og); + __handler.reclaimOutgoing(__og); } } @@ -167,7 +163,7 @@ public class _ObjectDelM implements _ObjectDel ice_invoke(String operation, OperationMode mode, byte[] inParams, ByteSeqHolder outParams, java.util.Map __context) throws IceInternal.LocalExceptionWrapper { - IceInternal.Outgoing __og = __connection.getOutgoing(__reference, operation, mode, __context, __compress); + IceInternal.Outgoing __og = __handler.getOutgoing(operation, mode, __context); try { if(inParams != null) @@ -183,7 +179,7 @@ public class _ObjectDelM implements _ObjectDel } } boolean ok = __og.invoke(); - if(__reference.getMode() == IceInternal.Reference.ModeTwoway) + if(__handler.getReference().getMode() == IceInternal.Reference.ModeTwoway) { try { @@ -203,15 +199,40 @@ public class _ObjectDelM implements _ObjectDel } finally { - __connection.reclaimOutgoing(__og); + __handler.reclaimOutgoing(__og); } } - public ConnectionI - __getConnection(BooleanHolder compress) + public void + ice_flushBatchRequests() + throws IceInternal.LocalExceptionWrapper + { + IceInternal.BatchOutgoing out = new IceInternal.BatchOutgoing(__handler); + try + { + out.invoke(); + } + catch(Ice.LocalException ex) + { + // + // We never retry flusing the batch requests as the connection batched + // requests were discarded and the caller needs to be notified of the + // failure. + // + throw new IceInternal.LocalExceptionWrapper(ex, false); + } + } + + public IceInternal.RequestHandler + __getRequestHandler() { - compress.value = __compress; - return __connection; + return __handler; + } + + public void + __setRequestHandler(IceInternal.RequestHandler handler) + { + __handler = handler; } // @@ -230,32 +251,38 @@ public class _ObjectDelM implements _ObjectDel // upon initialization. // - assert(__reference == null); - assert(__connection == null); + assert(__handler == null); - __reference = from.__reference; - __connection = from.__connection; - __compress = from.__compress; + __handler = from.__handler; } - protected IceInternal.Reference __reference; - protected ConnectionI __connection; - protected boolean __compress; + protected IceInternal.RequestHandler __handler; public void - setup(IceInternal.Reference ref) + setup(IceInternal.Reference ref, Ice.ObjectPrx proxy, boolean async) { // // No need to synchronize, as this operation is only called // upon initialization. // - assert(__reference == null); - assert(__connection == null); + assert(__handler == null); - __reference = ref; - BooleanHolder compress = new BooleanHolder(); - __connection = __reference.getConnection(compress); - __compress = compress.value; + // + // If the delegate is created as a result of an AMI call or if the proxy is + // a batch proxy we use the connect request handler to connect the in the + // background. + // + if(async || + ref.getMode() == IceInternal.Reference.ModeBatchOneway || + ref.getMode() == IceInternal.Reference.ModeBatchDatagram) + { + IceInternal.ConnectRequestHandler handler = new IceInternal.ConnectRequestHandler(ref, proxy, this); + __handler = handler.connect(); + } + else + { + __handler = new IceInternal.ConnectionRequestHandler(ref, proxy); + } } } diff --git a/java/src/IceInternal/BasicStream.java b/java/src/IceInternal/BasicStream.java index d7a33113069..16409506b80 100644 --- a/java/src/IceInternal/BasicStream.java +++ b/java/src/IceInternal/BasicStream.java @@ -12,27 +12,24 @@ package IceInternal; public class BasicStream { public - BasicStream(IceInternal.Instance instance) + BasicStream(Instance instance) { initialize(instance, false); } public - BasicStream(IceInternal.Instance instance, boolean unlimited) + BasicStream(Instance instance, boolean unlimited) { initialize(instance, unlimited); } private void - initialize(IceInternal.Instance instance, boolean unlimited) + initialize(Instance instance, boolean unlimited) { _instance = instance; + _buf = new Buffer(_instance.messageSizeMax()); _closure = null; _unlimited = unlimited; - allocate(1500); - _capacity = _buf.capacity(); - _limit = 0; - assert(_buf.limit() == _capacity); _readEncapsStack = null; _writeEncapsStack = null; @@ -56,9 +53,7 @@ public class BasicStream public void reset() { - _limit = 0; - _buf.limit(_capacity); - _buf.position(0); + _buf.reset(); if(_readEncapsStack != null) { @@ -75,7 +70,7 @@ public class BasicStream } } - public IceInternal.Instance + public Instance instance() { return _instance; @@ -104,18 +99,10 @@ public class BasicStream other._closure = _closure; _closure = tmpClosure; - java.nio.ByteBuffer tmpBuf = other._buf; + Buffer tmpBuf = other._buf; other._buf = _buf; _buf = tmpBuf; - int tmpCapacity = other._capacity; - other._capacity = _capacity; - _capacity = tmpCapacity; - - int tmpLimit = other._limit; - other._limit = _limit; - _limit = tmpLimit; - ReadEncaps tmpRead = other._readEncapsStack; other._readEncapsStack = _readEncapsStack; _readEncapsStack = tmpRead; @@ -154,49 +141,31 @@ public class BasicStream } public void - resize(int total, boolean reading) + resize(int sz, boolean reading) { - if(!_unlimited && total > _messageSizeMax) - { - throw new Ice.MemoryLimitException(); - } - if(total > _capacity) - { - final int cap2 = _capacity << 1; - int newCapacity = cap2 > total ? cap2 : total; - _buf.limit(_limit); - reallocate(newCapacity); - _capacity = _buf.capacity(); - } // - // If this stream is used for reading, then we want to set the - // buffer's limit to the new total size. If this buffer is - // used for writing, then we must set the buffer's limit to - // the buffer's capacity. + // Check memory limit if stream is not unlimited. // - if(reading) + if(!_unlimited && sz > _messageSizeMax) { - _buf.limit(total); - } - else - { - _buf.limit(_capacity); + throw new Ice.MemoryLimitException(); } - _buf.position(total); - _limit = total; + + _buf.resize(sz, reading); + _buf.b.position(sz); } - public java.nio.ByteBuffer - prepareRead() + public Buffer + prepareWrite() { + _buf.b.limit(_buf.size()); + _buf.b.position(0); return _buf; } - public java.nio.ByteBuffer - prepareWrite() + public Buffer + getBuffer() { - _buf.limit(_limit); - _buf.position(0); return _buf; } @@ -261,7 +230,7 @@ public class BasicStream sd.previous = _seqDataStack; _seqDataStack = sd; - int bytesLeft = _buf.remaining(); + int bytesLeft = _buf.b.remaining(); if(_seqDataStack.previous == null) // Outermost sequence { // @@ -287,7 +256,7 @@ public class BasicStream public void checkSeq() { - checkSeq(_buf.remaining()); + checkSeq(_buf.b.remaining()); } public void @@ -311,7 +280,7 @@ public class BasicStream public void checkFixedSeq(int numElements, int elemSize) { - int bytesLeft = _buf.remaining(); + int bytesLeft = _buf.b.remaining(); if(_seqDataStack == null) // Outermost sequence { // @@ -376,7 +345,7 @@ public class BasicStream _writeEncapsStack = curr; } - _writeEncapsStack.start = _buf.position(); + _writeEncapsStack.start = _buf.size(); writeBlob(_encapsBlob); } @@ -385,8 +354,8 @@ public class BasicStream { assert(_writeEncapsStack != null); int start = _writeEncapsStack.start; - int sz = _buf.position() - start; // Size includes size and version. - _buf.putInt(start, sz); + int sz = _buf.size() - start; // Size includes size and version. + _buf.b.putInt(start, sz); WriteEncaps curr = _writeEncapsStack; _writeEncapsStack = curr.next; @@ -413,8 +382,8 @@ public class BasicStream _readEncapsStack = curr; } - _readEncapsStack.start = _buf.position(); - + _readEncapsStack.start = _buf.b.position(); + // // I don't use readSize() and writeSize() for encapsulations, // because when creating an encapsulation, I must know in @@ -428,7 +397,7 @@ public class BasicStream throw new Ice.NegativeSizeException(); } - if(sz - 4 > _buf.limit()) + if(sz - 4 > _buf.b.limit()) { throw new Ice.UnmarshalOutOfBoundsException(); } @@ -457,7 +426,7 @@ public class BasicStream int sz = _readEncapsStack.sz; try { - _buf.position(start + sz); + _buf.b.position(start + sz); } catch(IllegalArgumentException ex) { @@ -477,7 +446,7 @@ public class BasicStream assert(_readEncapsStack != null); int start = _readEncapsStack.start; int sz = _readEncapsStack.sz; - if(_buf.position() != start + sz) + if(_buf.b.position() != start + sz) { throw new Ice.EncapsulationException(); } @@ -500,7 +469,7 @@ public class BasicStream } try { - _buf.position(_buf.position() + sz - 4); + _buf.b.position(_buf.b.position() + sz - 4); } catch(IllegalArgumentException ex) { @@ -512,13 +481,13 @@ public class BasicStream startWriteSlice() { writeInt(0); // Placeholder for the slice length. - _writeSlice = _buf.position(); + _writeSlice = _buf.size(); } public void endWriteSlice() { - final int sz = _buf.position() - _writeSlice + 4; - _buf.putInt(_writeSlice - 4, sz); + final int sz = _buf.size() - _writeSlice + 4; + _buf.b.putInt(_writeSlice - 4, sz); } public void startReadSlice() @@ -528,7 +497,7 @@ public class BasicStream { throw new Ice.NegativeSizeException(); } - _readSlice = _buf.position(); + _readSlice = _buf.b.position(); } public void endReadSlice() @@ -544,7 +513,7 @@ public class BasicStream } try { - _buf.position(_buf.position() + sz - 4); + _buf.b.position(_buf.b.position() + sz - 4); } catch(IllegalArgumentException ex) { @@ -558,13 +527,13 @@ public class BasicStream if(v > 254) { expand(5); - _buf.put((byte)-1); - _buf.putInt(v); + _buf.b.put((byte)-1); + _buf.b.putInt(v); } else { expand(1); - _buf.put((byte)v); + _buf.b.put((byte)v); } } @@ -573,10 +542,10 @@ public class BasicStream { try { - byte b = _buf.get(); + byte b = _buf.b.get(); if(b == -1) { - int v = _buf.getInt(); + int v = _buf.b.getInt(); if(v < 0) { throw new Ice.NegativeSizeException(); @@ -640,14 +609,14 @@ public class BasicStream writeBlob(byte[] v) { expand(v.length); - _buf.put(v); + _buf.b.put(v); } public void writeBlob(byte[] v, int off, int len) { expand(len); - _buf.put(v, off, len); + _buf.b.put(v, off, len); } public byte[] @@ -656,7 +625,7 @@ public class BasicStream byte[] v = new byte[sz]; try { - _buf.get(v); + _buf.b.get(v); return v; } catch(java.nio.BufferUnderflowException ex) @@ -669,7 +638,7 @@ public class BasicStream writeByte(byte v) { expand(1); - _buf.put(v); + _buf.b.put(v); } public void @@ -693,7 +662,7 @@ public class BasicStream { writeSize(v.length); expand(v.length); - _buf.put(v); + _buf.b.put(v); } } @@ -702,7 +671,7 @@ public class BasicStream { try { - return _buf.get(); + return _buf.b.get(); } catch(java.nio.BufferUnderflowException ex) { @@ -729,7 +698,7 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 1); byte[] v = new byte[sz]; - _buf.get(v); + _buf.b.get(v); return v; } catch(java.nio.BufferUnderflowException ex) @@ -742,7 +711,7 @@ public class BasicStream writeBool(boolean v) { expand(1); - _buf.put(v ? (byte)1 : (byte)0); + _buf.b.put(v ? (byte)1 : (byte)0); } public void @@ -758,7 +727,7 @@ public class BasicStream expand(v.length); for(int i = 0; i < v.length; i++) { - _buf.put(v[i] ? (byte)1 : (byte)0); + _buf.b.put(v[i] ? (byte)1 : (byte)0); } } } @@ -768,7 +737,7 @@ public class BasicStream { try { - return _buf.get() == 1; + return _buf.b.get() == 1; } catch(java.nio.BufferUnderflowException ex) { @@ -786,7 +755,7 @@ public class BasicStream boolean[] v = new boolean[sz]; for(int i = 0; i < sz; i++) { - v[i] = _buf.get() == 1; + v[i] = _buf.b.get() == 1; } return v; } @@ -800,7 +769,7 @@ public class BasicStream writeShort(short v) { expand(2); - _buf.putShort(v); + _buf.b.putShort(v); } public void @@ -824,9 +793,9 @@ public class BasicStream { writeSize(v.length); expand(v.length * 2); - java.nio.ShortBuffer shortBuf = _buf.asShortBuffer(); + java.nio.ShortBuffer shortBuf = _buf.b.asShortBuffer(); shortBuf.put(v); - _buf.position(_buf.position() + v.length * 2); + _buf.b.position(_buf.b.position() + v.length * 2); } } @@ -835,7 +804,7 @@ public class BasicStream { try { - return _buf.getShort(); + return _buf.b.getShort(); } catch(java.nio.BufferUnderflowException ex) { @@ -862,9 +831,9 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 2); short[] v = new short[sz]; - java.nio.ShortBuffer shortBuf = _buf.asShortBuffer(); + java.nio.ShortBuffer shortBuf = _buf.b.asShortBuffer(); shortBuf.get(v); - _buf.position(_buf.position() + sz * 2); + _buf.b.position(_buf.b.position() + sz * 2); return v; } catch(java.nio.BufferUnderflowException ex) @@ -877,7 +846,7 @@ public class BasicStream writeInt(int v) { expand(4); - _buf.putInt(v); + _buf.b.putInt(v); } public void @@ -901,9 +870,9 @@ public class BasicStream { writeSize(v.length); expand(v.length * 4); - java.nio.IntBuffer intBuf = _buf.asIntBuffer(); + java.nio.IntBuffer intBuf = _buf.b.asIntBuffer(); intBuf.put(v); - _buf.position(_buf.position() + v.length * 4); + _buf.b.position(_buf.b.position() + v.length * 4); } } @@ -912,7 +881,7 @@ public class BasicStream { try { - return _buf.getInt(); + return _buf.b.getInt(); } catch(java.nio.BufferUnderflowException ex) { @@ -939,9 +908,9 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 4); int[] v = new int[sz]; - java.nio.IntBuffer intBuf = _buf.asIntBuffer(); + java.nio.IntBuffer intBuf = _buf.b.asIntBuffer(); intBuf.get(v); - _buf.position(_buf.position() + sz * 4); + _buf.b.position(_buf.b.position() + sz * 4); return v; } catch(java.nio.BufferUnderflowException ex) @@ -954,7 +923,7 @@ public class BasicStream writeLong(long v) { expand(8); - _buf.putLong(v); + _buf.b.putLong(v); } public void @@ -968,9 +937,9 @@ public class BasicStream { writeSize(v.length); expand(v.length * 8); - java.nio.LongBuffer longBuf = _buf.asLongBuffer(); + java.nio.LongBuffer longBuf = _buf.b.asLongBuffer(); longBuf.put(v); - _buf.position(_buf.position() + v.length * 8); + _buf.b.position(_buf.b.position() + v.length * 8); } } @@ -979,7 +948,7 @@ public class BasicStream { try { - return _buf.getLong(); + return _buf.b.getLong(); } catch(java.nio.BufferUnderflowException ex) { @@ -995,9 +964,9 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 8); long[] v = new long[sz]; - java.nio.LongBuffer longBuf = _buf.asLongBuffer(); + java.nio.LongBuffer longBuf = _buf.b.asLongBuffer(); longBuf.get(v); - _buf.position(_buf.position() + sz * 8); + _buf.b.position(_buf.b.position() + sz * 8); return v; } catch(java.nio.BufferUnderflowException ex) @@ -1010,7 +979,7 @@ public class BasicStream writeFloat(float v) { expand(4); - _buf.putFloat(v); + _buf.b.putFloat(v); } public void @@ -1024,9 +993,9 @@ public class BasicStream { writeSize(v.length); expand(v.length * 4); - java.nio.FloatBuffer floatBuf = _buf.asFloatBuffer(); + java.nio.FloatBuffer floatBuf = _buf.b.asFloatBuffer(); floatBuf.put(v); - _buf.position(_buf.position() + v.length * 4); + _buf.b.position(_buf.b.position() + v.length * 4); } } @@ -1035,7 +1004,7 @@ public class BasicStream { try { - return _buf.getFloat(); + return _buf.b.getFloat(); } catch(java.nio.BufferUnderflowException ex) { @@ -1051,9 +1020,9 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 4); float[] v = new float[sz]; - java.nio.FloatBuffer floatBuf = _buf.asFloatBuffer(); + java.nio.FloatBuffer floatBuf = _buf.b.asFloatBuffer(); floatBuf.get(v); - _buf.position(_buf.position() + sz * 4); + _buf.b.position(_buf.b.position() + sz * 4); return v; } catch(java.nio.BufferUnderflowException ex) @@ -1066,7 +1035,7 @@ public class BasicStream writeDouble(double v) { expand(8); - _buf.putDouble(v); + _buf.b.putDouble(v); } public void @@ -1080,9 +1049,9 @@ public class BasicStream { writeSize(v.length); expand(v.length * 8); - java.nio.DoubleBuffer doubleBuf = _buf.asDoubleBuffer(); + java.nio.DoubleBuffer doubleBuf = _buf.b.asDoubleBuffer(); doubleBuf.put(v); - _buf.position(_buf.position() + v.length * 8); + _buf.b.position(_buf.b.position() + v.length * 8); } } @@ -1091,7 +1060,7 @@ public class BasicStream { try { - return _buf.getDouble(); + return _buf.b.getDouble(); } catch(java.nio.BufferUnderflowException ex) { @@ -1107,9 +1076,9 @@ public class BasicStream final int sz = readSize(); checkFixedSeq(sz, 8); double[] v = new double[sz]; - java.nio.DoubleBuffer doubleBuf = _buf.asDoubleBuffer(); + java.nio.DoubleBuffer doubleBuf = _buf.b.asDoubleBuffer(); doubleBuf.get(v); - _buf.position(_buf.position() + sz * 8); + _buf.b.position(_buf.b.position() + sz * 8); return v; } catch(java.nio.BufferUnderflowException ex) @@ -1170,14 +1139,14 @@ public class BasicStream } writeSize(b.limit()); expand(b.limit()); - _buf.put(b); + _buf.b.put(b); return; } _stringBytes[i] = (byte)_stringChars[i]; } writeSize(len); expand(len); - _buf.put(_stringBytes, 0, len); + _buf.b.put(_stringBytes, 0, len); } else { @@ -1228,7 +1197,7 @@ public class BasicStream { _stringChars = new char[len]; } - _buf.get(_stringBytes, 0, len); + _buf.b.get(_stringBytes, 0, len); // // It's more efficient to construct a string using a @@ -1356,7 +1325,7 @@ public class BasicStream } public void - readObject(IceInternal.Patcher patcher) + readObject(Patcher patcher) { Ice.Object v = null; @@ -1747,7 +1716,7 @@ public class BasicStream // for(java.util.Iterator i = patchlist.iterator(); i.hasNext(); ) { - IceInternal.Patcher p = (IceInternal.Patcher)i.next(); + Patcher p = (Patcher)i.next(); try { p.patch(v); @@ -1771,25 +1740,25 @@ public class BasicStream public int pos() { - return _buf.position(); + return _buf.b.position(); } public void pos(int n) { - _buf.position(n); + _buf.b.position(n); } public int size() { - return _limit; + return _buf.size(); } public boolean isEmpty() { - return _limit == 0; + return _buf.empty(); } private static class BufferedOutputStream extends java.io.OutputStream @@ -1865,8 +1834,8 @@ public class BasicStream // If the ByteBuffer is backed by an array then we can avoid // an extra copy by using the array directly. // - data = _buf.array(); - offset = _buf.arrayOffset(); + data = _buf.b.array(); + offset = _buf.b.arrayOffset(); } catch(Exception ex) { @@ -1874,7 +1843,7 @@ public class BasicStream // Otherwise, allocate an array to hold a copy of the uncompressed data. // data = new byte[size()]; - _buf.get(data); + _buf.b.get(data); } try @@ -1922,7 +1891,7 @@ public class BasicStream // Copy the header from the uncompressed stream to the // compressed one. // - cstream._buf.put(data, offset, headerSize); + cstream._buf.b.put(data, offset, headerSize); // // Add the size of the uncompressed stream before the @@ -1933,7 +1902,7 @@ public class BasicStream // // Add the compressed message body. // - cstream._buf.put(compressed, 0, compressedLen); + cstream._buf.b.put(compressed, 0, compressedLen); return cstream; } @@ -1960,8 +1929,8 @@ public class BasicStream // If the ByteBuffer is backed by an array then we can avoid // an extra copy by using the array directly. // - compressed = _buf.array(); - offset = _buf.arrayOffset(); + compressed = _buf.b.array(); + offset = _buf.b.arrayOffset(); } catch(Exception ex) { @@ -1969,7 +1938,7 @@ public class BasicStream // Otherwise, allocate an array to hold a copy of the compressed data. // compressed = new byte[size()]; - _buf.get(compressed); + _buf.b.get(compressed); } BasicStream ucStream = new BasicStream(_instance); @@ -2020,34 +1989,19 @@ public class BasicStream // Copy the header from the compressed stream to the uncompressed one. // ucStream.pos(0); - ucStream._buf.put(compressed, offset, headerSize); + ucStream._buf.b.put(compressed, offset, headerSize); return ucStream; } private void - expand(int size) + expand(int n) { - if(_buf.position() == _limit) + if(!_unlimited && _buf.b != null && _buf.b.position() + n > _messageSizeMax) { - int oldLimit = _limit; - _limit += size; - if(!_unlimited && _limit > _messageSizeMax) - { - throw new Ice.MemoryLimitException(); - } - if(_limit > _capacity) - { - final int cap2 = _capacity << 1; - int newCapacity = cap2 > _limit ? cap2 : _limit; - _buf.limit(oldLimit); - int pos = _buf.position(); - reallocate(newCapacity); - _capacity = _buf.capacity(); - _buf.limit(_capacity); - _buf.position(pos); - } + throw new Ice.MemoryLimitException(); } + _buf.expand(n); } private static final class DynamicObjectFactory implements Ice.ObjectFactory @@ -2334,52 +2288,9 @@ public class BasicStream return buf.toString(); } - private void - allocate(int size) - { - java.nio.ByteBuffer buf = null; - try - { - //buf = java.nio.ByteBuffer.allocateDirect(size); - buf = java.nio.ByteBuffer.allocate(size); - } - catch(OutOfMemoryError ex) - { - Ice.MarshalException e = new Ice.MarshalException(); - e.reason = "OutOfMemoryError occurred while allocating a ByteBuffer"; - e.initCause(ex); - throw e; - } - buf.order(java.nio.ByteOrder.LITTLE_ENDIAN); - _buf = buf; - } - - private void - reallocate(int size) - { - // - // Limit the buffer size to MessageSizeMax - // - if(!_unlimited) - { - size = size > _messageSizeMax ? _messageSizeMax : size; - } - - java.nio.ByteBuffer old = _buf; - assert(old != null); - - allocate(size); - assert(_buf != null); - - old.position(0); - _buf.put(old); - } - - private IceInternal.Instance _instance; + private Instance _instance; + private Buffer _buf; private Object _closure; - private java.nio.ByteBuffer _buf; - private int _capacity; // Cache capacity to avoid excessive method calls. - private int _limit; // Cache limit to avoid excessive method calls. private byte[] _stringBytes; // Reusable array for reading strings. private char[] _stringChars; // Reusable array for reading strings. diff --git a/java/src/IceInternal/BatchOutgoing.java b/java/src/IceInternal/BatchOutgoing.java new file mode 100644 index 00000000000..1e0071f047a --- /dev/null +++ b/java/src/IceInternal/BatchOutgoing.java @@ -0,0 +1,92 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public final class BatchOutgoing implements OutgoingMessageCallback +{ + public + BatchOutgoing(Ice.ConnectionI connection, Instance instance) + { + _connection = connection; + _sent = false; + _os = new BasicStream(instance); + } + + public + BatchOutgoing(RequestHandler handler) + { + _handler = handler; + _sent = false; + _os = new BasicStream(handler.getReference().getInstance()); + } + + public void + invoke() + { + assert(_handler != null || _connection != null); + + if(_handler != null && !_handler.flushBatchRequests(this) || + _connection != null && !_connection.flushBatchRequests(this)) + synchronized(this) + { + while(_exception == null && !_sent) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_exception != null) + { + throw _exception; + } + } + } + + public void + sent(boolean notify) + { + if(notify) + { + synchronized(this) + { + _sent = true; + notify(); + } + } + else + { + _sent = true; + } + } + + public synchronized void + finished(Ice.LocalException ex) + { + _exception = ex; + notify(); + } + + public BasicStream + os() + { + return _os; + } + + private RequestHandler _handler; + private Ice.ConnectionI _connection; + private BasicStream _os; + private boolean _sent; + private Ice.LocalException _exception; +} diff --git a/java/src/IceInternal/BatchOutgoingAsync.java b/java/src/IceInternal/BatchOutgoingAsync.java new file mode 100644 index 00000000000..94e15c2dca3 --- /dev/null +++ b/java/src/IceInternal/BatchOutgoingAsync.java @@ -0,0 +1,106 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public abstract class BatchOutgoingAsync implements OutgoingAsyncMessageCallback +{ + public + BatchOutgoingAsync() + { + } + + public abstract void ice_exception(Ice.LocalException ex); + + public final BasicStream + __os() + { + return __os; + } + + public final void + __sent(final Ice.ConnectionI connection) + { + synchronized(_monitor) + { + cleanup(); + } + } + + public final void + __finished(Ice.LocalException exc) + { + try + { + ice_exception(exc); + } + catch(java.lang.Exception ex) + { + warning(ex); + } + finally + { + synchronized(_monitor) + { + cleanup(); + } + } + } + + protected final void + __prepare(Instance instance) + { + synchronized(_monitor) + { + while(__os != null) + { + try + { + _monitor.wait(); + } + catch(InterruptedException ex) + { + } + } + + assert(__os == null); + __os = new BasicStream(instance); + } + } + + private final void + warning(java.lang.Exception ex) + { + if(__os != null) // Don't print anything if cleanup() was already called. + { + if(__os.instance().initializationData().properties.getPropertyAsIntWithDefault( + "Ice.Warn.AMICallback", 1) > 0) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + IceUtil.OutputBase out = new IceUtil.OutputBase(pw); + out.setUseTab(false); + out.print("exception raised by AMI callback:\n"); + ex.printStackTrace(pw); + pw.flush(); + __os.instance().initializationData().logger.warning(sw.toString()); + } + } + } + + private final void + cleanup() + { + __os = null; + _monitor.notify(); + } + + protected BasicStream __os; + private final java.lang.Object _monitor = new java.lang.Object(); +} diff --git a/java/src/IceInternal/Buffer.java b/java/src/IceInternal/Buffer.java new file mode 100644 index 00000000000..8795f5fccde --- /dev/null +++ b/java/src/IceInternal/Buffer.java @@ -0,0 +1,183 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +// +// An instance of java.nio.ByteBuffer cannot grow beyond its initial capacity. +// This class wraps a ByteBuffer and supports reallocation. +// +public class Buffer +{ + public + Buffer(int maxCapacity) + { + b = null; + _size = 0; + _capacity = 0; + _maxCapacity = maxCapacity; + } + + public int + size() + { + return _size; + } + + public boolean + empty() + { + return _size == 0; + } + + public void + clear() + { + b = null; + _size = 0; + _capacity = 0; + } + + // + // Call expand(n) to add room for n additional bytes. Note that expand() + // examines the current position of the buffer first; we don't want to + // expand the buffer if the caller is writing to a location that is + // already in the buffer. + // + public void + expand(int n) + { + final int sz = b == null ? n : b.position() + n; + if(sz > _size) + { + resize(sz, false); + } + } + + public void + resize(int n, boolean reading) + { + if(n == 0) + { + clear(); + } + else if(n > _capacity) + { + reserve(n); + } + _size = n; + + // + // When used for reading, we want to set the buffer's limit to the new size. + // + if(reading) + { + b.limit(_size); + } + } + + public void + reset() + { + if(_size > 0 && _size * 2 < _capacity) + { + // + // If the current buffer size is smaller than the + // buffer capacity, we shrink the buffer memory to the + // current size. This is to avoid holding on to too much + // memory if it's not needed anymore. + // + if(++_shrinkCounter > 2) + { + reserve(_size); + _shrinkCounter = 0; + } + } + else + { + _shrinkCounter = 0; + } + _size = 0; + if(b != null) + { + b.limit(b.capacity()); + b.position(0); + } + } + + private void + reserve(int n) + { + if(n > _capacity) + { + _capacity = java.lang.Math.max(n, java.lang.Math.min(2 * _capacity, _maxCapacity)); + _capacity = java.lang.Math.max(240, _capacity); + } + else if(n < _capacity) + { + _capacity = n; + } + else + { + return; + } + + try + { + java.nio.ByteBuffer buf; + + if(DIRECT) + { + buf = java.nio.ByteBuffer.allocateDirect(_capacity); + } + else + { + buf = java.nio.ByteBuffer.allocate(_capacity); + } + + if(b == null) + { + b = buf; + } + else + { + final int pos = b.position(); + b.position(0); + b.limit(java.lang.Math.min(_capacity, b.capacity())); + buf.put(b); + b = buf; + b.limit(b.capacity()); + b.position(pos); + } + + b.order(java.nio.ByteOrder.LITTLE_ENDIAN); + } + catch(OutOfMemoryError ex) + { + Ice.MarshalException e = new Ice.MarshalException(); + e.reason = "OutOfMemoryError occurred while allocating a ByteBuffer"; + e.initCause(ex); + throw e; + } + } + + public java.nio.ByteBuffer b; + + private int _size; + private int _capacity; // Cache capacity to avoid excessive method calls. + private int _maxCapacity; + private int _shrinkCounter; + + // + // This flag indicates whether we should use direct byte buffers. It is set to false + // because direct byte buffers have been known to cause problems in the past (for + // example, see bug 1582). + // + private static final boolean DIRECT = false; +} diff --git a/java/src/IceInternal/ConnectRequestHandler.java b/java/src/IceInternal/ConnectRequestHandler.java new file mode 100644 index 00000000000..45aa6c959b9 --- /dev/null +++ b/java/src/IceInternal/ConnectRequestHandler.java @@ -0,0 +1,480 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public class ConnectRequestHandler + implements RequestHandler, Reference.GetConnectionCallback, RouterInfo.AddProxyCallback +{ + static class Request + { + Request(BasicStream os) + { + this.os = new BasicStream(os.instance()); + this.os.swap(os); + } + + Request(OutgoingAsync out) + { + this.out = out; + } + + Request(BatchOutgoingAsync out) + { + this.batchOut = out; + } + + OutgoingAsync out = null; + BatchOutgoingAsync batchOut = null; + BasicStream os = null; + } + + public void + prepareBatchRequest(BasicStream os) + { + synchronized(this) + { + while(_batchRequestInProgress) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(!initialized()) + { + _batchStream.swap(os); + _batchRequestInProgress = true; + return; + } + } + + _connection.prepareBatchRequest(os); + } + + public void + finishBatchRequest(BasicStream os) + { + synchronized(this) + { + if(!initialized()) + { + assert(_batchRequestInProgress); + _batchRequestInProgress = false; + notifyAll(); + + _batchStream.swap(os); + + if(!_batchAutoFlush && + _batchStream.size() + _batchRequestsSize > _reference.getInstance().messageSizeMax()) + { + throw new Ice.MemoryLimitException(); + } + + _requests.add(new Request(_batchStream)); + return; + } + } + + _connection.finishBatchRequest(os, _compress); + } + + public void + abortBatchRequest() + { + synchronized(this) + { + if(!initialized()) + { + assert(_batchRequestInProgress); + _batchRequestInProgress = false; + notifyAll(); + + BasicStream dummy = new BasicStream(_reference.getInstance(), _batchAutoFlush); + _batchStream.swap(dummy); + _batchRequestsSize = Protocol.requestBatchHdr.length; + return; + } + } + + _connection.abortBatchRequest(); + } + + public Ice.ConnectionI + sendRequest(Outgoing out) + throws LocalExceptionWrapper + { + return (!getConnection(true).sendRequest(out, _compress, _response) || _response) ? _connection : null; + } + + public void + sendAsyncRequest(OutgoingAsync out) + { + try + { + synchronized(this) + { + if(!initialized()) + { + _requests.add(new Request(out)); + return; + } + } + + _connection.sendAsyncRequest(out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + out.__finished(ex); + } + catch(Ice.LocalException ex) + { + out.__finished(ex); + } + } + + public boolean + flushBatchRequests(BatchOutgoing out) + { + return getConnection(true).flushBatchRequests(out); + } + + public void + flushAsyncBatchRequests(BatchOutgoingAsync out) + { + try + { + synchronized(this) + { + if(!initialized()) + { + _requests.add(new Request(out)); + return; + } + } + + _connection.flushAsyncBatchRequests(out); + } + catch(Ice.LocalException ex) + { + out.__finished(ex); + } + } + + public Outgoing + getOutgoing(String operation, Ice.OperationMode mode, java.util.Map context) + throws LocalExceptionWrapper + { + synchronized(this) + { + if(!initialized()) + { + return new IceInternal.Outgoing(this, operation, mode, context); + } + } + + return _connection.getOutgoing(this, operation, mode, context); + } + + public void + reclaimOutgoing(Outgoing out) + { + synchronized(this) + { + if(_connection == null) + { + return; + } + } + + _connection.reclaimOutgoing(out); + } + + public Reference + getReference() + { + return _reference; + } + + synchronized public Ice.ConnectionI + getConnection(boolean wait) + { + if(wait) + { + // + // Wait for the connection establishment to complete or fail. + // + while(!_initialized && _exception == null) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + } + + if(_exception != null) + { + throw _exception; + } + else + { + assert(!wait || _initialized); + return _connection; + } + } + + // + // Implementation of Reference.GetConnectionCallback + // + + public void + setConnection(Ice.ConnectionI connection, boolean compress) + { + synchronized(this) + { + _connection = connection; + _compress = compress; + } + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + RouterInfo ri = _reference.getRouterInfo(); + if(ri != null) + { + if(!ri.addProxy(_proxy, this)) + { + return; // The request handler will be initialized once addProxy returns. + } + } + + flushRequests(); + } + + public void + setException(Ice.LocalException ex) + { + synchronized(this) + { + _exception = ex; + _proxy = null; // Break cyclic reference count. + _delegate = null; // Break cyclic reference count. + notifyAll(); + } + + java.util.Iterator p = _requests.iterator(); + while(p.hasNext()) + { + Request request = (Request)p.next(); + if(request.out != null) + { + request.out.__finished(ex); + } + else if(request.batchOut != null) + { + request.batchOut.__finished(ex); + } + } + _requests.clear(); + } + + // + // Implementation of RouterInfo.AddProxyCallback + // + public void + addedProxy() + { + flushRequests(); + } + + public + ConnectRequestHandler(Reference ref, Ice.ObjectPrx proxy, Ice._ObjectDelM delegate) + { + _reference = ref; + _response = _reference.getMode() == Reference.ModeTwoway; + _proxy = (Ice.ObjectPrxHelperBase)proxy; + _delegate = delegate; + _batchAutoFlush = ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault( + "Ice.BatchAutoFlush", 1) > 0 ? true : false; + _batchStream = new BasicStream(ref.getInstance(), _batchAutoFlush); + _batchRequestInProgress = false; + _batchRequestsSize = Protocol.requestBatchHdr.length; + _updateRequestHandler = false; + } + + public RequestHandler + connect() + { + _reference.getConnection(this); + + synchronized(this) + { + if(_connection != null) + { + return new ConnectionRequestHandler(_reference, _connection, _compress); + } + else + { + _updateRequestHandler = true; + return this; + } + } + } + + private boolean + initialized() + { + if(_initialized) + { + assert(_connection != null); + return true; + } + else + { + while(_flushing) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_exception != null) + { + throw _exception; + } + else + { + return _initialized; + } + } + } + + private void + flushRequests() + { + synchronized(this) + { + assert(_connection != null); + + if(_batchRequestInProgress) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + // + // We set the _flushing flag to true to prevent any additional queuing. Callers + // might block for a little while as the queued requests are being sent but this + // shouldn't be an issue as the request sends are non-blocking. + // + _flushing = true; + } + + java.util.Iterator p = _requests.iterator(); // _requests is immutable when _flushing = true + while(p.hasNext()) + { + Request request = (Request)p.next(); + if(request.out != null) + { + try + { + _connection.sendAsyncRequest(request.out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + request.out.__finished(ex); + } + catch(Ice.LocalException ex) + { + request.out.__finished(ex); + } + } + else if(request.batchOut != null) + { + try + { + _connection.flushAsyncBatchRequests(request.batchOut); + } + catch(Ice.LocalException ex) + { + request.batchOut.__finished(ex); + } + } + else + { + // + // TODO: Add sendBatchRequest() method to ConnectionI? + // + try + { + BasicStream os = new BasicStream(request.os.instance()); + _connection.prepareBatchRequest(os); + request.os.pos(0); + os.writeBlob(request.os.readBlob(request.os.size())); + _connection.finishBatchRequest(os, _compress); + } + catch(Ice.LocalException ex) + { + _connection.abortBatchRequest(); + _exception = ex; + } + } + } + _requests.clear(); + + synchronized(this) + { + _initialized = true; + _flushing = false; + notifyAll(); + } + + if(_updateRequestHandler && _exception == null) + { + _proxy.__setRequestHandler(_delegate, new ConnectionRequestHandler(_reference, _connection, _compress)); + } + _proxy = null; // Break cyclic reference count. + _delegate = null; // Break cyclic reference count. + } + + private final Reference _reference; + private final boolean _batchAutoFlush; + private Ice.ObjectPrxHelperBase _proxy; + private Ice._ObjectDelM _delegate; + private boolean _initialized = false; + private boolean _flushing = false; + private Ice.ConnectionI _connection = null; + private boolean _compress = false; + private boolean _response; + private Ice.LocalException _exception = null; + + private java.util.ArrayList _requests = new java.util.ArrayList(); + private boolean _batchRequestInProgress; + private int _batchRequestsSize; + private BasicStream _batchStream; + private boolean _updateRequestHandler; +} diff --git a/java/src/IceInternal/ConnectionMonitor.java b/java/src/IceInternal/ConnectionMonitor.java index 7f46d20f19b..3806b077b13 100644 --- a/java/src/IceInternal/ConnectionMonitor.java +++ b/java/src/IceInternal/ConnectionMonitor.java @@ -59,7 +59,7 @@ public final class ConnectionMonitor implements IceInternal.TimerTask } public void - run() + runTimerTask() { java.util.HashSet connections = new java.util.HashSet(); diff --git a/java/src/IceInternal/ConnectionRequestHandler.java b/java/src/IceInternal/ConnectionRequestHandler.java new file mode 100644 index 00000000000..2f1b1c031ed --- /dev/null +++ b/java/src/IceInternal/ConnectionRequestHandler.java @@ -0,0 +1,134 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public class ConnectionRequestHandler implements RequestHandler +{ + public void + prepareBatchRequest(BasicStream out) + { + _connection.prepareBatchRequest(out); + } + + public void + finishBatchRequest(BasicStream out) + { + _connection.finishBatchRequest(out, _compress); + } + + public void + abortBatchRequest() + { + _connection.abortBatchRequest(); + } + + public Ice.ConnectionI + sendRequest(Outgoing out) + throws LocalExceptionWrapper + { + return (!_connection.sendRequest(out, _compress, _response) || _response) ? _connection : null; + } + + public void + sendAsyncRequest(OutgoingAsync out) + { + try + { + _connection.sendAsyncRequest(out, _compress, _response); + } + catch(LocalExceptionWrapper ex) + { + out.__finished(ex); + } + catch(Ice.LocalException ex) + { + out.__finished(ex); + } + } + + public boolean + flushBatchRequests(BatchOutgoing out) + { + return _connection.flushBatchRequests(out); + } + + public void + flushAsyncBatchRequests(BatchOutgoingAsync out) + { + try + { + _connection.flushAsyncBatchRequests(out); + } + catch(Ice.LocalException ex) + { + out.__finished(ex); + } + } + + public Outgoing + getOutgoing(String operation, Ice.OperationMode mode, java.util.Map context) + throws LocalExceptionWrapper + { + return _connection.getOutgoing(this, operation, mode, context); + } + + public void + reclaimOutgoing(Outgoing out) + { + _connection.reclaimOutgoing(out); + } + + public Reference + getReference() + { + return _reference; + } + + public Ice.ConnectionI + getConnection(boolean wait) + { + return _connection; + } + + public + ConnectionRequestHandler(Reference ref, Ice.ObjectPrx proxy) + { + _reference = ref; + _response = _reference.getMode() == Reference.ModeTwoway; + + Ice.BooleanHolder compress = new Ice.BooleanHolder(); + _connection = _reference.getConnection(compress); + _compress = compress.value; + + // + // If this proxy is for a non-local object, and we are using a router, then + // add this proxy to the router info object. + // + IceInternal.RouterInfo ri = _reference.getRouterInfo(); + if(ri != null) + { + ri.addProxy(proxy); + } + } + + public + ConnectionRequestHandler(Reference ref, Ice.ConnectionI connection, boolean compress) + { + _reference = ref; + _response = _reference.getMode() == Reference.ModeTwoway; + _connection = connection; + _compress = compress; + } + + private final Reference _reference; + private final boolean _response; + private final Ice.ConnectionI _connection; + private final boolean _compress; +} diff --git a/java/src/IceInternal/Connector.java b/java/src/IceInternal/Connector.java index 7e4c5d16f37..52b71a84a6a 100644 --- a/java/src/IceInternal/Connector.java +++ b/java/src/IceInternal/Connector.java @@ -12,6 +12,7 @@ package IceInternal; public interface Connector { Transceiver connect(int timeout); + short type(); String toString(); diff --git a/java/src/IceInternal/DirectReference.java b/java/src/IceInternal/DirectReference.java index 56224453de5..2a60fda7e7a 100644 --- a/java/src/IceInternal/DirectReference.java +++ b/java/src/IceInternal/DirectReference.java @@ -116,7 +116,7 @@ public class DirectReference extends RoutableReference return getInstance().referenceFactory().create(getIdentity(), getContext(), getFacet(), getMode(), getSecure(), getPreferSecure(), newAdapterId, getRouterInfo(), locatorInfo, getCollocationOptimization(), getCacheConnection(), - getEndpointSelection(), getThreadPerConnection(), + getEndpointSelection(), getThreadPerConnection(), getLocatorCacheTimeout()); } @@ -188,28 +188,57 @@ public class DirectReference extends RoutableReference public Ice.ConnectionI getConnection(Ice.BooleanHolder comp) { - EndpointI[] endpts = super.getRoutedEndpoints(); - applyOverrides(endpts); - - if(endpts.length == 0) + if(getRouterInfo() != null) { - endpts = _endpoints; // Endpoint overrides are already applied on these endpoints. + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + EndpointI[] endpts = getRouterInfo().getClientEndpoints(); + if(endpts.length > 0) + { + applyOverrides(endpts); + return createConnection(endpts, comp); + } } - Ice.ConnectionI connection = createConnection(endpts, comp); + return createConnection(_endpoints, comp); + } - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // + public void + getConnection(final GetConnectionCallback callback) + { if(getRouterInfo() != null) { - connection.setAdapter(getRouterInfo().getAdapter()); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo().getClientEndpoints(new RouterInfo.GetClientEndpointsCallback() + { + public void + setEndpoints(EndpointI[] endpts) + { + if(endpts.length > 0) + { + applyOverrides(endpts); + createConnection(endpts, callback); + return; + } + + createConnection(_endpoints, callback); + } + + public void + setException(Ice.LocalException ex) + { + callback.setException(ex); + } + }); + return; } - assert(connection != null); - return connection; + createConnection(_endpoints, callback); } public boolean diff --git a/java/src/IceInternal/EndpointFactoryManager.java b/java/src/IceInternal/EndpointFactoryManager.java index 52b2e21888e..fc772b3f6fe 100644 --- a/java/src/IceInternal/EndpointFactoryManager.java +++ b/java/src/IceInternal/EndpointFactoryManager.java @@ -80,7 +80,7 @@ public final class EndpointFactoryManager EndpointI e = f.create(s.substring(m.end()), server); BasicStream bs = new BasicStream(_instance, true); e.streamWrite(bs); - java.nio.ByteBuffer buf = bs.prepareRead(); + java.nio.ByteBuffer buf = bs.getBuffer(); buf.position(0); short type = bs.readShort(); EndpointI ue = new IceInternal.UnknownEndpointI(type, bs); @@ -110,8 +110,8 @@ public final class EndpointFactoryManager // BasicStream bs = new BasicStream(_instance, true); ue.streamWrite(bs); - java.nio.ByteBuffer buf = bs.prepareRead(); - buf.position(0); + Buffer buf = bs.getBuffer(); + buf.b.position(0); short type = bs.readShort(); return f.read(bs); } @@ -136,7 +136,6 @@ public final class EndpointFactoryManager return f.read(s); } } - return new UnknownEndpointI(type, s); } diff --git a/java/src/IceInternal/EndpointHostResolver.java b/java/src/IceInternal/EndpointHostResolver.java new file mode 100644 index 00000000000..4ef6d756e0f --- /dev/null +++ b/java/src/IceInternal/EndpointHostResolver.java @@ -0,0 +1,166 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public class EndpointHostResolver +{ + EndpointHostResolver(Instance instance) + { + _instance = instance; + + _thread = new HelperThread(); + _thread.start(); + } + + synchronized public void + resolve(String host, int port, EndpointI endpoint, EndpointI_connectors callback) + { + // + // TODO: Optimize to avoid the lookup if the given host is a textual IPv4 or IPv6 + // address. This requires implementing parsing of IPv4/IPv6 addresses (Java does + // not provide such methods). + // + + assert(!_destroyed); + + ResolveEntry entry = new ResolveEntry(); + entry.host = host; + entry.port = port; + entry.endpoint = endpoint; + entry.callback = callback; + _queue.add(entry); + notify(); + } + + synchronized public void + destroy() + { + assert(!_destroyed); + _destroyed = true; + notify(); + } + + public void + joinWithThread() + { + if(_thread != null) + { + try + { + _thread.join(); + } + catch(InterruptedException ex) + { + } + } + } + + public void + run() + { + while(true) + { + ResolveEntry resolve; + synchronized(this) + { + while(!_destroyed && _queue.isEmpty()) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_destroyed) + { + break; + } + + resolve = (ResolveEntry)_queue.removeFirst(); + } + + resolve.callback.connectors(resolve.endpoint.connectors(Network.getAddresses(resolve.host, resolve.port))); + } + + java.util.Iterator p = _queue.iterator(); + while(p.hasNext()) + { + ((ResolveEntry)p.next()).callback.exception(new Ice.CommunicatorDestroyedException()); + } + _queue.clear(); + } + + class ResolveEntry + { + String host; + int port; + EndpointI endpoint; + EndpointI_connectors callback; + } + + private final Instance _instance; + private boolean _destroyed; + private java.util.LinkedList _queue = new java.util.LinkedList(); + + private final class HelperThread extends Thread + { + HelperThread() + { + String threadName = _instance.initializationData().properties.getProperty("Ice.ProgramName"); + if(threadName.length() > 0) + { + threadName += "-"; + } + setName(threadName + "Ice.EndpointHostResolverThread"); + } + + public void + run() + { + if(_instance.initializationData().threadHook != null) + { + _instance.initializationData().threadHook.start(); + } + + try + { + EndpointHostResolver.this.run(); + } + catch(Ice.LocalException ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "exception in endpoint host resolver thread " + getName() + ":\n" + sw.toString(); + _instance.initializationData().logger.error(s); + } + catch(java.lang.Exception ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "unknown exception in endpoint host resolver thread " + getName() + ":\n" + sw.toString(); + _instance.initializationData().logger.error(s); + } + + if(_instance.initializationData().threadHook != null) + { + _instance.initializationData().threadHook.stop(); + } + } + } + + private HelperThread _thread; +} diff --git a/java/src/IceInternal/EndpointI.java b/java/src/IceInternal/EndpointI.java index c0a29e2187e..8086bf138fd 100644 --- a/java/src/IceInternal/EndpointI.java +++ b/java/src/IceInternal/EndpointI.java @@ -86,7 +86,8 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable // Return connectors for this endpoint, or empty list if no connector // is available. // - public abstract java.util.ArrayList connectors(); + public abstract java.util.List connectors(); + public abstract void connectors_async(EndpointI_connectors callback); // // Return an acceptor for this endpoint, or null if no acceptors @@ -101,12 +102,12 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_NAY. // - public abstract java.util.ArrayList expand(); + public abstract java.util.List expand(); // - // Check whether the endpoint is equivalent to a specific Connector. + // Check whether the endpoint is equivalent to another one. // - public abstract boolean equivalent(Connector connector); + public abstract boolean equivalent(EndpointI endpoint); // // Compare endpoints for sorting purposes. @@ -120,4 +121,15 @@ abstract public class EndpointI implements Ice.Endpoint, java.lang.Comparable // TODO: Remove this when we no longer support SSL for JDK 1.4. // public abstract boolean requiresThreadPerConnection(); + + public java.util.List + connectors(java.util.List addresses) + { + // + // This method must be extended by endpoints which use the EndpointHostResolver to create + // connectors from IP addresses. + // + assert(false); + return null; + } } diff --git a/java/src/IceInternal/EndpointI_connectors.java b/java/src/IceInternal/EndpointI_connectors.java new file mode 100644 index 00000000000..dd4f8bba305 --- /dev/null +++ b/java/src/IceInternal/EndpointI_connectors.java @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public interface EndpointI_connectors +{ + void connectors(java.util.List connectors); + void exception(Ice.LocalException ex); +}
\ No newline at end of file diff --git a/java/src/IceInternal/EventHandler.java b/java/src/IceInternal/EventHandler.java index 3a0ed6231a2..11241725083 100644 --- a/java/src/IceInternal/EventHandler.java +++ b/java/src/IceInternal/EventHandler.java @@ -25,12 +25,17 @@ public abstract class EventHandler // Read data via the event handler. May only be called if // readable() returns true. // - // NOTE: In Java, read returns true if the handler has more data - // data available, and therefore read should be called again. - // abstract public boolean read(BasicStream is); // + // In Java, it's possible that the transceiver reads more data + // than what was really asked. If this is the case, hasMoreData() + // returns true and the handler read() method should be called + // again (without doing a select()). + // + abstract public boolean hasMoreData(); + + // // A complete message has been received. // abstract public void message(BasicStream stream, ThreadPool threadPool); @@ -68,7 +73,8 @@ public abstract class EventHandler protected Instance _instance; // - // The _stream data member is for use by ThreadPool only. + // The _stream data member is only for use by the ThreadPool or by the + // connection for validation. // - BasicStream _stream; + protected BasicStream _stream; } diff --git a/java/src/IceInternal/FixedReference.java b/java/src/IceInternal/FixedReference.java index 055dc12b288..d86791e7fb0 100644 --- a/java/src/IceInternal/FixedReference.java +++ b/java/src/IceInternal/FixedReference.java @@ -198,6 +198,20 @@ public class FixedReference extends Reference return connection; } + public void + getConnection(GetConnectionCallback callback) + { + try + { + Ice.BooleanHolder compress = new Ice.BooleanHolder(); + callback.setConnection(getConnection(compress), compress.value); + } + catch(Ice.LocalException ex) + { + callback.setException(ex); + } + } + public boolean equals(java.lang.Object obj) { diff --git a/java/src/IceInternal/IncomingConnectionFactory.java b/java/src/IceInternal/IncomingConnectionFactory.java index 5f2fdb15201..2d01a11be95 100644 --- a/java/src/IceInternal/IncomingConnectionFactory.java +++ b/java/src/IceInternal/IncomingConnectionFactory.java @@ -9,7 +9,7 @@ package IceInternal; -public final class IncomingConnectionFactory extends EventHandler +public final class IncomingConnectionFactory extends EventHandler implements Ice.ConnectionI.StartCallback { public synchronized void activate() @@ -73,7 +73,7 @@ public final class IncomingConnectionFactory extends EventHandler waitUntilFinished() { Thread threadPerIncomingConnectionFactory = null; - java.util.LinkedList connections; + java.util.LinkedList connections = null; synchronized(this) { @@ -104,12 +104,10 @@ public final class IncomingConnectionFactory extends EventHandler // We want to wait until all connections are finished outside the // thread synchronization. // - // For consistency with C#, we set _connections to null rather than to a - // new empty list so that our finalizer does not try to invoke any - // methods on member objects. - // - connections = _connections; - _connections = null; + if(_connections != null) + { + connections = new java.util.LinkedList(_connections); + } } if(threadPerIncomingConnectionFactory != null) @@ -136,6 +134,16 @@ public final class IncomingConnectionFactory extends EventHandler connection.waitUntilFinished(); } } + + synchronized(this) + { + // + // For consistency with C#, we set _connections to null rather than to a + // new empty list so that our finalizer does not try to invoke any + // methods on member objects. + // + _connections = null; + } } public EndpointI @@ -145,7 +153,7 @@ public final class IncomingConnectionFactory extends EventHandler return _endpoint; } - public synchronized Ice.ConnectionI[] + public synchronized java.util.LinkedList connections() { java.util.LinkedList connections = new java.util.LinkedList(); @@ -157,26 +165,24 @@ public final class IncomingConnectionFactory extends EventHandler while(p.hasNext()) { Ice.ConnectionI connection = (Ice.ConnectionI)p.next(); - if(!connection.isDestroyed()) + if(connection.isActiveOrHolding()) { connections.add(connection); } } - - Ice.ConnectionI[] arr = new Ice.ConnectionI[connections.size()]; - connections.toArray(arr); - return arr; + + return connections; } public void flushBatchRequests() { - Ice.ConnectionI[] c = connections(); // connections() is synchronized, so no need to synchronize here. - for(int i = 0; i < c.length; i++) + java.util.Iterator p = connections().iterator(); // connections() is synchronized, no need to synchronize here. + while(p.hasNext()) { try { - c[i].flushBatchRequests(); + ((Ice.ConnectionI)p.next()).flushBatchRequests(); } catch(Ice.LocalException ex) { @@ -211,6 +217,14 @@ public final class IncomingConnectionFactory extends EventHandler return false; } + public boolean + hasMoreData() + { + assert(!_threadPerConnection); // Only for use with a thread pool. + assert(false); // Must not be called. + return false; + } + public void message(BasicStream unused, ThreadPool threadPool) { @@ -218,9 +232,9 @@ public final class IncomingConnectionFactory extends EventHandler Ice.ConnectionI connection = null; - synchronized(this) + try { - try + synchronized(this) { if(_state != StateActive) { @@ -244,7 +258,7 @@ public final class IncomingConnectionFactory extends EventHandler // // Now accept a new connection. // - Transceiver transceiver; + Transceiver transceiver = null; try { transceiver = _acceptor.accept(0); @@ -275,47 +289,38 @@ public final class IncomingConnectionFactory extends EventHandler { assert(!_threadPerConnection); connection = new Ice.ConnectionI(_instance, transceiver, _endpoint, _adapter, false); - connection.start(); } catch(Ice.LocalException ex) { + try + { + transceiver.close(); + } + catch(Ice.LocalException exc) + { + // Ignore + } + + if(_warn) + { + warning(ex); + } return; } _connections.add(connection); } - finally - { - // - // This makes sure that we promote a follower before - // we leave the scope of the mutex above, but after we - // call accept() (if we call it). - // - threadPool.promoteFollower(); - } } - - assert(connection != null); - - // - // We validate and activate outside the thread - // synchronization, to not block the factory. - // - try + finally { - connection.validate(); - } - catch(Ice.LocalException ex) - { - synchronized(this) - { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - _connections.remove(connection); - return; - } + // + // This makes sure that we promote a follower before we leave the scope of the mutex + // above, but after we call accept() (if we call it). + // + threadPool.promoteFollower(); } - connection.activate(); + connection.start(this); } public synchronized void @@ -354,9 +359,48 @@ public final class IncomingConnectionFactory extends EventHandler return _acceptor.toString(); } + // + // Operations from ConnectionI.StartCallback + // + public synchronized void + connectionStartCompleted(Ice.ConnectionI connection) + { + // + // Initially, connections are in the holding state. If the factory is active + // we activate the connection. + // + if(_state == StateActive) + { + connection.activate(); + } + } + + public synchronized void + connectionStartFailed(Ice.ConnectionI connection, Ice.LocalException ex) + { + if(_state == StateClosed) + { + return; + } + + if(_warn) + { + warning(ex); + } + + // + // If the connection is finished, remove it right away from + // the connection map. Otherwise, we keep it in the map, it + // will eventually be reaped. + // + if(connection.isFinished()) + { + _connections.remove(connection); + } + } + public - IncomingConnectionFactory(Instance instance, EndpointI endpoint, Ice.ObjectAdapter adapter, - String adapterName) + IncomingConnectionFactory(Instance instance, EndpointI endpoint, Ice.ObjectAdapter adapter, String adapterName) { super(instance); _endpoint = endpoint; @@ -390,28 +434,25 @@ public final class IncomingConnectionFactory extends EventHandler { _endpoint = h.value; - Ice.ConnectionI connection = null; - - try - { - connection = new Ice.ConnectionI(_instance, _transceiver, _endpoint, _adapter, + Ice.ConnectionI connection; + try + { + connection = new Ice.ConnectionI(_instance, _transceiver, _endpoint, _adapter, _threadPerConnection); - connection.start(); - connection.validate(); - } - catch(Ice.LocalException ex) - { - // - // If a connection object was constructed, then - // validate() must have raised the exception. - // - if(connection != null) - { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - } - - return; - } + } + catch(Ice.LocalException ex) + { + try + { + _transceiver.close(); + } + catch(Ice.LocalException exc) + { + // Ignore + } + throw ex; + } + connection.start(null); _connections.add(connection); } @@ -654,8 +695,7 @@ public final class IncomingConnectionFactory extends EventHandler } catch(Ice.SocketException ex) { - // Do not ignore SocketException in Java. - throw ex; + // Ignore socket exceptions. } catch(Ice.TimeoutException ex) { @@ -669,9 +709,8 @@ public final class IncomingConnectionFactory extends EventHandler warning(ex); } } - + Ice.ConnectionI connection = null; - synchronized(this) { while(_state == StateHolding) @@ -730,37 +769,42 @@ public final class IncomingConnectionFactory extends EventHandler } } - // - // Create a connection object for the connection. - // - if(transceiver != null) + if(transceiver == null) { - try - { - connection = new Ice.ConnectionI(_instance, transceiver, _endpoint, _adapter, - _threadPerConnection); - connection.start(); - } - catch(Ice.LocalException ex) + continue; + } + + try + { + connection = new Ice.ConnectionI(_instance, transceiver, _endpoint, _adapter, _threadPerConnection); + } + catch(Ice.LocalException ex) + { + try + { + transceiver.close(); + } + catch(Ice.LocalException exc) + { + // Ignore + } + + if(_warn) { - return; + warning(ex); } - - _connections.add(connection); + continue; } + _connections.add(connection); } // - // In thread per connection mode, the connection's thread - // will take care of connection validation and activation - // (for non-datagram connections). We don't want to block - // this thread waiting until validation is complete, - // because in contrast to thread pool mode, it is the only - // thread that can accept connections with this factory's - // acceptor. Therefore we don't call validate() and - // activate() from the connection factory in thread per - // connection mode. + // In thread-per-connection mode and regardless of the background mode, + // start() doesn't block. The connection thread is started and takes + // care of the connection validation and notifies the factory through + // the callback when it's done. // + connection.start(this); } } @@ -796,5 +840,5 @@ public final class IncomingConnectionFactory extends EventHandler private int _state; - private boolean _threadPerConnection; + private final boolean _threadPerConnection; } diff --git a/java/src/IceInternal/IndirectReference.java b/java/src/IceInternal/IndirectReference.java index 004d63350dc..55eb6f60c13 100644 --- a/java/src/IceInternal/IndirectReference.java +++ b/java/src/IceInternal/IndirectReference.java @@ -163,23 +163,38 @@ public class IndirectReference extends RoutableReference public Ice.ConnectionI getConnection(Ice.BooleanHolder comp) { - Ice.ConnectionI connection; + if(getRouterInfo() != null) + { + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + EndpointI[] endpts = getRouterInfo().getClientEndpoints(); + if(endpts.length > 0) + { + applyOverrides(endpts); + return createConnection(endpts, comp); + } + } while(true) { - EndpointI[] endpts = super.getRoutedEndpoints(); Ice.BooleanHolder cached = new Ice.BooleanHolder(false); - if(endpts.length == 0 && _locatorInfo != null) + EndpointI[] endpts = null; + if(_locatorInfo != null) { endpts = _locatorInfo.getEndpoints(this, _locatorCacheTimeout, cached); + applyOverrides(endpts); } - applyOverrides(endpts); + if(endpts == null || endpts.length == 0) + { + throw new Ice.NoEndpointException(toString()); + } try { - connection = createConnection(endpts, comp); - assert(connection != null); + return createConnection(endpts, comp); } catch(Ice.NoEndpointException ex) { @@ -187,44 +202,132 @@ public class IndirectReference extends RoutableReference } catch(Ice.LocalException ex) { - if(getRouterInfo() == null) + assert(_locatorInfo != null); + _locatorInfo.clearCache(this); + if(cached.value) { - assert(_locatorInfo != null); - _locatorInfo.clearCache(this); - - if(cached.value) + TraceLevels traceLevels = getInstance().traceLevels(); + if(traceLevels.retry >= 2) { - TraceLevels traceLevels = getInstance().traceLevels(); - - if(traceLevels.retry >= 2) - { - String s = "connection to cached endpoints failed\n" + - "removing endpoints from cache and trying one more time\n" + ex; - getInstance().initializationData().logger.trace(traceLevels.retryCat, s); - } - - continue; + String s = "connection to cached endpoints failed\n" + + "removing endpoints from cache and trying one more time\n" + ex; + getInstance().initializationData().logger.trace(traceLevels.retryCat, s); } + continue; // Try again if the endpoints were cached. } - throw ex; } - - break; } + } - // - // If we have a router, set the object adapter for this router - // (if any) to the new connection, so that callbacks from the - // router can be received over this new connection. - // + public void + getConnection(final GetConnectionCallback callback) + { if(getRouterInfo() != null) { - connection.setAdapter(getRouterInfo().getAdapter()); + // + // If we route, we send everything to the router's client + // proxy endpoints. + // + getRouterInfo().getClientEndpoints(new RouterInfo.GetClientEndpointsCallback() + { + public void + setEndpoints(EndpointI[] endpts) + { + if(endpts.length > 0) + { + applyOverrides(endpts); + createConnection(endpts, callback); + } + else + { + getConnectionNoRouterInfo(callback); + } + } + + public void + setException(Ice.LocalException ex) + { + callback.setException(ex); + } + }); } + else + { + getConnectionNoRouterInfo(callback); + } + } - assert(connection != null); - return connection; + private void + getConnectionNoRouterInfo(final GetConnectionCallback callback) + { + final IndirectReference self = this; + if(_locatorInfo != null) + { + _locatorInfo.getEndpoints(this, _locatorCacheTimeout, new LocatorInfo.GetEndpointsCallback() + { + public void + setEndpoints(EndpointI[] endpoints, final boolean cached) + { + if(endpoints.length == 0) + { + callback.setException(new Ice.NoEndpointException(self.toString())); + return; + } + + applyOverrides(endpoints); + createConnection(endpoints, new GetConnectionCallback() + { + public void + setConnection(Ice.ConnectionI connection, boolean compress) + { + callback.setConnection(connection, compress); + } + + public void + setException(Ice.LocalException exc) + { + try + { + throw exc; + } + catch(Ice.NoEndpointException ex) + { + callback.setException(ex); // No need to retry if there's no endpoints. + } + catch(Ice.LocalException ex) + { + assert(_locatorInfo != null); + _locatorInfo.clearCache(self); + if(cached) + { + TraceLevels traceLvls = getInstance().traceLevels(); + if(traceLvls.retry >= 2) + { + String s = "connection to cached endpoints failed\n" + + "removing endpoints from cache and trying one more time\n" + ex; + getInstance().initializationData().logger.trace(traceLvls.retryCat, s); + } + getConnectionNoRouterInfo(callback); // Retry. + return; + } + callback.setException(ex); + } + } + }); + } + + public void + setException(Ice.LocalException ex) + { + callback.setException(ex); + } + }); + } + else + { + callback.setException(new Ice.NoEndpointException(toString())); + } } public synchronized int diff --git a/java/src/IceInternal/Instance.java b/java/src/IceInternal/Instance.java index 3051450518d..aea0de5b8e7 100644 --- a/java/src/IceInternal/Instance.java +++ b/java/src/IceInternal/Instance.java @@ -158,14 +158,46 @@ public final class Instance return _serverThreadPool; } + public synchronized SelectorThread + selectorThread() + { + if(_state == StateDestroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + if(_selectorThread == null) // Lazy initialization. + { + _selectorThread = new SelectorThread(this); + } + + return _selectorThread; + } + + public synchronized EndpointHostResolver + endpointHostResolver() + { + if(_state == StateDestroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + if(_endpointHostResolver == null) // Lazy initialization. + { + _endpointHostResolver = new EndpointHostResolver(this); + } + + return _endpointHostResolver; + } + synchronized public Timer timer() { if(_state == StateDestroyed) { throw new Ice.CommunicatorDestroyedException(); - } - + } + if(_timer == null) // Lazy initialization. { _timer = new Timer(this); @@ -186,6 +218,12 @@ public final class Instance return _threadPerConnectionStackSize; } + public boolean + background() + { + return _background; + } + public synchronized EndpointFactoryManager endpointFactoryManager() { @@ -598,6 +636,8 @@ public final class Instance _threadPerConnectionStackSize = stackSize; } + _background = _initData.properties.getPropertyAsInt("Ice.Background") > 0; + _routerManager = new RouterManager(); _locatorManager = new LocatorManager(); @@ -655,6 +695,8 @@ public final class Instance IceUtil.Assert.FinalizerAssert(_objectAdapterFactory == null); IceUtil.Assert.FinalizerAssert(_clientThreadPool == null); IceUtil.Assert.FinalizerAssert(_serverThreadPool == null); + IceUtil.Assert.FinalizerAssert(_selectorThread == null); + IceUtil.Assert.FinalizerAssert(_endpointHostResolver == null); IceUtil.Assert.FinalizerAssert(_timer == null); IceUtil.Assert.FinalizerAssert(_routerManager == null); IceUtil.Assert.FinalizerAssert(_locatorManager == null); @@ -777,6 +819,8 @@ public final class Instance ThreadPool serverThreadPool = null; ThreadPool clientThreadPool = null; + SelectorThread selectorThread = null; + EndpointHostResolver endpointHostResolver = null; synchronized(this) { @@ -804,6 +848,20 @@ public final class Instance _clientThreadPool = null; } + if(_selectorThread != null) + { + _selectorThread.destroy(); + selectorThread = _selectorThread; + _selectorThread = null; + } + + if(_endpointHostResolver != null) + { + _endpointHostResolver.destroy(); + endpointHostResolver = _endpointHostResolver; + _endpointHostResolver = null; + } + if(_timer != null) { _timer._destroy(); @@ -857,8 +915,7 @@ public final class Instance } // - // Join with the thread pool threads outside the - // synchronization. + // Join with threads outside the synchronization. // if(clientThreadPool != null) { @@ -868,6 +925,14 @@ public final class Instance { serverThreadPool.joinWithAllThreads(); } + if(selectorThread != null) + { + selectorThread.joinWithThread(); + } + if(endpointHostResolver != null) + { + endpointHostResolver.joinWithThread(); + } if(_initData.properties.getPropertyAsInt("Ice.Warn.UnusedProperties") > 0) { @@ -935,9 +1000,12 @@ public final class Instance private ObjectAdapterFactory _objectAdapterFactory; private ThreadPool _clientThreadPool; private ThreadPool _serverThreadPool; + private SelectorThread _selectorThread; + private EndpointHostResolver _endpointHostResolver; private Timer _timer; private final boolean _threadPerConnection; private final int _threadPerConnectionStackSize; + private final boolean _background; private EndpointFactoryManager _endpointFactoryManager; private Ice.PluginManager _pluginManager; private java.util.Map _defaultContext; diff --git a/java/src/IceInternal/LocatorInfo.java b/java/src/IceInternal/LocatorInfo.java index 0d54d87555a..c5b4b1d0060 100644 --- a/java/src/IceInternal/LocatorInfo.java +++ b/java/src/IceInternal/LocatorInfo.java @@ -11,6 +11,12 @@ package IceInternal; public final class LocatorInfo { + interface GetEndpointsCallback + { + void setEndpoints(EndpointI[] endpoints, boolean cached); + void setException(Ice.LocalException ex); + } + LocatorInfo(Ice.LocatorPrx locator, LocatorTable table) { _locator = locator; @@ -158,94 +164,137 @@ public final class LocatorInfo cached.value = objectCached || endpointsCached; } } - catch(Ice.AdapterNotFoundException ex) + catch(Exception ex) { - if(ref.getInstance().traceLevels().location >= 1) - { - StringBuffer s = new StringBuffer(); - s.append("adapter not found\n"); - s.append("adapter = " + adapterId); - ref.getInstance().initializationData().logger.trace( - ref.getInstance().traceLevels().locationCat, s.toString()); - } - - Ice.NotRegisteredException e = new Ice.NotRegisteredException(); - e.kindOfObject = "object adapter"; - e.id = adapterId; - throw e; + getEndpointsException(ref, ex); } - catch(Ice.ObjectNotFoundException ex) - { - if(ref.getInstance().traceLevels().location >= 1) - { - StringBuffer s = new StringBuffer(); - s.append("object not found\n"); - s.append("object = " + ref.getInstance().identityToString(identity)); - ref.getInstance().initializationData().logger.trace( - ref.getInstance().traceLevels().locationCat, s.toString()); - } - Ice.NotRegisteredException e = new Ice.NotRegisteredException(); - e.kindOfObject = "object"; - e.id = ref.getInstance().identityToString(identity); - throw e; - } - catch(Ice.NotRegisteredException ex) + if(ref.getInstance().traceLevels().location >= 1) { - throw ex; + getEndpointsTrace(ref, endpoints, cached.value); } - catch(Ice.LocalException ex) + + return endpoints == null ? new EndpointI[0] : endpoints; + } + + public void + getEndpoints(final IndirectReference ref, final int ttl, final GetEndpointsCallback callback) + { + final String adapterId = ref.getAdapterId(); + final Ice.Identity identity = ref.getIdentity(); + final Instance instance = ref.getInstance(); + if(adapterId.length() > 0) { - if(ref.getInstance().traceLevels().location >= 1) + EndpointI[] endpoints = _table.getAdapterEndpoints(adapterId, ttl); + if(endpoints == null) { - StringBuffer s = new StringBuffer(); - s.append("couldn't contact the locator to retrieve adapter endpoints\n"); - if(adapterId.length() > 0) + if(instance.traceLevels().location >= 1) { - s.append("adapter = " + adapterId + "\n"); + StringBuffer s = new StringBuffer(); + s.append("searching for adapter by id\n"); + s.append("adapter = " + adapterId); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } - else + + // + // Search the adapter in the location service if we didn't + // find it in the cache. + // + _locator.findAdapterById_async(new Ice.AMI_Locator_findAdapterById() + { + public void + ice_response(Ice.ObjectPrx object) + { + EndpointI[] endpoints = null; + if(object != null) + { + endpoints = ((Ice.ObjectPrxHelperBase)object).__reference().getEndpoints(); + if(endpoints.length > 0) + { + _table.addAdapterEndpoints(adapterId, endpoints); + } + } + + if(instance.traceLevels().location >= 1) + { + getEndpointsTrace(ref, endpoints, false); + } + + if(endpoints == null) + { + callback.setEndpoints(new EndpointI[0], false); + } + else + { + callback.setEndpoints(endpoints, false); + } + } + + public void + ice_exception(Ice.UserException ex) + { + getEndpointsException(ref, ex, callback); + } + + public void + ice_exception(Ice.LocalException ex) + { + getEndpointsException(ref, ex, callback); + } + }, adapterId); + return; + } + else + { + if(instance.traceLevels().location >= 1) { - s.append("object = " + ref.getInstance().identityToString(identity) + "\n"); + getEndpointsTrace(ref, endpoints, true); } - s.append("reason = " + ex); - ref.getInstance().initializationData().logger.trace( - ref.getInstance().traceLevels().locationCat, s.toString()); + callback.setEndpoints(endpoints, true); + return; } - throw ex; } - - if(ref.getInstance().traceLevels().location >= 1) + else { - if(endpoints != null && endpoints.length > 0) + Ice.ObjectPrx object = _table.getProxy(identity, ttl); + if(object == null) { - if(cached.value) - { - trace("found endpoints in locator table", ref, endpoints); - } - else + if(instance.traceLevels().location >= 1) { - trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + StringBuffer s = new StringBuffer(); + s.append("searching for object by id\n"); + s.append("object = " + instance.identityToString(identity)); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); } + + _locator.findObjectById_async(new Ice.AMI_Locator_findObjectById() + { + public void + ice_response(Ice.ObjectPrx object) + { + getWellKnownObjectEndpoints(ref, object, ttl, false, callback); + } + + public void + ice_exception(Ice.UserException ex) + { + getEndpointsException(ref, ex, callback); + } + + public void + ice_exception(Ice.LocalException ex) + { + getEndpointsException(ref, ex, callback); + } + }, identity); + return; } else { - StringBuffer s = new StringBuffer(); - s.append("no endpoints configured for "); - if(adapterId.length() > 0) - { - s.append("adapter\n"); - s.append("adapter = " + adapterId + "\n"); - } - else - { - s.append("object\n"); - s.append("object = " + ref.getInstance().identityToString(identity) + "\n"); - } + getWellKnownObjectEndpoints(ref, object, ttl, true, callback); + return; } } - - return endpoints == null ? new EndpointI[0] : endpoints; } public void @@ -333,14 +382,204 @@ public final class LocatorInfo { s.append(endpoints[i].toString()); if(i + 1 < sz) + { s.append(":"); + } } ref.getInstance().initializationData().logger.trace(ref.getInstance().traceLevels().locationCat, s.toString()); } + private void + getEndpointsException(IndirectReference ref, Exception exc) + { + try + { + throw exc; + } + catch(Ice.AdapterNotFoundException ex) + { + final Instance instance = ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + StringBuffer s = new StringBuffer(); + s.append("adapter not found\n"); + s.append("adapter = " + ref.getAdapterId()); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + } + + Ice.NotRegisteredException e = new Ice.NotRegisteredException(); + e.kindOfObject = "object adapter"; + e.id = ref.getAdapterId(); + throw e; + } + catch(Ice.ObjectNotFoundException ex) + { + final Instance instance = ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + StringBuffer s = new StringBuffer(); + s.append("object not found\n"); + s.append("object = " + instance.identityToString(ref.getIdentity())); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + } + + Ice.NotRegisteredException e = new Ice.NotRegisteredException(); + e.kindOfObject = "object"; + e.id = instance.identityToString(ref.getIdentity()); + throw e; + } + catch(Ice.NotRegisteredException ex) + { + throw ex; + } + catch(Ice.LocalException ex) + { + final Instance instance = ref.getInstance(); + if(instance.traceLevels().location >= 1) + { + StringBuffer s = new StringBuffer(); + s.append("couldn't contact the locator to retrieve adapter endpoints\n"); + if(ref.getAdapterId().length() > 0) + { + s.append("adapter = " + ref.getAdapterId() + "\n"); + } + else + { + s.append("object = " + instance.identityToString(ref.getIdentity()) + "\n"); + } + s.append("reason = " + ex); + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + } + throw ex; + } + catch(Exception ex) + { + assert(false); + } + } + + private void + getEndpointsException(IndirectReference ref, Exception exc, GetEndpointsCallback callback) + { + try + { + getEndpointsException(ref, exc); + } + catch(Ice.LocalException ex) + { + callback.setException(ex); + } + catch(Exception ex) + { + assert(false); + } + } + + private void + getWellKnownObjectEndpoints(final IndirectReference ref, + final Ice.ObjectPrx object, + final int ttl, + final boolean objectCached, + final GetEndpointsCallback callback) + { + EndpointI[] endpoints = null; + if(object != null) + { + Reference r = ((Ice.ObjectPrxHelperBase)object).__reference(); + if(r instanceof DirectReference) + { + DirectReference odr = (DirectReference)r; + endpoints = odr.getEndpoints(); + } + else + { + IndirectReference oir = (IndirectReference)r; + if(oir.getAdapterId().length() > 0) + { + getEndpoints(oir, ttl, new GetEndpointsCallback() + { + public void + setEndpoints(EndpointI[] endpoints, boolean endpointsCached) + { + if(!objectCached && endpoints != null && endpoints.length > 0) + { + _table.addProxy(ref.getIdentity(), object); + } + + if(ref.getInstance().traceLevels().location >= 1) + { + getEndpointsTrace(ref, endpoints, objectCached || endpointsCached); + } + + callback.setEndpoints(endpoints, objectCached || endpointsCached); + } + + public void + setException(Ice.LocalException ex) + { + callback.setException(ex); + } + }); + return; + } + } + } + + if(!objectCached && endpoints != null && endpoints.length > 0) + { + _table.addProxy(ref.getIdentity(), object); + } + + if(ref.getInstance().traceLevels().location >= 1) + { + getEndpointsTrace(ref, endpoints, objectCached); + } + + if(endpoints == null) + { + callback.setEndpoints(new EndpointI[0], false); + } + else + { + callback.setEndpoints(endpoints, objectCached); + } + } + + private void + getEndpointsTrace(IndirectReference ref, EndpointI[] endpoints, boolean cached) + { + if(endpoints != null && endpoints.length > 0) + { + if(cached) + { + trace("found endpoints in locator table", ref, endpoints); + } + else + { + trace("retrieved endpoints from locator, adding to locator table", ref, endpoints); + } + } + else + { + final Instance instance = ref.getInstance(); + StringBuffer s = new StringBuffer(); + s.append("no endpoints configured for "); + if(ref.getAdapterId().length() > 0) + { + s.append("adapter\n"); + s.append("adapter = " + ref.getAdapterId() + "\n"); + } + else + { + s.append("object\n"); + s.append("object = " + instance.identityToString(ref.getIdentity()) + "\n"); + } + instance.initializationData().logger.trace(instance.traceLevels().locationCat, s.toString()); + } + } + private final Ice.LocatorPrx _locator; private Ice.LocatorRegistryPrx _locatorRegistry; private final LocatorTable _table; } - diff --git a/java/src/IceInternal/Network.java b/java/src/IceInternal/Network.java index 07770711f45..5971e1122d5 100644 --- a/java/src/IceInternal/Network.java +++ b/java/src/IceInternal/Network.java @@ -162,7 +162,7 @@ public final class Network } } - private static void + public static void closeSocketNoThrow(java.nio.channels.SelectableChannel fd) { try @@ -274,13 +274,74 @@ public final class Network } } - public static void + public static boolean doConnect(java.nio.channels.SocketChannel fd, java.net.InetSocketAddress addr, int timeout) { try { if(!fd.connect(addr)) { + if(timeout == 0) + { + return false; + } + + try + { + doFinishConnect(fd, timeout); + } + catch(Ice.LocalException ex) + { + closeSocketNoThrow(fd); + throw ex; + } + return true; + } + } + catch(java.net.ConnectException ex) + { + closeSocketNoThrow(fd); + + Ice.ConnectFailedException se; + if(connectionRefused(ex)) + { + se = new Ice.ConnectionRefusedException(); + } + else + { + se = new Ice.ConnectFailedException(); + } + se.initCause(ex); + throw se; + } + catch(java.io.IOException ex) + { + closeSocketNoThrow(fd); + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + + if(addr.equals(fd.socket().getLocalSocketAddress())) + { + closeSocketNoThrow(fd); + throw new Ice.ConnectionRefusedException(); + } + return true; + } + + public static void + doFinishConnect(java.nio.channels.SocketChannel fd, int timeout) + { + // + // Note: we don't close the socket if there's an exception. It's the responsibility + // of the caller to do so. + // + + if(timeout != 0) + { + try + { java.nio.channels.Selector selector = java.nio.channels.Selector.open(); try { @@ -288,17 +349,13 @@ public final class Network { try { - java.nio.channels.SelectionKey key = + java.nio.channels.SelectionKey key = fd.register(selector, java.nio.channels.SelectionKey.OP_CONNECT); int n; if(timeout > 0) { n = selector.select(timeout); } - else if(timeout == 0) - { - n = selector.selectNow(); - } else { n = selector.select(); @@ -306,7 +363,6 @@ public final class Network if(n == 0) { - closeSocketNoThrow(fd); throw new Ice.ConnectTimeoutException(); } @@ -335,17 +391,35 @@ public final class Network // Ignore } } + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } - if(!fd.finishConnect()) - { - throw new Ice.ConnectFailedException(); - } + try + { + if(!fd.finishConnect()) + { + throw new Ice.ConnectFailedException(); + } + + // + // Prevent self connect (self connect happens on Linux when a client tries to connect to + // a server which was just deactivated if the client socket re-uses the same ephemeral + // port as the server). + // + java.net.SocketAddress addr = fd.socket().getRemoteSocketAddress(); + if(addr != null && addr.equals(fd.socket().getLocalSocketAddress())) + { + throw new Ice.ConnectionRefusedException(); } } catch(java.net.ConnectException ex) { - closeSocketNoThrow(fd); - Ice.ConnectFailedException se; if(connectionRefused(ex)) { @@ -360,7 +434,6 @@ public final class Network } catch(java.io.IOException ex) { - closeSocketNoThrow(fd); Ice.SocketException se = new Ice.SocketException(); se.initCause(ex); throw se; diff --git a/java/src/IceInternal/Outgoing.java b/java/src/IceInternal/Outgoing.java index 85cf0c1ce9b..fd22795c6cf 100644 --- a/java/src/IceInternal/Outgoing.java +++ b/java/src/IceInternal/Outgoing.java @@ -9,19 +9,19 @@ package IceInternal; -public final class Outgoing +public final class Outgoing implements OutgoingMessageCallback { public - Outgoing(Ice.ConnectionI connection, Reference ref, String operation, Ice.OperationMode mode, - java.util.Map context, boolean compress) + Outgoing(RequestHandler handler, String operation, Ice.OperationMode mode, java.util.Map context) throws LocalExceptionWrapper { - _connection = connection; - _reference = ref; _state = StateUnsent; - _is = new BasicStream(ref.getInstance()); - _os = new BasicStream(ref.getInstance()); - _compress = compress; + _sent = false; + _handler = handler; + + Instance instance = _handler.getReference().getInstance(); + _is = new BasicStream(instance); + _os = new BasicStream(instance); writeHeader(operation, mode, context); } @@ -30,13 +30,13 @@ public final class Outgoing // These functions allow this object to be reused, rather than reallocated. // public void - reset(Reference ref, String operation, Ice.OperationMode mode, java.util.Map context, boolean compress) + reset(RequestHandler handler, String operation, Ice.OperationMode mode, java.util.Map context) throws LocalExceptionWrapper { - _reference = ref; _state = StateUnsent; _exception = null; - _compress = compress; + _sent = false; + _handler = handler; writeHeader(operation, mode, context); } @@ -57,41 +57,39 @@ public final class Outgoing _os.endWriteEncaps(); - switch(_reference.getMode()) + switch(_handler.getReference().getMode()) { case Reference.ModeTwoway: { - // - // We let all exceptions raised by sending directly - // propagate to the caller, because they can be - // retried without violating "at-most-once". In case - // of such exceptions, the connection object does not - // call back on this object, so we don't need to lock - // the mutex, keep track of state, or save exceptions. - // - _connection.sendRequest(_os, this, _compress); + _state = StateInProgress; - // - // Wait until the request has completed, or until the - // request times out. - // + Ice.ConnectionI connection = _handler.sendRequest(this); boolean timedOut = false; synchronized(this) { + // - // It's possible that the request has already - // completed, due to a regular response, or because of - // an exception. So we only change the state to "in - // progress" if it is still "unsent". + // If the request is being sent in the background we first wait for the + // sent notification. // - if(_state == StateUnsent) + while(_state != StateFailed && !_sent) { - _state = StateInProgress; + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } } - - int timeout = _connection.timeout(); + + // + // Wait until the request has completed, or until the request + // times out. + // + int timeout = connection.timeout(); while(_state == StateInProgress && !timedOut) { try @@ -99,7 +97,7 @@ public final class Outgoing if(timeout >= 0) { wait(timeout); - + if(_state == StateInProgress) { timedOut = true; @@ -115,15 +113,15 @@ public final class Outgoing } } } - + if(timedOut) { // // Must be called outside the synchronization of // this object // - _connection.exception(new Ice.TimeoutException()); - + connection.exception(new Ice.TimeoutException()); + // // We must wait until the exception set above has // propagated to this Outgoing object. @@ -142,11 +140,11 @@ public final class Outgoing } } } - + if(_exception != null) { _exception.fillInStackTrace(); - + // // A CloseConnectionException indicates graceful // server shutdown, and is therefore always repeatable @@ -158,12 +156,13 @@ public final class Outgoing // An ObjectNotExistException can always be retried as // well without violating "at-most-once". // - if(_exception instanceof Ice.CloseConnectionException || + if(!_sent || + _exception instanceof Ice.CloseConnectionException || _exception instanceof Ice.ObjectNotExistException) { throw _exception; } - + // // Throw the exception wrapped in a LocalExceptionWrapper, to // indicate that the request cannot be resent without @@ -171,30 +170,68 @@ public final class Outgoing // throw new LocalExceptionWrapper(_exception, false); } - + if(_state == StateUserException) { return false; } - - assert(_state == StateOK); - break; + else + { + assert(_state == StateOK); + return true; + } + } case Reference.ModeOneway: case Reference.ModeDatagram: { - // - // For oneway and datagram requests, the connection object - // never calls back on this object. Therefore we don't - // need to lock the mutex or save exceptions. We simply - // let all exceptions from sending propagate to the - // caller, because such exceptions can be retried without - // violating "at-most-once". - // - _state = StateInProgress; - _connection.sendRequest(_os, null, _compress); - break; + try + { + _state = StateInProgress; + if(_handler.sendRequest(this) != null) + { + // + // If the handler returns the connection, we must wait for the sent callback. + // + synchronized(this) + { + while(_state != StateFailed && !_sent) + { + try + { + wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + + if(_exception != null) + { + assert(!_sent); + throw _exception; + } + } + } + return true; + } + catch(Ice.LocalException ex) // Java specfic work-around (see ConnectionI.sendRequest()) + { + if(!_sent) // The send might have failed but the request might still be sent... + { + throw ex; + } + else + { + // + // We wrap the exception into a LocalExceptionWrapper to indicate that + // the request cannot be resent without potentially violating the + // "at-most-once" principle. + // + throw new IceInternal.LocalExceptionWrapper(ex, false); + } + } } case Reference.ModeBatchOneway: @@ -206,12 +243,13 @@ public final class Outgoing // apply. // _state = StateInProgress; - _connection.finishBatchRequest(_os, _compress); - break; + _handler.finishBatchRequest(_os); + return true; } } - - return true; + + assert(false); + return false; } public void @@ -225,10 +263,10 @@ public final class Outgoing // must notify the connection about that we give up ownership // of the batch stream. // - int mode = _reference.getMode(); + int mode = _handler.getReference().getMode(); if(mode == Reference.ModeBatchOneway || mode == Reference.ModeBatchDatagram) { - _connection.abortBatchRequest(); + _handler.abortBatchRequest(); // // If we abort a batch requests, we cannot retry, because @@ -242,10 +280,31 @@ public final class Outgoing throw ex; } + public void + sent(boolean notify) + { + if(notify) + { + synchronized(this) + { + _sent = true; + notify(); + } + } + else + { + // + // No synchronization is necessary if called from sendRequest() because the connection + // send mutex is locked and no other threads can call on Outgoing until it's released. + // + _sent = true; + } + } + public synchronized void finished(BasicStream is) { - assert(_reference.getMode() == Reference.ModeTwoway); // Can only be called for twoways. + assert(_handler.getReference().getMode() == Reference.ModeTwoway); // Only for twoways. assert(_state <= StateInProgress); @@ -390,11 +449,8 @@ public final class Outgoing public synchronized void finished(Ice.LocalException ex) { - assert(_reference.getMode() == Reference.ModeTwoway); // Can only be called for twoways. - assert(_state <= StateInProgress); - - _state = StateLocalException; + _state = StateFailed; _exception = ex; notify(); } @@ -415,7 +471,7 @@ public final class Outgoing writeHeader(String operation, Ice.OperationMode mode, java.util.Map context) throws LocalExceptionWrapper { - switch(_reference.getMode()) + switch(_handler.getReference().getMode()) { case Reference.ModeTwoway: case Reference.ModeOneway: @@ -428,19 +484,19 @@ public final class Outgoing case Reference.ModeBatchOneway: case Reference.ModeBatchDatagram: { - _connection.prepareBatchRequest(_os); + _handler.prepareBatchRequest(_os); break; } } try { - _reference.getIdentity().__write(_os); + _handler.getReference().getIdentity().__write(_os); // // For compatibility with the old FacetPath. // - String facet = _reference.getFacet(); + String facet = _handler.getReference().getFacet(); if(facet == null || facet.length() == 0) { _os.writeStringSeq(null); @@ -467,10 +523,8 @@ public final class Outgoing // // Implicit context // - Ice.ImplicitContextI implicitContext = - _reference.getInstance().getImplicitContext(); - - java.util.Map prxContext = _reference.getContext(); + Ice.ImplicitContextI implicitContext = _handler.getReference().getInstance().getImplicitContext(); + java.util.Map prxContext = _handler.getReference().getContext(); if(implicitContext == null) { @@ -495,8 +549,11 @@ public final class Outgoing } } - private Ice.ConnectionI _connection; - private Reference _reference; + private RequestHandler _handler; + private BasicStream _is; + private BasicStream _os; + private boolean _sent; + private Ice.LocalException _exception; private static final int StateUnsent = 0; @@ -504,12 +561,8 @@ public final class Outgoing private static final int StateOK = 2; private static final int StateUserException = 3; private static final int StateLocalException = 4; + private static final int StateFailed = 5; private int _state; - private BasicStream _is; - private BasicStream _os; - - private boolean _compress; - public Outgoing next; // For use by Ice._ObjectDelM } diff --git a/java/src/IceInternal/OutgoingAsync.java b/java/src/IceInternal/OutgoingAsync.java index 8f49c69ac06..184355e8e06 100644 --- a/java/src/IceInternal/OutgoingAsync.java +++ b/java/src/IceInternal/OutgoingAsync.java @@ -9,7 +9,7 @@ package IceInternal; -public abstract class OutgoingAsync +public abstract class OutgoingAsync implements OutgoingAsyncMessageCallback { public OutgoingAsync() @@ -18,19 +18,75 @@ public abstract class OutgoingAsync public abstract void ice_exception(Ice.LocalException ex); + public final BasicStream + __os() + { + return __os; + } + public final void - __finished(BasicStream is) + __sent(final Ice.ConnectionI connection) { synchronized(_monitor) { - byte replyStatus; - - try + _sent = true; + + if(!_proxy.ice_isTwoway()) + { + cleanup(); // No response expected, we're done with the OutgoingAsync. + } + else if(_response) + { + _monitor.notifyAll(); // If the response was already received notify finished() which is waiting. + } + else if(connection.timeout() >= 0) + { + assert(_timerTask == null); + _timerTask = new TimerTask() + { + public void + runTimerTask() + { + __runTimerTask(connection); + } + }; + _proxy.__reference().getInstance().timer().schedule(_timerTask, connection.timeout()); + } + } + } + + public final void + __finished(BasicStream is) + { + assert(_proxy.ice_isTwoway()); // Can only be called for twoways. + + byte replyStatus; + try + { + synchronized(_monitor) { + assert(__os != null); + _response = true; + + if(_timerTask != null && _proxy.__reference().getInstance().timer().cancel(_timerTask)) + { + _timerTask = null; // Timer cancelled. + } + + while(!_sent || _timerTask != null) + { + try + { + _monitor.wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + __is.swap(is); - replyStatus = __is.readByte(); - + switch(replyStatus) { case ReplyStatus.replyOK: @@ -39,7 +95,7 @@ public abstract class OutgoingAsync __is.startReadEncaps(); break; } - + case ReplyStatus.replyObjectNotExist: case ReplyStatus.replyFacetNotExist: case ReplyStatus.replyOperationNotExist: @@ -145,36 +201,57 @@ public abstract class OutgoingAsync } } } - catch(Ice.LocalException ex) - { - __finished(ex); - return; - } - - assert(replyStatus == ReplyStatus.replyOK || replyStatus == ReplyStatus.replyUserException); + } + catch(Ice.LocalException ex) + { + __finished(ex); + return; + } + + assert(replyStatus == ReplyStatus.replyOK || replyStatus == ReplyStatus.replyUserException); - try - { - __response(replyStatus == ReplyStatus.replyOK); - } - catch(java.lang.Exception ex) - { - warning(ex); - } - finally + try + { + __response(replyStatus == ReplyStatus.replyOK); + } + catch(java.lang.Exception ex) + { + warning(ex); + } + finally + { + synchronized(_monitor) { cleanup(); } } } + public final void __finished(Ice.LocalException exc) { + boolean retry = false; synchronized(_monitor) { - if(__os != null) // Don't retry if cleanup() was already called. + if(__os != null) // Might be called from __prepare or before __prepare { + if(_timerTask != null && _proxy.__reference().getInstance().timer().cancel(_timerTask)) + { + _timerTask = null; // Timer cancelled. + } + + while(_timerTask != null) + { + try + { + _monitor.wait(); + } + catch(java.lang.InterruptedException ex) + { + } + } + // // A CloseConnectionException indicates graceful // server shutdown, and is therefore always repeatable @@ -187,53 +264,85 @@ public abstract class OutgoingAsync // An ObjectNotExistException can always be retried as // well without violating "at-most-once". // - if(_mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent || + if(!_sent || + _mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent || exc instanceof Ice.CloseConnectionException || exc instanceof Ice.ObjectNotExistException) { - try - { - _cnt = ((Ice.ObjectPrxHelperBase)_proxy).__handleException(_delegate, exc, _cnt); - __send(); - return; - } - catch(Ice.LocalException ex) - { - } + retry = true; } } - + } + + if(retry) + { try { - ice_exception(exc); + _cnt = _proxy.__handleException(_delegate, exc, _cnt); + __send(); + return; } - catch(java.lang.Exception ex) + catch(Ice.LocalException ex) { - warning(ex); } - finally + } + + try + { + ice_exception(exc); + } + catch(java.lang.Exception ex) + { + warning(ex); + } + finally + { + synchronized(_monitor) { cleanup(); } } } - public final boolean - __timedOut() + public final void + __finished(LocalExceptionWrapper ex) { // - // No synchronization necessary, because - // _absoluteTimeoutMillis is declared volatile. We cannot - // synchronize here because otherwise there might be deadlocks - // when Ice.ConnectionI calls back on this object with this - // function. + // NOTE: This is called if sendRequest/sendAsyncRequest fails with + // a LocalExceptionWrapper exception. It's not possible for the + // timer to be set at this point because the request couldn't be + // sent. // - if(_absoluteTimeoutMillis > 0) + assert(!_sent && _timerTask == null); + + try { - return IceInternal.Time.currentMonotonicTimeMillis() >= _absoluteTimeoutMillis; + if(_mode == Ice.OperationMode.Nonmutating || _mode == Ice.OperationMode.Idempotent) + { + _cnt = _proxy.__handleExceptionWrapperRelaxed(_delegate, ex, _cnt); + } + else + { + _proxy.__handleExceptionWrapper(_delegate, ex); + } + __send(); } - else + catch(Ice.LocalException exc) { - return false; + try + { + ice_exception(exc); + } + catch(java.lang.Exception exl) + { + warning(exl); + } + finally + { + synchronized(_monitor) + { + cleanup(); + } + } } } @@ -259,23 +368,28 @@ public abstract class OutgoingAsync } // - // Can't call async via a oneway proxy. + // Can't call async via a batch proxy. // - ((Ice.ObjectPrxHelperBase)prx).__checkTwowayOnly(operation); + _proxy = (Ice.ObjectPrxHelperBase)prx; + if(_proxy.ice_isBatchOneway() || _proxy.ice_isBatchDatagram()) + { + throw new Ice.FeatureNotSupportedException("can't send batch requests with AMI"); + } - _proxy = prx; _delegate = null; _cnt = 0; _mode = mode; + _sent = false; + _response = false; - Reference ref = ((Ice.ObjectPrxHelperBase)_proxy).__reference(); + Reference ref = _proxy.__reference(); assert(__is == null); __is = new BasicStream(ref.getInstance()); assert(__os == null); __os = new BasicStream(ref.getInstance()); __os.writeBlob(IceInternal.Protocol.requestHdr); - + ref.getIdentity().__write(__os); // @@ -308,11 +422,9 @@ public abstract class OutgoingAsync // // Implicit context // - Ice.ImplicitContextI implicitContext = - ref.getInstance().getImplicitContext(); - + Ice.ImplicitContextI implicitContext = ref.getInstance().getImplicitContext(); java.util.Map prxContext = ref.getContext(); - + if(implicitContext == null) { Ice.ContextHelper.write(__os, prxContext); @@ -322,7 +434,7 @@ public abstract class OutgoingAsync implicitContext.write(prxContext, __os); } } - + __os.startWriteEncaps(); } catch(Ice.LocalException ex) @@ -336,62 +448,56 @@ public abstract class OutgoingAsync protected final void __send() { + // + // NOTE: no synchronization needed. At this point, no other threads can be calling on this object. + // + + RequestHandler handler; + try + { + _delegate = _proxy.__getDelegate(true); + handler = _delegate.__getRequestHandler(); + } + catch(Ice.LocalException ex) + { + __finished(ex); + return; + } + + _sent = false; + _response = false; + handler.sendAsyncRequest(this); + } + + protected abstract void __response(boolean ok); + + private final void + __runTimerTask(Ice.ConnectionI connection) + { synchronized(_monitor) { - try - { - while(true) - { - Ice.BooleanHolder comp = new Ice.BooleanHolder(); - _delegate = ((Ice.ObjectPrxHelperBase)_proxy).__getDelegate(); - Ice.ConnectionI con = _delegate.__getConnection(comp); - if(con.timeout() >= 0) - { - _absoluteTimeoutMillis = IceInternal.Time.currentMonotonicTimeMillis() + con.timeout(); - } - else - { - _absoluteTimeoutMillis = 0; - } - - try - { - con.sendAsyncRequest(__os, this, comp.value); - - // - // Don't do anything after sendAsyncRequest() returned - // without an exception. I such case, there will be - // callbacks, i.e., calls to the __finished() - // functions. Since there is no mutex protection, we - // cannot modify state here and in such callbacks. - // - return; - } - catch(LocalExceptionWrapper ex) - { - ((Ice.ObjectPrxHelperBase)_proxy).__handleExceptionWrapper(_delegate, ex); - } - catch(Ice.LocalException ex) - { - _cnt = ((Ice.ObjectPrxHelperBase)_proxy).__handleException(_delegate, ex, _cnt); - } - } - } - catch(Ice.LocalException ex) + assert(_timerTask != null && _sent); // Can only be set once the request is sent. + + if(_response) // If the response was just received, don't close the connection. { - __finished(ex); + connection = null; } + _timerTask = null; + _monitor.notifyAll(); } - } - protected abstract void __response(boolean ok); + if(connection != null) + { + connection.exception(new Ice.TimeoutException()); + } + } private final void warning(java.lang.Exception ex) { if(__os != null) // Don't print anything if cleanup() was already called. { - Reference ref = ((Ice.ObjectPrxHelperBase)_proxy).__reference(); + Reference ref = _proxy.__reference(); if(ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault( "Ice.Warn.AMICallback", 1) > 0) { @@ -410,6 +516,8 @@ public abstract class OutgoingAsync private final void cleanup() { + assert(_timerTask == null); + __is = null; __os = null; @@ -419,16 +527,14 @@ public abstract class OutgoingAsync protected BasicStream __is; protected BasicStream __os; - private Ice.ObjectPrx _proxy; + private boolean _sent; + private boolean _response; + private Ice.ObjectPrxHelperBase _proxy; private Ice._ObjectDel _delegate; private int _cnt; private Ice.OperationMode _mode; - // - // Must be volatile, because we don't want to lock the monitor - // below in __timedOut(), to avoid deadlocks. - // - private volatile long _absoluteTimeoutMillis; + private TimerTask _timerTask; private final java.lang.Object _monitor = new java.lang.Object(); } diff --git a/java/src/IceInternal/OutgoingAsyncMessageCallback.java b/java/src/IceInternal/OutgoingAsyncMessageCallback.java new file mode 100644 index 00000000000..2575dd33b38 --- /dev/null +++ b/java/src/IceInternal/OutgoingAsyncMessageCallback.java @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public interface OutgoingAsyncMessageCallback +{ + void __sent(Ice.ConnectionI connection); + void __finished(Ice.LocalException ex); +};
\ No newline at end of file diff --git a/java/src/IceInternal/OutgoingConnectionFactory.java b/java/src/IceInternal/OutgoingConnectionFactory.java index ffec338dd83..fb3108aa472 100644 --- a/java/src/IceInternal/OutgoingConnectionFactory.java +++ b/java/src/IceInternal/OutgoingConnectionFactory.java @@ -11,6 +11,11 @@ package IceInternal; public final class OutgoingConnectionFactory { + interface CreateConnectionCallback + { + void setConnection(Ice.ConnectionI connection, boolean compress); + void setException(Ice.LocalException ex); + } public synchronized void destroy() @@ -40,7 +45,7 @@ public final class OutgoingConnectionFactory public void waitUntilFinished() { - java.util.HashMap connections; + java.util.HashMap connections = null; synchronized(this) { @@ -50,7 +55,7 @@ public final class OutgoingConnectionFactory // anymore. Only then we can be sure the _connections // contains all connections. // - while(!_destroyed || !_pending.isEmpty()) + while(!_destroyed || !_pending.isEmpty() || !_pendingEndpoints.isEmpty()) { try { @@ -65,17 +70,14 @@ public final class OutgoingConnectionFactory // We want to wait until all connections are finished outside the // thread synchronization. // - // For consistency with C#, we set _connections to null rather than to a - // new empty list so that our finalizer does not try to invoke any - // methods on member objects. - // - connections = _connections; - _connections = null; + if(_connections != null) + { + connections = new java.util.HashMap(_connections); + } } // - // Now we wait for until the destruction of each connection is - // finished. + // Now we wait until the destruction of each connection is finished. // java.util.Iterator p = connections.values().iterator(); while(p.hasNext()) @@ -89,257 +91,119 @@ public final class OutgoingConnectionFactory connection.waitUntilFinished(); } } + + synchronized(this) + { + // + // For consistency with C#, we set _connections to null rather than to a + // new empty list so that our finalizer does not try to invoke any + // methods on member objects. + // + _connections = null; + } } public Ice.ConnectionI - create(EndpointI[] endpts, boolean hasMore, boolean threadPerConnection, Ice.EndpointSelectionType selType, + create(EndpointI[] endpts, boolean hasMore, boolean tpc, Ice.EndpointSelectionType selType, Ice.BooleanHolder compress) { - class ConnectorEndpointPair - { - public ConnectorEndpointPair(Connector c, EndpointI e) - { - connector = c; - endpoint = e; - } - - public Connector connector; - public EndpointI endpoint; - } - assert(endpts.length > 0); - java.util.ArrayList connectors = new java.util.ArrayList(); - - DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); - synchronized(this) + // + // TODO: Remove when we no longer support SSL for JDK 1.4. We can also remove + // the threadPerConnection argument. + // + for(int i = 0; i < endpts.length; i++) { - if(_destroyed) + if(!tpc && endpts[i].requiresThreadPerConnection()) { - throw new Ice.CommunicatorDestroyedException(); + Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); + ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].toString(); + throw ex; } + } - // - // TODO: Remove when we no longer support SSL for JDK 1.4. - // - for(int i = 0; i < endpts.length; i++) - { - if(!threadPerConnection && endpts[i].requiresThreadPerConnection()) - { - Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); - ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].toString(); - throw ex; - } - } + // + // Apply the overrides. + // + java.util.List endpoints = applyOverrides(endpts); - // - // Reap connections for which destruction has completed. - // - java.util.Iterator p = _connections.values().iterator(); - while(p.hasNext()) - { - java.util.LinkedList connectionList = (java.util.LinkedList)p.next(); - - java.util.Iterator q = connectionList.iterator(); - while(q.hasNext()) - { - Ice.ConnectionI con = (Ice.ConnectionI)q.next(); - if(con.isFinished()) - { - q.remove(); - } - } + // + // Try to find a connection to one of the given endpoints. + // + Ice.ConnectionI connection = findConnection(endpoints, tpc, compress); + if(connection != null) + { + return connection; + } - if(connectionList.isEmpty()) - { - p.remove(); - } - } + Ice.LocalException exception = null; - EndpointI[] endpoints = new EndpointI[endpts.length]; - System.arraycopy(endpts, 0, endpoints, 0, endpts.length); - for(int i = 0; i < endpoints.length; i++) - { - // - // Modify endpoints with overrides. - // - if(defaultsAndOverrides.overrideTimeout) - { - endpoints[i] = endpoints[i].timeout(defaultsAndOverrides.overrideTimeoutValue); - } + // + // If we didn't find a connection with the endpoints, we create the connectors + // for the endpoints. + // + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = endpoints.iterator(); + while(p.hasNext()) + { + EndpointI endpoint = (EndpointI)p.next(); - // - // Create connectors for the endpoint. - // - java.util.ArrayList cons = endpoints[i].connectors(); + // + // Create connectors for the endpoint. + // + try + { + java.util.List cons = endpoint.connectors(); assert(cons.size() > 0); - + // - // Shuffle connectors is endpoint selection type is Random. + // Shuffle connectors if endpoint selection type is Random. // if(selType == Ice.EndpointSelectionType.Random) { java.util.Collections.shuffle(cons); } - - p = cons.iterator(); - while(p.hasNext()) - { - connectors.add(new ConnectorEndpointPair((Connector)p.next(), endpoints[i])); - } - - } - - // - // Search for existing connections. - // - p = connectors.iterator(); - while(p.hasNext()) - { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - - - java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(cep.connector); - if(connectionList != null) - { - java.util.Iterator q = connectionList.iterator(); - - while(q.hasNext()) - { - Ice.ConnectionI connection = (Ice.ConnectionI)q.next(); - - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!connection.isDestroyed() && connection.threadPerConnection() == threadPerConnection) - { - if(defaultsAndOverrides.overrideCompress) - { - compress.value = defaultsAndOverrides.overrideCompressValue; - } - else - { - compress.value = cep.endpoint.compress(); - } - - return connection; - } - } - } - } - - // - // If some other thread is currently trying to establish a - // connection to any of our endpoints, we wait until this - // thread is finished. - // - boolean searchAgain = false; - while(!_destroyed) - { - boolean found = false; - p = connectors.iterator(); - while(p.hasNext()) - { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - if(_pending.contains(cep.connector)) - { - found = true; - break; - } - } - if(!found) - { - break; - } - - searchAgain = true; - - try - { - wait(); - } - catch(InterruptedException ex) - { - } - } - - if(_destroyed) - { - throw new Ice.CommunicatorDestroyedException(); - } - - // - // Search for existing connections again if we waited - // above, as new connections might have been added in the - // meantime. - // - if(searchAgain) - { - p = connectors.iterator(); - while(p.hasNext()) + java.util.Iterator q = cons.iterator(); + while(q.hasNext()) { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - - java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(cep.connector); - if(connectionList != null) - { - java.util.Iterator q = connectionList.iterator(); - - while(q.hasNext()) - { - Ice.ConnectionI connection = (Ice.ConnectionI)q.next(); - - // - // Don't return connections for which destruction has - // been initiated. The connection must also match the - // requested thread-per-connection setting. - // - if(!connection.isDestroyed() && connection.threadPerConnection() == threadPerConnection) - { - if(defaultsAndOverrides.overrideCompress) - { - compress.value = defaultsAndOverrides.overrideCompressValue; - } - else - { - compress.value = cep.endpoint.compress(); - } - - return connection; - } - } - } + connectors.add(new ConnectorInfo((Connector)q.next(), endpoint, tpc)); } } - - // - // No connection to any of our endpoints exists yet, so we - // will try to create one. To avoid that other threads try - // to create connections to the same endpoints, we add our - // endpoints to _pending. - // - p = connectors.iterator(); - while(p.hasNext()) + catch(Ice.LocalException ex) { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - _pending.add(cep.connector); + exception = ex; + handleException(exception, hasMore || p.hasNext()); } } + + if(connectors.isEmpty()) + { + assert(exception != null); + throw exception; + } + + // + // Try to get a connection to one of the connectors. A null result indicates that no + // connection was found and that we should try to establish the connection (and that + // the connectors were added to _pending to prevent other threads from establishing + // the connection). + // + connection = getConnection(connectors, null, compress); + if(connection != null) + { + return connection; + } - Connector connector = null; - Ice.ConnectionI connection = null; - Ice.LocalException exception = null; - - java.util.Iterator p = connectors.iterator(); + // + // Try to establish the connection to the connectors. + // + DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + p = connectors.iterator(); while(p.hasNext()) { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - connector = cep.connector; - EndpointI endpoint = cep.endpoint; - + ConnectorInfo ci = (ConnectorInfo)p.next(); try { int timeout; @@ -347,21 +211,17 @@ public final class OutgoingConnectionFactory { timeout = defaultsAndOverrides.overrideConnectTimeoutValue; } - // It is not necessary to check for overrideTimeout, - // the endpoint has already been modified with this - // override, if set. else { - timeout = endpoint.timeout(); + // + // It is not necessary to check for overrideTimeout, the endpoint has already + // been modified with this override, if set. + // + timeout = ci.endpoint.timeout(); } - Transceiver transceiver = connector.connect(timeout); - assert(transceiver != null); - - connection = - new Ice.ConnectionI(_instance, transceiver, endpoint.compress(false), null, threadPerConnection); - connection.start(); - connection.validate(); + connection = createConnection(ci.connector.connect(timeout), ci); + connection.start(null); if(defaultsAndOverrides.overrideCompress) { @@ -369,86 +229,79 @@ public final class OutgoingConnectionFactory } else { - compress.value = endpoint.compress(); + compress.value = ci.endpoint.compress(); } + break; } - catch(Ice.LocalException ex) + catch(Ice.CommunicatorDestroyedException ex) { exception = ex; - - // - // If a connection object was constructed, then validate() - // must have raised the exception. - // - if(connection != null) - { - connection.waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - connection = null; - } + handleException(exception, ci, connection, hasMore || p.hasNext()); + connection = null; + break; // No need to continue } - - TraceLevels traceLevels = _instance.traceLevels(); - if(traceLevels.retry >= 2) + catch(Ice.LocalException ex) { - StringBuffer s = new StringBuffer(); - s.append("connection to endpoint failed"); - if(hasMore || p.hasNext()) - { - s.append(", trying next endpoint\n"); - } - else - { - s.append(" and no more endpoints to try\n"); - } - s.append(exception.toString()); - _instance.initializationData().logger.trace(traceLevels.retryCat, s.toString()); + exception = ex; + handleException(exception, ci, connection, hasMore || p.hasNext()); + connection = null; } } - - synchronized(this) + + // + // Finish creating the connection (this removes the connectors from the _pending + // list and notifies any waiting threads). + // + finishGetConnection(connectors, null, connection); + + if(connection == null) { - // - // Signal other threads that we are done with trying to - // establish connections to our endpoints. - // - p = connectors.iterator(); - while(p.hasNext()) - { - ConnectorEndpointPair cep = (ConnectorEndpointPair)p.next(); - _pending.remove(cep.connector); - } - notifyAll(); - - if(connection == null) + assert(exception != null); + throw exception; + } + + return connection; + } + + public void + create(EndpointI[] endpts, boolean hasMore, boolean tpc, Ice.EndpointSelectionType selType, + CreateConnectionCallback callback) + { + assert(endpts.length > 0); + + // + // TODO: Remove when we no longer support SSL for JDK 1.4. We can also remove + // the threadPerConnection argument. + // + for(int i = 0; i < endpts.length; i++) + { + if(!tpc && endpts[i].requiresThreadPerConnection()) { - assert(exception != null); - throw exception; + Ice.FeatureNotSupportedException ex = new Ice.FeatureNotSupportedException(); + ex.unsupportedFeature = "endpoint requires thread-per-connection:\n" + endpts[i].toString(); + throw ex; } - else - { - java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(connector); - if(connectionList == null) - { - connectionList = new java.util.LinkedList(); - _connections.put(connector, connectionList); - } - connectionList.add(connection); + } - if(_destroyed) - { - connection.destroy(Ice.ConnectionI.CommunicatorDestroyed); - throw new Ice.CommunicatorDestroyedException(); - } - else - { - connection.activate(); - } - } + // + // Apply the overrides. + // + java.util.List endpoints = applyOverrides(endpts); + + // + // Try to find a connection to one of the given endpoints. + // + Ice.BooleanHolder compress = new Ice.BooleanHolder(); + Ice.ConnectionI connection = findConnection(endpoints, tpc, compress); + if(connection != null) + { + callback.setConnection(connection, compress.value); + return; } - - assert(connection != null); - return connection; + + ConnectCallback cb = new ConnectCallback(this, endpoints, hasMore, callback, selType, tpc); + cb.getConnection(); } public synchronized void @@ -607,8 +460,740 @@ public final class OutgoingConnectionFactory super.finalize(); } + private java.util.List + applyOverrides(EndpointI[] endpts) + { + DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + java.util.ArrayList endpoints = new java.util.ArrayList(); + for(int i = 0; i < endpts.length; i++) + { + // + // Modify endpoints with overrides. + // + if(defaultsAndOverrides.overrideTimeout) + { + endpoints.add(endpts[i].timeout(defaultsAndOverrides.overrideTimeoutValue)); + } + else + { + endpoints.add(endpts[i]); + } + } + + return endpoints; + } + + synchronized private Ice.ConnectionI + findConnection(java.util.List endpoints, boolean tpc, Ice.BooleanHolder compress) + { + DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + assert(!endpoints.isEmpty()); + + java.util.Iterator p = endpoints.iterator(); + while(p.hasNext()) + { + EndpointI endpoint = (EndpointI)p.next(); + java.util.LinkedList connectionList = (java.util.LinkedList)_connectionsByEndpoint.get(endpoint); + if(connectionList == null) + { + continue; + } + + java.util.Iterator q = connectionList.iterator(); + while(q.hasNext()) + { + Ice.ConnectionI connection = (Ice.ConnectionI)q.next(); + if(connection.isActiveOrHolding() && + connection.threadPerConnection() == tpc) // Don't return destroyed or un-validated connections + { + if(defaultsAndOverrides.overrideCompress) + { + compress.value = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress.value = endpoint.compress(); + } + return connection; + } + } + } + + return null; + } + + // + // Must be called while synchronized. + // + private Ice.ConnectionI + findConnection(java.util.List connectors, Ice.BooleanHolder compress) + { + DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides(); + java.util.Iterator p = connectors.iterator(); + while(p.hasNext()) + { + ConnectorInfo ci = (ConnectorInfo)p.next(); + java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(ci); + if(connectionList == null) + { + continue; + } + + java.util.Iterator q = connectionList.iterator(); + while(q.hasNext()) + { + Ice.ConnectionI connection = (Ice.ConnectionI)q.next(); + if(connection.isActiveOrHolding()) // Don't return destroyed or un-validated connections + { + if(connection.endpoint().equals(ci.endpoint)) + { + java.util.List conList = (java.util.LinkedList)_connectionsByEndpoint.get(ci.endpoint); + if(conList == null) + { + conList = new java.util.LinkedList(); + _connectionsByEndpoint.put(ci.endpoint, conList); + } + conList.add(connection); + } + + if(defaultsAndOverrides.overrideCompress) + { + compress.value = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress.value = ci.endpoint.compress(); + } + return connection; + } + } + } + + return null; + } + + synchronized private void + addPendingEndpoints(java.util.List endpoints) + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + _pendingEndpoints.addAll(endpoints); + } + + synchronized private void + removePendingEndpoints(java.util.List endpoints) + { + java.util.Iterator p = endpoints.iterator(); + while(p.hasNext()) + { + _pendingEndpoints.remove(p.next()); + } + + if(_destroyed) + { + notifyAll(); + } + } + + private Ice.ConnectionI + getConnection(java.util.List connectors, ConnectCallback cb, Ice.BooleanHolder compress) + { + synchronized(this) + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + // + // Reap connections for which destruction has completed. + // + java.util.Iterator p = _connections.values().iterator(); + while(p.hasNext()) + { + java.util.LinkedList connectionList = (java.util.LinkedList)p.next(); + java.util.Iterator q = connectionList.iterator(); + while(q.hasNext()) + { + Ice.ConnectionI con = (Ice.ConnectionI)q.next(); + if(con.isFinished()) + { + q.remove(); + } + } + + if(connectionList.isEmpty()) + { + p.remove(); + } + } + + p = _connectionsByEndpoint.values().iterator(); + while(p.hasNext()) + { + java.util.LinkedList connectionList = (java.util.LinkedList)p.next(); + java.util.Iterator q = connectionList.iterator(); + while(q.hasNext()) + { + Ice.ConnectionI con = (Ice.ConnectionI)q.next(); + if(con.isFinished()) + { + q.remove(); + } + } + + if(connectionList.isEmpty()) + { + p.remove(); + } + } + + // + // Try to get the connection. We may need to wait for other threads to + // finish if one of them is currently establishing a connection to one + // of our connectors. + // + while(!_destroyed) + { + // + // Search for a matching connection. If we find one, we're done. + // + Ice.ConnectionI connection = findConnection(connectors, compress); + if(connection != null) + { + if(cb != null) + { + // + // This might not be the first getConnection call for the callback. We need + // to ensure that the callback isn't registered with any other pending + // connectors since we just found a connection and therefore don't need to + // wait anymore for other pending connectors. + // + p = connectors.iterator(); + while(p.hasNext()) + { + java.util.Set cbs = (java.util.Set)_pending.get(p.next()); + if(cbs != null) + { + cbs.remove(cb); + } + } + } + return connection; + } + + // + // Determine whether another thread is currently attempting to connect to one of our endpoints; + // if so we wait until it's done. + // + p = connectors.iterator(); + boolean found = false; + while(p.hasNext()) + { + java.util.Set cbs = (java.util.Set)_pending.get(p.next()); + if(cbs != null) + { + found = true; + if(cb != null) + { + cbs.add(cb); // Add the callback to each pending connector. + } + } + } + + if(!found) + { + // + // If no thread is currently establishing a connection to one of our connectors, + // we get out of this loop and start the connection establishment to one of the + // given connectors. + // + break; + } + else + { + // + // If a callback is not specified we wait until another thread notifies us about a + // change to the pending list. Otherwise, if a callback is provided we're done: + // when the pending list changes the callback will be notified and will try to + // get the connection again. + // + if(cb == null) + { + try + { + wait(); + } + catch(InterruptedException ex) + { + } + } + else + { + return null; + } + } + } + + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + // + // No connection to any of our endpoints exists yet; we add the given connectors to + // the _pending set to indicate that we're attempting connection establishment to + // these connectors. + // + p = connectors.iterator(); + while(p.hasNext()) + { + _pending.put(p.next(), new java.util.HashSet()); + } + } + + // + // At this point, we're responsible for establishing the connection to one of + // the given connectors. If it's a non-blocking connect, calling nextConnector + // will start the connection establishment. Otherwise, we return null to get + // the caller to establish the connection. + // + if(cb != null) + { + cb.nextConnector(); + } + + return null; + } + + private synchronized Ice.ConnectionI + createConnection(Transceiver transceiver, ConnectorInfo ci) + { + assert(_pending.containsKey(ci) && transceiver != null); + + // + // Create and add the connection to the connection map. Adding the connection to the map + // is necessary to support the interruption of the connection initialization and validation + // in case the communicator is destroyed. + // + try + { + if(_destroyed) + { + throw new Ice.CommunicatorDestroyedException(); + } + + Ice.ConnectionI connection = new Ice.ConnectionI(_instance, transceiver, ci.endpoint.compress(false), + null, ci.threadPerConnection); + + java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(ci); + if(connectionList == null) + { + connectionList = new java.util.LinkedList(); + _connections.put(ci, connectionList); + } + connectionList.add(connection); + return connection; + } + catch(Ice.LocalException ex) + { + try + { + transceiver.close(); + } + catch(Ice.LocalException exc) + { + // Ignore + } + throw ex; + } + } + + private void + finishGetConnection(java.util.List connectors, ConnectCallback cb, Ice.ConnectionI connection) + { + java.util.ArrayList callbacks = new java.util.ArrayList(); + + synchronized(this) + { + // + // We're done trying to connect to the given connectors so we remove the + // connectors from the pending list and notify waiting threads. We also + // notify the pending connect callbacks (outside the synchronization). + // + + java.util.Iterator p = connectors.iterator(); + while(p.hasNext()) + { + callbacks.addAll((java.util.Set)_pending.remove(p.next())); + } + notifyAll(); + + // + // If the connect attempt succeeded and the communicator is not destroyed, + // activate the connection! + // + if(connection != null && !_destroyed) + { + connection.activate(); + } + } + + // + // Notify any waiting callbacks. + // + java.util.Iterator p = callbacks.iterator(); + while(p.hasNext()) + { + ((ConnectCallback)p.next()).getConnection(); + } + } + + private void + handleException(Ice.LocalException ex, ConnectorInfo ci, Ice.ConnectionI connection, boolean hasMore) + { + TraceLevels traceLevels = _instance.traceLevels(); + if(traceLevels.retry >= 2) + { + StringBuffer s = new StringBuffer(); + s.append("connection to endpoint failed"); + if(ex instanceof Ice.CommunicatorDestroyedException) + { + s.append("\n"); + } + else + { + if(hasMore) + { + s.append(", trying next endpoint\n"); + } + else + { + s.append(" and no more endpoints to try\n"); + } + } + s.append(ex.toString()); + _instance.initializationData().logger.trace(traceLevels.retryCat, s.toString()); + } + + if(connection != null && connection.isFinished()) + { + // + // If the connection is finished, we remove it right away instead of + // waiting for the reaping. + // + // NOTE: it's possible for the connection to not be finished yet. That's + // for instance the case when using thread per connection and if it's the + // thread which is calling back the outgoing connection factory to notify + // it of the failure. + // + synchronized(this) + { + java.util.LinkedList connectionList = (java.util.LinkedList)_connections.get(ci); + if(connectionList != null) // It might have already been reaped! + { + connectionList.remove(connection); + if(connectionList.isEmpty()) + { + _connections.remove(ci); + } + } + } + } + } + + private void + handleException(Ice.LocalException ex, boolean hasMore) + { + TraceLevels traceLevels = _instance.traceLevels(); + if(traceLevels.retry >= 2) + { + StringBuffer s = new StringBuffer(); + s.append("couldn't resolve endpoint host"); + if(ex instanceof Ice.CommunicatorDestroyedException) + { + s.append("\n"); + } + else + { + if(hasMore) + { + s.append(", trying next endpoint\n"); + } + else + { + s.append(" and no more endpoints to try\n"); + } + } + s.append(ex.toString()); + _instance.initializationData().logger.trace(traceLevels.retryCat, s.toString()); + } + } + + private static class ConnectorInfo + { + public ConnectorInfo(Connector c, EndpointI e, boolean t) + { + connector = c; + endpoint = e; + threadPerConnection = t; + } + + public boolean + equals(Object obj) + { + ConnectorInfo r = (ConnectorInfo)obj; + if(threadPerConnection != r.threadPerConnection) + { + return false; + } + return connector.equals(r.connector); + } + + public int + hashCode() + { + return 2 * connector.hashCode() + (threadPerConnection ? 0 : 1); + } + + public Connector connector; + public EndpointI endpoint; + public boolean threadPerConnection; + } + + private static class ConnectCallback implements Ice.ConnectionI.StartCallback, EndpointI_connectors, + ThreadPoolWorkItem + { + ConnectCallback(OutgoingConnectionFactory f, java.util.List endpoints, boolean more, + CreateConnectionCallback cb, Ice.EndpointSelectionType selType, boolean threadPerConnection) + { + _factory = f; + _endpoints = endpoints; + _hasMore = more; + _callback = cb; + _selType = selType; + _threadPerConnection = threadPerConnection; + _endpointsIter = _endpoints.iterator(); + } + + // + // Methods from ConnectionI.StartCallback + // + public synchronized void + connectionStartCompleted(Ice.ConnectionI connection) + { + assert(_exception == null && connection == _connection); + + boolean compress; + DefaultsAndOverrides defaultsAndOverrides = _factory._instance.defaultsAndOverrides(); + if(defaultsAndOverrides.overrideCompress) + { + compress = defaultsAndOverrides.overrideCompressValue; + } + else + { + compress = _current.endpoint.compress(); + } + + _factory.finishGetConnection(_connectors, this, connection); + _factory.removePendingEndpoints(_endpoints); + _callback.setConnection(connection, compress); + } + + public synchronized void + connectionStartFailed(Ice.ConnectionI connection, Ice.LocalException ex) + { + assert(_exception == null && connection == _connection); + + _exception = ex; + handleException(); + } + + // + // Methods from EndpointI_connectors + // + public void + connectors(java.util.List cons) + { + // + // Shuffle connectors if endpoint selection type is Random. + // + if(_selType == Ice.EndpointSelectionType.Random) + { + java.util.Collections.shuffle(cons); + } + + java.util.Iterator q = cons.iterator(); + while(q.hasNext()) + { + _connectors.add(new ConnectorInfo((Connector)q.next(), _currentEndpoint, _threadPerConnection)); + } + + if(_endpointsIter.hasNext()) + { + _currentEndpoint = (EndpointI)_endpointsIter.next(); + _currentEndpoint.connectors_async(this); + } + else + { + assert(!_connectors.isEmpty()); + + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.iterator(); + getConnection(); + } + } + + public void + exception(Ice.LocalException ex) + { + _factory.handleException(ex, _hasMore || _endpointsIter.hasNext()); + if(_endpointsIter.hasNext()) + { + _currentEndpoint = (EndpointI)_endpointsIter.next(); + _currentEndpoint.connectors_async(this); + } + else if(!_connectors.isEmpty()) + { + // + // We now have all the connectors for the given endpoints. We can try to obtain the + // connection. + // + _iter = _connectors.iterator(); + getConnection(); + } + else + { + _exception = ex; + _factory._instance.clientThreadPool().execute(this); + } + } + + // + // Methods from ThreadPoolWorkItem + // + public void + execute(ThreadPool threadPool) + { + threadPool.promoteFollower(); + assert(_exception != null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + + void + getConnection() + { + // + // First, get the connectors for all the endpoints. + // + if(_endpointsIter.hasNext()) + { + try + { + _factory.addPendingEndpoints(_endpoints); + _currentEndpoint = (EndpointI)_endpointsIter.next(); + _currentEndpoint.connectors_async(this); + } + catch(Ice.LocalException ex) + { + _callback.setException(ex); + } + return; + } + + try + { + Ice.BooleanHolder compress = new Ice.BooleanHolder(); + Ice.ConnectionI connection = _factory.getConnection(_connectors, this, compress); + if(connection == null) + { + // + // A null return value from getConnection indicates that the connection + // is being established and that everthing has been done to ensure that + // the callback will be notified when the connection establishment is + // done. + // + return; + } + + _factory.removePendingEndpoints(_endpoints); + _callback.setConnection(connection, compress.value); + } + catch(Ice.LocalException ex) + { + _exception = ex; + _factory._instance.clientThreadPool().execute(this); + } + } + + void + nextConnector() + { + _current = (ConnectorInfo)_iter.next(); + try + { + _exception = null; + _connection = _factory.createConnection(_current.connector.connect(0), _current); + _connection.start(this); + } + catch(Ice.LocalException ex) + { + _exception = ex; + handleException(); + } + } + + private void + handleException() + { + assert(_current != null && _exception != null); + + _factory.handleException(_exception, _current, _connection, _hasMore || _iter.hasNext()); + if(_exception instanceof Ice.CommunicatorDestroyedException) // No need to continue. + { + _factory.finishGetConnection(_connectors, this, null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + else if(_iter.hasNext()) // Try the next connector. + { + nextConnector(); + } + else + { + _factory.finishGetConnection(_connectors, this, null); + _factory.removePendingEndpoints(_endpoints); + _callback.setException(_exception); + } + } + + private final OutgoingConnectionFactory _factory; + private final boolean _hasMore; + private final CreateConnectionCallback _callback; + private final java.util.List _endpoints; + private final Ice.EndpointSelectionType _selType; + private final boolean _threadPerConnection; + private java.util.Iterator _endpointsIter; + private EndpointI _currentEndpoint; + private java.util.List _connectors = new java.util.ArrayList(); + private java.util.Iterator _iter; + private ConnectorInfo _current; + private Ice.LocalException _exception; + private Ice.ConnectionI _connection; + } + private final Instance _instance; private boolean _destroyed; + private java.util.HashMap _connections = new java.util.HashMap(); - private java.util.HashSet _pending = new java.util.HashSet(); + private java.util.HashMap _pending = new java.util.HashMap(); + + private java.util.HashMap _connectionsByEndpoint = new java.util.HashMap(); + private java.util.LinkedList _pendingEndpoints = new java.util.LinkedList(); } diff --git a/java/src/IceInternal/OutgoingMessageCallback.java b/java/src/IceInternal/OutgoingMessageCallback.java new file mode 100644 index 00000000000..53c7a744c12 --- /dev/null +++ b/java/src/IceInternal/OutgoingMessageCallback.java @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public interface OutgoingMessageCallback +{ + void sent(boolean notify); + void finished(Ice.LocalException ex); +} diff --git a/java/src/IceInternal/PropertyNames.java b/java/src/IceInternal/PropertyNames.java index 1f9fc892260..49e5b9e5673 100644 --- a/java/src/IceInternal/PropertyNames.java +++ b/java/src/IceInternal/PropertyNames.java @@ -7,7 +7,7 @@ // // ********************************************************************** // -// Generated by makeprops.py from file ../config/PropertyNames.xml, Thu Nov 22 20:40:28 2007 +// Generated by makeprops.py from file ../config/PropertyNames.xml, Mon Nov 26 11:29:02 2007 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/java/src/IceInternal/ProtocolPluginFacade.java b/java/src/IceInternal/ProtocolPluginFacade.java index 52b92d5f57d..8423491d10f 100644 --- a/java/src/IceInternal/ProtocolPluginFacade.java +++ b/java/src/IceInternal/ProtocolPluginFacade.java @@ -18,6 +18,11 @@ public interface ProtocolPluginFacade Ice.Communicator getCommunicator(); // + // Get the endpoint host resolver. + // + IceInternal.EndpointHostResolver getEndpointHostResolver(); + + // // Get the default hostname to be used in endpoints. // String getDefaultHost(); @@ -32,4 +37,9 @@ public interface ProtocolPluginFacade // Register an EndpointFactory. // void addEndpointFactory(EndpointFactory factory); + + // + // Get an EndpointFactory. + // + EndpointFactory getEndpointFactory(short type); } diff --git a/java/src/IceInternal/ProtocolPluginFacadeI.java b/java/src/IceInternal/ProtocolPluginFacadeI.java index 53ae82a59d1..1dacd623499 100644 --- a/java/src/IceInternal/ProtocolPluginFacadeI.java +++ b/java/src/IceInternal/ProtocolPluginFacadeI.java @@ -29,6 +29,15 @@ public class ProtocolPluginFacadeI implements ProtocolPluginFacade } // + // Get the endpoint host resolver. + // + public EndpointHostResolver + getEndpointHostResolver() + { + return _instance.endpointHostResolver(); + } + + // // Get the default hostname to be used in endpoints. // public String @@ -61,6 +70,15 @@ public class ProtocolPluginFacadeI implements ProtocolPluginFacade _instance.endpointFactoryManager().add(factory); } + // + // Register an EndpointFactory. + // + public EndpointFactory + getEndpointFactory(short type) + { + return _instance.endpointFactoryManager().get(type); + } + private Instance _instance; private Ice.Communicator _communicator; } diff --git a/java/src/IceInternal/Reference.java b/java/src/IceInternal/Reference.java index 59ccbee7bec..5d486b41af3 100644 --- a/java/src/IceInternal/Reference.java +++ b/java/src/IceInternal/Reference.java @@ -18,6 +18,12 @@ public abstract class Reference implements Cloneable public final static int ModeBatchDatagram = 4; public final static int ModeLast = ModeBatchDatagram; + public interface GetConnectionCallback + { + void setConnection(Ice.ConnectionI connection, boolean compress); + void setException(Ice.LocalException ex); + } + public final int getMode() { @@ -325,6 +331,7 @@ public abstract class Reference implements Cloneable } public abstract Ice.ConnectionI getConnection(Ice.BooleanHolder comp); + public abstract void getConnection(GetConnectionCallback callback); public boolean equals(java.lang.Object obj) diff --git a/java/src/IceInternal/ReferenceFactory.java b/java/src/IceInternal/ReferenceFactory.java index 784c45c4aa3..37f24e64c56 100644 --- a/java/src/IceInternal/ReferenceFactory.java +++ b/java/src/IceInternal/ReferenceFactory.java @@ -100,7 +100,7 @@ public final class ReferenceFactory // // Create new reference // - FixedReference ref = new FixedReference(_instance, _communicator, ident, context, facet, mode, + FixedReference ref = new FixedReference(_instance, _communicator, ident, context, facet, mode, fixedConnections); return updateCache(ref); } diff --git a/java/src/IceInternal/RequestHandler.java b/java/src/IceInternal/RequestHandler.java new file mode 100644 index 00000000000..49df9e6bc8d --- /dev/null +++ b/java/src/IceInternal/RequestHandler.java @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public interface RequestHandler +{ + void prepareBatchRequest(BasicStream out); + void finishBatchRequest(BasicStream out); + void abortBatchRequest(); + + Ice.ConnectionI sendRequest(Outgoing out) + throws LocalExceptionWrapper; + + void sendAsyncRequest(OutgoingAsync out); + + boolean flushBatchRequests(BatchOutgoing out); + void flushAsyncBatchRequests(BatchOutgoingAsync out); + + Reference getReference(); + + Ice.ConnectionI getConnection(boolean wait); + + Outgoing getOutgoing(String operation, Ice.OperationMode mode, java.util.Map context) + throws LocalExceptionWrapper; + + void reclaimOutgoing(Outgoing out); +} diff --git a/java/src/IceInternal/RoutableReference.java b/java/src/IceInternal/RoutableReference.java index f04c30eb86c..213453b71cd 100644 --- a/java/src/IceInternal/RoutableReference.java +++ b/java/src/IceInternal/RoutableReference.java @@ -17,20 +17,6 @@ public abstract class RoutableReference extends Reference return _routerInfo; } - public final EndpointI[] - getRoutedEndpoints() - { - if(_routerInfo != null) - { - // - // If we route, we send everything to the router's client - // proxy endpoints. - // - return _routerInfo.getClientEndpoints(); - } - return new EndpointI[0]; - } - public final boolean getSecure() { @@ -252,6 +238,7 @@ public abstract class RoutableReference extends Reference { return false; } + return _routerInfo == null ? rhs._routerInfo == null : _routerInfo.equals(rhs._routerInfo); } @@ -304,8 +291,8 @@ public abstract class RoutableReference extends Reference } } - protected Ice.ConnectionI - createConnection(EndpointI[] allEndpoints, Ice.BooleanHolder compress) + private EndpointI[] + filterEndpoints(EndpointI[] allEndpoints) { java.util.ArrayList endpoints = new java.util.ArrayList(); @@ -413,25 +400,30 @@ public abstract class RoutableReference extends Reference java.util.Collections.sort(endpoints, _preferNonSecureEndpointComparator); } - if(endpoints.size() == 0) + return (EndpointI[])endpoints.toArray(new EndpointI[endpoints.size()]); + } + + protected Ice.ConnectionI + createConnection(EndpointI[] allEndpoints, Ice.BooleanHolder compress) + { + EndpointI[] endpoints = filterEndpoints(allEndpoints); + if(endpoints.length == 0) { - Ice.NoEndpointException ex = new Ice.NoEndpointException(); - ex.proxy = toString(); - throw ex; + throw new Ice.NoEndpointException(toString()); } // // Finally, create the connection. // OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory(); - if(getCacheConnection() || endpoints.size() == 1) + Ice.ConnectionI connection = null; + if(getCacheConnection() || endpoints.length == 1) { // // Get an existing connection or create one if there's no // existing connection to one of the given endpoints. // - return factory.create((EndpointI[])endpoints.toArray( - new EndpointI[endpoints.size()]), false, _threadPerConnection, getEndpointSelection(), compress); + connection = factory.create(endpoints, false, _threadPerConnection, getEndpointSelection(), compress); } else { @@ -444,16 +436,16 @@ public abstract class RoutableReference extends Reference // Ice.LocalException exception = null; - EndpointI[] endpoint = new EndpointI[1]; - - java.util.Iterator i = endpoints.iterator(); - while(i.hasNext()) + EndpointI[] endpoint = new EndpointI[1]; + for(int i = 0; i < endpoints.length; ++i) { try { - endpoint[0] = (EndpointI)i.next(); - return factory.create(endpoint, i.hasNext(), _threadPerConnection, getEndpointSelection(), - compress); + endpoint[0] = endpoints[i]; + final boolean more = i != endpoints.length - 1; + connection = factory.create(endpoint, more, _threadPerConnection, getEndpointSelection(), + compress); + break; } catch(Ice.LocalException ex) { @@ -461,8 +453,123 @@ public abstract class RoutableReference extends Reference } } - assert(exception != null); - throw exception; + if(connection == null) + { + assert(exception != null); + throw exception; + } + } + + assert(connection != null); + + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo != null) + { + connection.setAdapter(_routerInfo.getAdapter()); + } + + return connection; + } + + protected void + createConnection(EndpointI[] allEndpoints, final GetConnectionCallback callback) + { + final EndpointI[] endpoints = filterEndpoints(allEndpoints); + if(endpoints.length == 0) + { + callback.setException(new Ice.NoEndpointException(toString())); + return; + } + + // + // Finally, create the connection. + // + final OutgoingConnectionFactory factory = getInstance().outgoingConnectionFactory(); + if(getCacheConnection() || endpoints.length == 1) + { + // + // Get an existing connection or create one if there's no + // existing connection to one of the given endpoints. + // + factory.create(endpoints, false, _threadPerConnection, getEndpointSelection(), + new OutgoingConnectionFactory.CreateConnectionCallback() + { + public void + setConnection(Ice.ConnectionI connection, boolean compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo != null) + { + connection.setAdapter(_routerInfo.getAdapter()); + } + callback.setConnection(connection, compress); + } + + public void + setException(Ice.LocalException ex) + { + callback.setException(ex); + } + }); + } + else + { + // + // Go through the list of endpoints and try to create the + // connection until it succeeds. This is different from just + // calling create() with the given endpoints since this might + // create a new connection even if there's an existing + // connection for one of the endpoints. + // + + factory.create(new EndpointI[]{ endpoints[0] }, true, _threadPerConnection, getEndpointSelection(), + new OutgoingConnectionFactory.CreateConnectionCallback() + { + public void + setConnection(Ice.ConnectionI connection, boolean compress) + { + // + // If we have a router, set the object adapter for this router + // (if any) to the new connection, so that callbacks from the + // router can be received over this new connection. + // + if(_routerInfo != null) + { + connection.setAdapter(_routerInfo.getAdapter()); + } + callback.setConnection(connection, compress); + } + + public void + setException(final Ice.LocalException ex) + { + if(_exception == null) + { + _exception = ex; + } + + if(++_i == endpoints.length) + { + callback.setException(_exception); + return; + } + + final boolean more = _i != endpoints.length - 1; + final EndpointI[] endpoint = new EndpointI[]{ endpoints[_i] }; + factory.create(endpoint, more, _threadPerConnection, getEndpointSelection(), this); + } + + private int _i = 0; + private Ice.LocalException _exception = null; + }); } } diff --git a/java/src/IceInternal/RouterInfo.java b/java/src/IceInternal/RouterInfo.java index d9e6c6f6839..cf4180a7a0f 100644 --- a/java/src/IceInternal/RouterInfo.java +++ b/java/src/IceInternal/RouterInfo.java @@ -11,6 +11,18 @@ package IceInternal; public final class RouterInfo { + interface GetClientEndpointsCallback + { + void setEndpoints(EndpointI[] endpoints); + void setException(Ice.LocalException ex); + } + + interface AddProxyCallback + { + void addedProxy(); + void setException(Ice.LocalException ex); + } + RouterInfo(Ice.RouterPrx router) { _router = router; @@ -52,12 +64,136 @@ public final class RouterInfo return _router; } - public synchronized EndpointI[] + public EndpointI[] getClientEndpoints() { - if(_clientEndpoints == null) // Lazy initialization. + synchronized(this) + { + if(_clientEndpoints != null) // Lazy initialization. + { + return _clientEndpoints; + } + } + + return setClientEndpoints(_router.getClientProxy()); + } + + public void + getClientEndpoints(final GetClientEndpointsCallback callback) + { + EndpointI[] clientEndpoints = null; + synchronized(this) + { + clientEndpoints = _clientEndpoints; + } + + if(clientEndpoints != null) + { + callback.setEndpoints(clientEndpoints); + return; + } + + final RouterInfo self = this; + _router.getClientProxy_async(new Ice.AMI_Router_getClientProxy() + { + public void + ice_response(Ice.ObjectPrx clientProxy) + { + callback.setEndpoints(setClientEndpoints(clientProxy)); + } + + public void + ice_exception(Ice.LocalException ex) + { + callback.setException(ex); + } + }); + } + + public EndpointI[] + getServerEndpoints() + { + synchronized(this) + { + if(_serverEndpoints != null) // Lazy initialization. + { + return _serverEndpoints; + } + } + + return setServerEndpoints(_router.getServerProxy()); + } + + public void + addProxy(Ice.ObjectPrx proxy) + { + assert(proxy != null); + synchronized(this) + { + if(_identities.contains(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return; + } + } + + addAndEvictProxies(proxy, _router.addProxies(new Ice.ObjectPrx[] { proxy })); + } + + public boolean + addProxy(final Ice.ObjectPrx proxy, final AddProxyCallback callback) + { + assert(proxy != null); + synchronized(this) + { + if(_identities.contains(proxy.ice_getIdentity())) + { + // + // Only add the proxy to the router if it's not already in our local map. + // + return true; + } + } + + _router.addProxies_async(new Ice.AMI_Router_addProxies() + { + public void + ice_response(Ice.ObjectPrx[] evictedProxies) + { + addAndEvictProxies(proxy, evictedProxies); + callback.addedProxy(); + } + + public void + ice_exception(Ice.LocalException ex) + { + callback.setException(ex); + } + }, + new Ice.ObjectPrx[] { proxy }); + + return false; + } + + public synchronized void + setAdapter(Ice.ObjectAdapter adapter) + { + _adapter = adapter; + } + + public synchronized Ice.ObjectAdapter + getAdapter() + { + return _adapter; + } + + private synchronized EndpointI[] + setClientEndpoints(Ice.ObjectPrx clientProxy) + { + if(_clientEndpoints == null) { - Ice.ObjectPrx clientProxy = _router.getClientProxy(); if(clientProxy == null) { // @@ -82,76 +218,69 @@ public final class RouterInfo { // Ignore - collocated router. } - + _clientEndpoints = ((Ice.ObjectPrxHelperBase)clientProxy).__reference().getEndpoints(); } } - return _clientEndpoints; } - public synchronized EndpointI[] - getServerEndpoints() + private synchronized EndpointI[] + setServerEndpoints(Ice.ObjectPrx serverProxy) { - if(_serverEndpoints == null) // Lazy initialization. + if(serverProxy == null) { - Ice.ObjectPrx serverProxy = _router.getServerProxy(); - if(serverProxy == null) - { - throw new Ice.NoEndpointException(); - } - - serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed. - _serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy).__reference().getEndpoints(); + throw new Ice.NoEndpointException(); } - + + serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed. + _serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy).__reference().getEndpoints(); return _serverEndpoints; } - public synchronized void - addProxy(Ice.ObjectPrx proxy) + private synchronized void + addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies) { - assert(proxy != null); - - if(!_identities.contains(proxy.ice_getIdentity())) + // + // Check if the proxy hasn't already been evicted by a + // concurrent addProxies call. If it's the case, don't + // add it to our local map. + // + int index = _evictedIdentities.indexOf(proxy.ice_getIdentity()); + if(index >= 0) + { + _evictedIdentities.remove(index); + } + else { // - // Only add the proxy to the router if it's not already in our local map. - // - Ice.ObjectPrx[] proxies = new Ice.ObjectPrx[1]; - proxies[0] = proxy; - Ice.ObjectPrx[] evictedProxies = _router.addProxies(proxies); - - // - // If we successfully added the proxy to the router, we add it to our local map. + // If we successfully added the proxy to the router, + // we add it to our local map. // _identities.add(proxy.ice_getIdentity()); + } - // - // We also must remove whatever proxies the router evicted. - // - for(int i = 0; i < evictedProxies.length; ++i) + // + // We also must remove whatever proxies the router evicted. + // + for(int i = 0; i < evictedProxies.length; ++i) + { + if(!_identities.remove(evictedProxies[i].ice_getIdentity())) { - _identities.remove(evictedProxies[i].ice_getIdentity()); + // + // It's possible for the proxy to not have been + // added yet in the local map if two threads + // concurrently call addProxies. + // + _evictedIdentities.add(evictedProxies[i].ice_getIdentity()); } } } - public synchronized void - setAdapter(Ice.ObjectAdapter adapter) - { - _adapter = adapter; - } - - public synchronized Ice.ObjectAdapter - getAdapter() - { - return _adapter; - } - private final Ice.RouterPrx _router; private EndpointI[] _clientEndpoints; private EndpointI[] _serverEndpoints; private Ice.ObjectAdapter _adapter; private java.util.HashSet _identities = new java.util.HashSet(); + private java.util.List _evictedIdentities = new java.util.ArrayList(); } diff --git a/java/src/IceInternal/RouterManager.java b/java/src/IceInternal/RouterManager.java index a34091fd479..9aad2116754 100644 --- a/java/src/IceInternal/RouterManager.java +++ b/java/src/IceInternal/RouterManager.java @@ -39,7 +39,10 @@ public final class RouterManager return null; } - Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); // The router cannot be routed. + // + // The router cannot be routed. + // + Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(rtr.ice_router(null)); synchronized(this) { diff --git a/java/src/IceInternal/SelectorThread.java b/java/src/IceInternal/SelectorThread.java new file mode 100644 index 00000000000..6a291e36926 --- /dev/null +++ b/java/src/IceInternal/SelectorThread.java @@ -0,0 +1,511 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public class SelectorThread +{ + public interface SocketReadyCallback + { + // + // The selector thread unregisters the callback when socketReady returns SocketStatus.Finished. + // + SocketStatus socketReady(boolean finished); + + // + // The selector thread doesn't unregister the callback when sockectTimeout is called; socketTimeout + // must unregister the callback either explicitly with unregister() or by shutting down the socket + // (if necessary). + // + void socketTimeout(); + } + + SelectorThread(Instance instance) + { + _instance = instance; + _destroyed = false; + + Network.SocketPair pair = Network.createPipe(); + _fdIntrRead = (java.nio.channels.ReadableByteChannel)pair.source; + _fdIntrWrite = pair.sink; + + try + { + _selector = java.nio.channels.Selector.open(); + pair.source.configureBlocking(false); + _fdIntrReadKey = pair.source.register(_selector, java.nio.channels.SelectionKey.OP_READ); + } + catch(java.io.IOException ex) + { + Ice.SyscallException sys = new Ice.SyscallException(); + sys.initCause(ex); + throw sys; + } + + // + // The Selector holds a Set representing the selected keys. The + // Set reference doesn't change, so we obtain it once here. + // + _keys = _selector.selectedKeys(); + + _thread = new HelperThread(); + _thread.start(); + + _timer = _instance.timer(); + } + + protected synchronized void + finalize() + throws Throwable + { + IceUtil.Assert.FinalizerAssert(_destroyed); + } + + public synchronized void + destroy() + { + assert(!_destroyed); + _destroyed = true; + setInterrupt(); + } + + public synchronized void + _register(java.nio.channels.SelectableChannel fd, SocketReadyCallback cb, SocketStatus status, int timeout) + { + assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing connection factories. + assert(status != SocketStatus.Finished); + + SocketInfo info = new SocketInfo(fd, cb, status, timeout); + _changes.add(info); + if(info.timeout >= 0) + { + _timer.schedule(info, info.timeout); + } + setInterrupt(); + } + + // + // Unregister the given file descriptor. The registered callback will be notified with socketReady() + // upon registration to allow some cleanup to be done. + // + public synchronized void + unregister(java.nio.channels.SelectableChannel fd) + { + assert(!_destroyed); // The selector thread is destroyed after the incoming/outgoing connection factories. + _changes.add(new SocketInfo(fd, null, SocketStatus.Finished, 0)); + setInterrupt(); + } + + public void + joinWithThread() + { + if(_thread != null) + { + try + { + _thread.join(); + } + catch(InterruptedException ex) + { + } + } + } + + private void + clearInterrupt() + { + byte b = 0; + + java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(1); + try + { + while(true) + { + buf.rewind(); + if(_fdIntrRead.read(buf) != 1) + { + break; + } + + b = buf.get(0); + break; + } + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } + + private void + setInterrupt() + { + java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(1); + buf.put(0, (byte)0); + while(buf.hasRemaining()) + { + try + { + _fdIntrWrite.write(buf); + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } + } + + public void + run() + { + java.util.HashMap socketMap = new java.util.HashMap(); + java.util.LinkedList readyList = new java.util.LinkedList(); + java.util.LinkedList finishedList = new java.util.LinkedList(); + while(true) + { + int ret = 0; + + while(true) + { + try + { + ret = _selector.select(); + } + catch(java.io.IOException ex) + { + // + // Pressing Ctrl-C causes select() to raise an + // IOException, which seems like a JDK bug. We trap + // for that special case here and ignore it. + // Hopefully we're not masking something important! + // + if(Network.interrupted(ex)) + { + continue; + } + + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + //throw se; + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + se.printStackTrace(pw); + pw.flush(); + String s = "exception in selector thread:\n" + sw.toString(); + _instance.initializationData().logger.error(s); + continue; + } + + break; + } + + assert(readyList.isEmpty() && finishedList.isEmpty()); + + if(_keys.contains(_fdIntrReadKey) && _fdIntrReadKey.isReadable()) + { + synchronized(this) + { + // + // There are two possiblities for an interrupt: + // + // 1. The selector thread has been destroyed. + // 2. A socket was registered or unregistered. + // + + // + // Thread destroyed? + // + if(_destroyed) + { + break; + } + + // + // Remove the interrupt channel from the selected key set. + // + _keys.remove(_fdIntrReadKey); + + clearInterrupt(); + SocketInfo info = (SocketInfo)_changes.removeFirst(); + if(info.cb != null) // Registration + { + try + { + info.key = info.fd.register(_selector, convertStatus(info.status), info); + } + catch(java.nio.channels.ClosedChannelException ex) + { + assert(false); + } + assert(!socketMap.containsKey(info.fd)); + socketMap.put(info.fd, info); + } + else // Unregistration + { + info = (SocketInfo)socketMap.get(info.fd); + if(info != null && info.status != SocketStatus.Finished) + { + if(info.timeout >= 0) + { + _timer.cancel(info); + } + + try + { + info.key.cancel(); + } + catch(java.nio.channels.CancelledKeyException ex) + { + assert(false); + } + info.status = SocketStatus.Finished; + readyList.add(info); + } + } + } + } + else + { + // + // Examine the selection key set. + // + java.util.Iterator iter = _keys.iterator(); + while(iter.hasNext()) + { + // + // Ignore selection keys that have been cancelled or timed out. + // + java.nio.channels.SelectionKey key = (java.nio.channels.SelectionKey)iter.next(); + iter.remove(); + assert(key != _fdIntrReadKey); + SocketInfo info = (SocketInfo)key.attachment(); + if(info.timeout >= 0) + { + _timer.cancel(info); + } + assert(key.isValid()); + readyList.add(info); + } + } + + java.util.Iterator iter = readyList.iterator(); + while(iter.hasNext()) + { + SocketInfo info = (SocketInfo)iter.next(); + SocketStatus status; + try + { + status = info.cb.socketReady(info.status == SocketStatus.Finished); + } + catch(Ice.LocalException ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "exception in selector thread " + _thread.getName() + + " while calling socketReady():\n" + sw.toString(); + _instance.initializationData().logger.error(s); + status = SocketStatus.Finished; + } + + if(status == SocketStatus.Finished) + { + finishedList.add(info); + } + else + { + assert(info.status != SocketStatus.Finished); + try + { + info.status = status; + info.key.interestOps(convertStatus(status)); + if(info.timeout >= 0) + { + _timer.schedule(info, info.timeout); + } + } + catch(java.nio.channels.CancelledKeyException ex) + { + assert(false); + } + } + } + readyList.clear(); + + if(finishedList.isEmpty()) + { + continue; + } + + iter = finishedList.iterator(); + while(iter.hasNext()) + { + SocketInfo info = (SocketInfo)iter.next(); + if(info.status != SocketStatus.Finished) + { + try + { + info.key.cancel(); + } + catch(java.nio.channels.CancelledKeyException ex) + { + //assert(false); // The channel might already be closed at this point so we can't assert. + } + } + socketMap.remove(info.fd); + } + finishedList.clear(); + } + + assert(_destroyed); + + try + { + _selector.close(); + } + catch(java.io.IOException ex) + { + // Ignore. + } + + try + { + _fdIntrWrite.close(); + } + catch(java.io.IOException ex) + { + // + // BUGFIX: + // + // Ignore this exception. This shouldn't happen + // but for some reasons the close() call raises + // "java.io.IOException: No such file or + // directory" under Linux with JDK 1.4.2. + // + } + _fdIntrWrite = null; + + try + { + _fdIntrRead.close(); + } + catch(java.io.IOException ex) + { + } + _fdIntrRead = null; + } + + private int + convertStatus(SocketStatus status) + { + if(status == SocketStatus.NeedConnect) + { + return java.nio.channels.SelectionKey.OP_CONNECT; + } + else if(status == SocketStatus.NeedRead) + { + return java.nio.channels.SelectionKey.OP_READ; + } + else + { + assert(status == SocketStatus.NeedWrite); + return java.nio.channels.SelectionKey.OP_WRITE; + } + } + + private Instance _instance; + private boolean _destroyed; + private java.nio.channels.ReadableByteChannel _fdIntrRead; + private java.nio.channels.SelectionKey _fdIntrReadKey; + private java.nio.channels.WritableByteChannel _fdIntrWrite; + private java.nio.channels.Selector _selector; + private java.util.Set _keys; + private java.util.LinkedList _changes = new java.util.LinkedList(); + + private final class SocketInfo implements TimerTask + { + java.nio.channels.SelectableChannel fd; + SocketReadyCallback cb; + SocketStatus status; + int timeout; + java.nio.channels.SelectionKey key; + + public void + runTimerTask() + { + this.cb.socketTimeout(); // Exceptions will be reported by the timer thread. + } + + SocketInfo(java.nio.channels.SelectableChannel fd, SocketReadyCallback cb, SocketStatus status, int timeout) + { + this.fd = fd; + this.cb = cb; + this.status = status; + this.timeout = timeout; + } + } + + private final class HelperThread extends Thread + { + HelperThread() + { + String threadName = _instance.initializationData().properties.getProperty("Ice.ProgramName"); + if(threadName.length() > 0) + { + threadName += "-"; + } + setName(threadName + "Ice.SelectorThread"); + } + + public void + run() + { + if(_instance.initializationData().threadHook != null) + { + _instance.initializationData().threadHook.start(); + } + + try + { + SelectorThread.this.run(); + } + catch(Ice.LocalException ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "exception in selector thread " + getName() + ":\n" + sw.toString(); + _instance.initializationData().logger.error(s); + } + catch(java.lang.Exception ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "unknown exception in selector thread " + getName() + ":\n" + sw.toString(); + _instance.initializationData().logger.error(s); + } + + if(_instance.initializationData().threadHook != null) + { + _instance.initializationData().threadHook.stop(); + } + } + } + + private HelperThread _thread; + private Timer _timer; +} diff --git a/java/src/IceInternal/SocketStatus.java b/java/src/IceInternal/SocketStatus.java new file mode 100644 index 00000000000..dc3bed4a735 --- /dev/null +++ b/java/src/IceInternal/SocketStatus.java @@ -0,0 +1,39 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public final class SocketStatus +{ + private static SocketStatus[] _values = new SocketStatus[4]; + + public static final int _Finished = 0; + public static final SocketStatus Finished = new SocketStatus(_Finished); + public static final int _NeedConnect = 1; + public static final SocketStatus NeedConnect = new SocketStatus(_NeedConnect); + public static final int _NeedRead = 2; + public static final SocketStatus NeedRead = new SocketStatus(_NeedRead); + public static final int _NeedWrite = 3; + public static final SocketStatus NeedWrite = new SocketStatus(_NeedWrite); + + public int + value() + { + return _value; + } + + private + SocketStatus(int val) + { + _value = val; + _values[val] = this; + } + + private int _value; +} diff --git a/java/src/IceInternal/TcpAcceptor.java b/java/src/IceInternal/TcpAcceptor.java index 21d56732fc6..72eaec50cf9 100644 --- a/java/src/IceInternal/TcpAcceptor.java +++ b/java/src/IceInternal/TcpAcceptor.java @@ -160,7 +160,7 @@ class TcpAcceptor implements Acceptor _logger.trace(_traceLevels.networkCat, s); } - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd, true); } public void diff --git a/java/src/IceInternal/TcpConnector.java b/java/src/IceInternal/TcpConnector.java index 2635d9ad881..ab2a2a877e3 100644 --- a/java/src/IceInternal/TcpConnector.java +++ b/java/src/IceInternal/TcpConnector.java @@ -11,8 +11,6 @@ package IceInternal; final class TcpConnector implements Connector, java.lang.Comparable { - final static short TYPE = 1; - public Transceiver connect(int timeout) { @@ -25,21 +23,22 @@ final class TcpConnector implements Connector, java.lang.Comparable java.nio.channels.SocketChannel fd = Network.createTcpSocket(); Network.setBlock(fd, false); Network.setTcpBufSize(fd, _instance.initializationData().properties, _logger); - Network.doConnect(fd, _addr, timeout); - - if(_traceLevels.network >= 1) + boolean connected = Network.doConnect(fd, _addr, timeout); + if(connected) { - String s = "tcp connection established\n" + Network.fdToString(fd); - _logger.trace(_traceLevels.networkCat, s); + if(_traceLevels.network >= 1) + { + String s = "tcp connection established\n" + Network.fdToString(fd); + _logger.trace(_traceLevels.networkCat, s); + } } - - return new TcpTransceiver(_instance, fd); + return new TcpTransceiver(_instance, fd, connected); } public short type() { - return TYPE; + return TcpEndpointI.TYPE; } public String @@ -54,21 +53,6 @@ final class TcpConnector implements Connector, java.lang.Comparable return _hashCode; } - public final boolean - equivalent(String host, int port) - { - java.net.InetSocketAddress addr; - try - { - addr = Network.getAddress(host, port); - } - catch(Ice.DNSException ex) - { - return false; - } - return addr.equals(_addr); - } - // // Only for use by TcpEndpoint // @@ -149,6 +133,13 @@ final class TcpConnector implements Connector, java.lang.Comparable return Network.compareAddress(_addr, p._addr); } + protected synchronized void + finalize() + throws Throwable + { + super.finalize(); + } + private Instance _instance; private TraceLevels _traceLevels; private Ice.Logger _logger; diff --git a/java/src/IceInternal/TcpEndpointI.java b/java/src/IceInternal/TcpEndpointI.java index 941b1ee0cc3..90b3073b3ce 100644 --- a/java/src/IceInternal/TcpEndpointI.java +++ b/java/src/IceInternal/TcpEndpointI.java @@ -332,17 +332,16 @@ final class TcpEndpointI extends EndpointI // Return connectors for this endpoint, or empty list if no connector // is available. // - public java.util.ArrayList + public java.util.List connectors() { - java.util.ArrayList connectors = new java.util.ArrayList(); - java.util.ArrayList addresses = Network.getAddresses(_host, _port); - java.util.Iterator p = addresses.iterator(); - while(p.hasNext()) - { - connectors.add(new TcpConnector(_instance, (java.net.InetSocketAddress)p.next(), _timeout, _connectionId)); - } - return connectors; + return connectors(Network.getAddresses(_host, _port)); + } + + public void + connectors_async(EndpointI_connectors callback) + { + _instance.endpointHostResolver().resolve(_host, _port, this, callback); } // @@ -364,7 +363,7 @@ final class TcpEndpointI extends EndpointI // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public java.util.ArrayList + public java.util.List expand() { java.util.ArrayList endps = new java.util.ArrayList(); @@ -389,21 +388,21 @@ final class TcpEndpointI extends EndpointI } // - // Check whether the endpoint is equivalent to a specific Connector + // Check whether the endpoint is equivalent to another one. // public boolean - equivalent(Connector connector) + equivalent(EndpointI endpoint) { - TcpConnector tcpConnector = null; + TcpEndpointI tcpEndpointI = null; try { - tcpConnector = (TcpConnector)connector; + tcpEndpointI = (TcpEndpointI)endpoint; } catch(ClassCastException ex) { return false; } - return tcpConnector.equivalent(_host, _port); + return tcpEndpointI._host.equals(_host) && tcpEndpointI._port == _port; } public int @@ -489,6 +488,18 @@ final class TcpEndpointI extends EndpointI return false; } + public java.util.List + connectors(java.util.List addresses) + { + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = addresses.iterator(); + while(p.hasNext()) + { + connectors.add(new TcpConnector(_instance, (java.net.InetSocketAddress)p.next(), _timeout, _connectionId)); + } + return connectors; + } + private void calcHashValue() { diff --git a/java/src/IceInternal/TcpTransceiver.java b/java/src/IceInternal/TcpTransceiver.java index f07bff3a62c..533b91adfc7 100644 --- a/java/src/IceInternal/TcpTransceiver.java +++ b/java/src/IceInternal/TcpTransceiver.java @@ -18,6 +18,29 @@ final class TcpTransceiver implements Transceiver return _fd; } + public SocketStatus + initialize(int timeout) + { + if(_state == StateNeedConnect && timeout == 0) + { + _state = StateConnectPending; + return SocketStatus.NeedConnect; + } + else if(_state <= StateConnectPending) + { + Network.doFinishConnect(_fd, timeout); + _state = StateConnected; + _desc = Network.fdToString(_fd); + if(_traceLevels.network >= 1) + { + String s = "tcp connection established\n" + _desc; + _logger.trace(_traceLevels.networkCat, s); + } + } + assert(_state == StateConnected); + return SocketStatus.Finished; + } + public void close() { @@ -74,6 +97,11 @@ final class TcpTransceiver implements Transceiver public void shutdownWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels.network >= 2) { String s = "shutting down tcp connection for writing\n" + toString(); @@ -110,6 +138,11 @@ final class TcpTransceiver implements Transceiver public void shutdownReadWrite() { + if(_state < StateConnected) + { + return; + } + if(_traceLevels.network >= 2) { String s = "shutting down tcp connection for reading and writing\n" + toString(); @@ -144,125 +177,78 @@ final class TcpTransceiver implements Transceiver } } - public void - write(BasicStream stream, int timeout) + public boolean + write(Buffer buf, int timeout) throws LocalExceptionWrapper { - java.nio.ByteBuffer buf = stream.prepareWrite(); - int size = buf.limit(); - int packetSize = 0; - if(_maxPacketSize > 0 && size > _maxPacketSize) + while(writeBuffer(buf.b)) { - packetSize = _maxPacketSize; - buf.limit(buf.position() + packetSize); - } + // + // There is more data to write but the socket would block; now we + // must deal with timeouts. + // + assert(buf.b.hasRemaining()); - while(buf.hasRemaining()) - { + if(timeout == 0) + { + return false; + } + try { - assert(_fd != null); - int ret = _fd.write(buf); - - if(ret == -1) + if(_writeSelector == null) { - throw new Ice.ConnectionLostException(); + _writeSelector = java.nio.channels.Selector.open(); + _fd.register(_writeSelector, java.nio.channels.SelectionKey.OP_WRITE, null); } - if(ret == 0) + try { - if(timeout == 0) + if(timeout > 0) { - throw new Ice.TimeoutException(); - } - - if(_writeSelector == null) - { - _writeSelector = java.nio.channels.Selector.open(); - _fd.register(_writeSelector, java.nio.channels.SelectionKey.OP_WRITE, null); - } - - try - { - if(timeout > 0) - { - long start = IceInternal.Time.currentMonotonicTimeMillis(); - int n = _writeSelector.select(timeout); - if(n == 0 && IceInternal.Time.currentMonotonicTimeMillis() >= start + timeout) - { - throw new Ice.TimeoutException(); - } - } - else + long start = IceInternal.Time.currentMonotonicTimeMillis(); + int n = _writeSelector.select(timeout); + if(n == 0 && IceInternal.Time.currentMonotonicTimeMillis() >= start + timeout) { - _writeSelector.select(); + throw new Ice.TimeoutException(); } } - catch(java.io.InterruptedIOException ex) + else { - // Ignore. + _writeSelector.select(); } - - continue; } - - - if(_traceLevels.network >= 3) - { - String s = "sent " + ret + " of " + buf.limit() + " bytes via tcp\n" + toString(); - _logger.trace(_traceLevels.networkCat, s); - } - - if(_stats != null) - { - _stats.bytesSent(type(), ret); - } - - if(packetSize > 0) + catch(java.io.InterruptedIOException ex) { - assert(buf.position() == buf.limit()); - int position = buf.position(); - if(size - position > packetSize) - { - buf.limit(position + packetSize); - } - else - { - packetSize = 0; - buf.limit(size); - } + // Ignore. } } - catch(java.io.InterruptedIOException ex) - { - continue; - } catch(java.io.IOException ex) { Ice.SocketException se = new Ice.SocketException(); se.initCause(ex); throw se; } - } + } + return true; } public boolean - read(BasicStream stream, int timeout) + read(Buffer buf, int timeout, Ice.BooleanHolder moreData) { - java.nio.ByteBuffer buf = stream.prepareRead(); - int remaining = 0; if(_traceLevels.network >= 3) { - remaining = buf.remaining(); + remaining = buf.b.remaining(); } + moreData.value = false; - while(buf.hasRemaining()) + while(buf.b.hasRemaining()) { try { assert(_fd != null); - int ret = _fd.read(buf); + int ret = _fd.read(buf.b); if(ret == -1) { @@ -273,7 +259,7 @@ final class TcpTransceiver implements Transceiver { if(timeout == 0) { - throw new Ice.TimeoutException(); + return false; } if(_readSelector == null) @@ -339,7 +325,7 @@ final class TcpTransceiver implements Transceiver } } - return false; + return true; } public String @@ -355,9 +341,9 @@ final class TcpTransceiver implements Transceiver } public void - checkSendSize(BasicStream stream, int messageSizeMax) + checkSendSize(Buffer buf, int messageSizeMax) { - if(stream.size() > messageSizeMax) + if(buf.size() > messageSizeMax) { throw new Ice.MemoryLimitException(); } @@ -366,12 +352,13 @@ final class TcpTransceiver implements Transceiver // // Only for use by TcpConnector, TcpAcceptor // - TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd) + TcpTransceiver(Instance instance, java.nio.channels.SocketChannel fd, boolean connected) { _fd = fd; _traceLevels = instance.traceLevels(); _logger = instance.initializationData().logger; _stats = instance.initializationData().stats; + _state = connected ? StateConnected : StateNeedConnect; _desc = Network.fdToString(_fd); _maxPacketSize = 0; @@ -399,12 +386,89 @@ final class TcpTransceiver implements Transceiver super.finalize(); } + private boolean + writeBuffer(java.nio.ByteBuffer buf) + { + final int size = buf.limit(); + int packetSize = size - buf.position(); + if(_maxPacketSize > 0 && packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + buf.limit(buf.position() + packetSize); + } + + while(buf.hasRemaining()) + { + try + { + assert(_fd != null); + int ret = _fd.write(buf); + + if(ret == -1) + { + throw new Ice.ConnectionLostException(); + } + else if(ret == 0) + { + // + // Writing would block, so we reset the limit (if necessary) and return true to indicate + // that more data must be sent. + // + if(packetSize == _maxPacketSize) + { + buf.limit(size); + } + return true; + } + + if(_traceLevels.network >= 3) + { + String s = "sent " + ret + " of " + size + " bytes via tcp\n" + toString(); + _logger.trace(_traceLevels.networkCat, s); + } + + if(_stats != null) + { + _stats.bytesSent(type(), ret); + } + + if(packetSize == _maxPacketSize) + { + assert(buf.position() == buf.limit()); + packetSize = size - buf.position(); + if(packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + } + buf.limit(buf.position() + packetSize); + } + } + catch(java.io.InterruptedIOException ex) + { + continue; + } + catch(java.io.IOException ex) + { + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } + + return false; // No more data to send. + } + private java.nio.channels.SocketChannel _fd; private TraceLevels _traceLevels; private Ice.Logger _logger; private Ice.Stats _stats; private String _desc; + private int _state; private java.nio.channels.Selector _readSelector; private java.nio.channels.Selector _writeSelector; private int _maxPacketSize; + + private static final int StateNeedConnect = 0; + private static final int StateConnectPending = 1; + private static final int StateConnected = 2; } diff --git a/java/src/IceInternal/ThreadPool.java b/java/src/IceInternal/ThreadPool.java index 30ed86a3082..6306ca10475 100644 --- a/java/src/IceInternal/ThreadPool.java +++ b/java/src/IceInternal/ThreadPool.java @@ -146,6 +146,7 @@ public final class ThreadPool assert(!_destroyed); assert(_handlerMap.isEmpty()); assert(_changes.isEmpty()); + assert(_workItems.isEmpty()); _destroyed = true; setInterrupt(); } @@ -193,6 +194,14 @@ public final class ThreadPool setInterrupt(); } + public synchronized void + execute(ThreadPoolWorkItem workItem) + { + assert(!_destroyed); + _workItems.add(workItem); + setInterrupt(); + } + public void promoteFollower() { @@ -468,6 +477,7 @@ public final class ThreadPool } EventHandler handler = null; + ThreadPoolWorkItem workItem = null; // // Only call select() if there are no pending handlers with additional data @@ -510,14 +520,15 @@ public final class ThreadPool } // - // There are two possiblities for an interrupt: + // There are three possiblities for an interrupt: // // 1. The thread pool has been destroyed. // // 2. An event handler was registered or unregistered. // - + // 3. A work item has been scheduled. // + // Thread pool destroyed? // if(_destroyed) @@ -547,57 +558,79 @@ public final class ThreadPool // An event handler must have been registered // or unregistered. // - assert(!_changes.isEmpty()); - FdHandlerPair change = (FdHandlerPair)_changes.removeFirst(); - - if(change.handler != null) // Addition if handler is set. + if(!_changes.isEmpty()) { - int op; - if((change.fd.validOps() & java.nio.channels.SelectionKey.OP_READ) > 0) - { - op = java.nio.channels.SelectionKey.OP_READ; - } - else + FdHandlerPair change = (FdHandlerPair)_changes.removeFirst(); + + if(change.handler != null) // Addition if handler is set. { - op = java.nio.channels.SelectionKey.OP_ACCEPT; - } + int op; + if((change.fd.validOps() & java.nio.channels.SelectionKey.OP_READ) > 0) + { + op = java.nio.channels.SelectionKey.OP_READ; + } + else + { + op = java.nio.channels.SelectionKey.OP_ACCEPT; + } - java.nio.channels.SelectionKey key = null; - try - { - key = change.fd.register(_selector, op, change.handler); + java.nio.channels.SelectionKey key = null; + try + { + key = change.fd.register(_selector, op, change.handler); + } + catch(java.nio.channels.ClosedChannelException ex) + { + // + // This is expected if the transceiver finishConnect() call failed + // and the connection is a background connection. + // + } + _handlerMap.put(change.fd, new HandlerKeyPair(change.handler, key)); + + // + // If the handler is readable and already has some data to read add it + // to the _pendingHandlers list to ensure it will be processed. + // + if(change.handler.readable() && change.handler.hasMoreData()) + { + _pendingHandlers.add(change.handler); + } + + if(TRACE_REGISTRATION) + { + trace("added handler (" + change.handler.getClass().getName() + ") for fd " + + change.fd); + } + + continue; } - catch(java.nio.channels.ClosedChannelException ex) + else // Removal if handler is not set. { - assert(false); - } - _handlerMap.put(change.fd, new HandlerKeyPair(change.handler, key)); + HandlerKeyPair pair = (HandlerKeyPair)_handlerMap.remove(change.fd); + assert(pair != null); + handler = pair.handler; + finished = true; + if(pair.key != null) + { + pair.key.cancel(); + } - if(TRACE_REGISTRATION) - { - trace("added handler (" + change.handler.getClass().getName() + ") for fd " + - change.fd); - } + if(TRACE_REGISTRATION) + { + trace("removed handler (" + handler.getClass().getName() + ") for fd " + + change.fd); + } - continue; + // Don't continue; we have to call + // finished() on the event handler below, + // outside the thread synchronization. + } } - else // Removal if handler is not set. + else { - HandlerKeyPair pair = (HandlerKeyPair)_handlerMap.remove(change.fd); - assert(pair != null); - handler = pair.handler; - finished = true; - pair.key.cancel(); - - if(TRACE_REGISTRATION) - { - trace("removed handler (" + handler.getClass().getName() + ") for fd " + - change.fd); - } - - // Don't continue; we have to call - // finished() on the event handler below, - // outside the thread synchronization. + assert(!_workItems.isEmpty()); + workItem = (ThreadPoolWorkItem)_workItems.removeFirst(); } } else @@ -672,6 +705,29 @@ public final class ThreadPool // promoteFollower(). // } + else if(workItem != null) + { + try + { + workItem.execute(this); + } + catch(Ice.LocalException ex) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + String s = "exception in `" + _prefix + "' while calling execute():\n" + sw.toString(); + _instance.initializationData().logger.error(s); + } + + // + // No "continue", because we want execute() to + // be called in its own thread from this + // pool. Note that this means that execute() + // must call promoteFollower(). + // + } else { assert(handler != null); @@ -716,17 +772,23 @@ public final class ThreadPool { try { + if(!read(handler)) + { + continue; // Can't read without blocking. + } + // - // If read returns true, the handler has more data for the thread pool - // to process. + // If the handler has more data to process add it to the _pendingHandlers list + // to ensure it will be processed. // - if(read(handler)) + if(handler.hasMoreData()) { _pendingHandlers.add(handler); } } - catch(Ice.TimeoutException ex) // Expected. + catch(Ice.TimeoutException ex) { + assert(false); // This shouldn't occur as we only perform non-blocking reads. continue; } catch(Ice.DatagramLimitException ex) // Expected. @@ -914,8 +976,6 @@ public final class ThreadPool private boolean read(EventHandler handler) { - boolean moreData = false; - BasicStream stream = handler._stream; if(stream.size() == 0) @@ -926,7 +986,10 @@ public final class ThreadPool if(stream.pos() != stream.size()) { - moreData = handler.read(stream); + if(!handler.read(stream)) + { + return false; + } assert(stream.pos() == stream.size()); } @@ -1008,12 +1071,15 @@ public final class ThreadPool } else { - moreData = handler.read(stream); + if(!handler.read(stream)) + { + return false; + } assert(stream.pos() == stream.size()); } } - return moreData; + return true; } /* @@ -1205,6 +1271,7 @@ public final class ThreadPool private java.util.Set _keys; private java.util.LinkedList _changes = new java.util.LinkedList(); + private java.util.LinkedList _workItems = new java.util.LinkedList(); private java.util.HashMap _handlerMap = new java.util.HashMap(); diff --git a/java/src/IceInternal/ThreadPoolWorkItem.java b/java/src/IceInternal/ThreadPoolWorkItem.java new file mode 100644 index 00000000000..ba917b67708 --- /dev/null +++ b/java/src/IceInternal/ThreadPoolWorkItem.java @@ -0,0 +1,15 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +package IceInternal; + +public interface ThreadPoolWorkItem +{ + void execute(ThreadPool threadPool); +} diff --git a/java/src/IceInternal/Time.java b/java/src/IceInternal/Time.java index d77879ef836..04059a31fff 100644 --- a/java/src/IceInternal/Time.java +++ b/java/src/IceInternal/Time.java @@ -16,4 +16,4 @@ final public class Time { return System.nanoTime() / 1000000; } -}; +} diff --git a/java/src/IceInternal/Timer.java b/java/src/IceInternal/Timer.java index 44e8ba0f6eb..7646409a16c 100644 --- a/java/src/IceInternal/Timer.java +++ b/java/src/IceInternal/Timer.java @@ -11,8 +11,8 @@ package IceInternal; interface TimerTask { - void run(); -}; + void runTimerTask(); +} public final class Timer extends Thread { @@ -224,7 +224,7 @@ public final class Timer extends Thread { try { - token.task.run(); + token.task.runTimerTask(); } catch(Exception ex) { diff --git a/java/src/IceInternal/TraceUtil.java b/java/src/IceInternal/TraceUtil.java index 7a81793ffdc..6a85917a7c4 100644 --- a/java/src/IceInternal/TraceUtil.java +++ b/java/src/IceInternal/TraceUtil.java @@ -12,77 +12,41 @@ package IceInternal; public final class TraceUtil { public static void - traceHeader(String heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + traceSend(BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { int p = str.pos(); str.pos(0); - + java.io.StringWriter s = new java.io.StringWriter(); - s.write(heading); - printHeader(s, str); + byte type = printMessage(s, str); - logger.trace(tl.protocolCat, s.toString()); - str.pos(p); - } - } + logger.trace(tl.protocolCat, "sending " + getMessageTypeAsString(type) + " " + s.toString()); - public static void - traceRequest(String heading, BasicStream str, Ice.Logger logger, TraceLevels tl) - { - if(tl.protocol >= 1) - { - int p = str.pos(); - str.pos(0); - - java.io.StringWriter s = new java.io.StringWriter(); - s.write(heading); - printHeader(s, str); - - int requestId = str.readInt(); - s.write("\nrequest id = " + requestId); - if(requestId == 0) - { - s.write(" (oneway)"); - } - - printRequestHeader(s, str); - - logger.trace(tl.protocolCat, s.toString()); str.pos(p); } } public static void - traceBatchRequest(String heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + traceRecv(BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { int p = str.pos(); str.pos(0); - + java.io.StringWriter s = new java.io.StringWriter(); - s.write(heading); - printHeader(s, str); + byte type = printMessage(s, str); - int batchRequestNum = str.readInt(); - s.write("\nnumber of requests = " + batchRequestNum); - - for(int i = 0; i < batchRequestNum; ++i) - { - s.write("\nrequest #" + i + ':'); - printRequestHeader(s, str); - str.skipEncaps(); - } + logger.trace(tl.protocolCat, "received " + getMessageTypeAsString(type) + " " + s.toString()); - logger.trace(tl.protocolCat, s.toString()); str.pos(p); } } public static void - traceReply(String heading, BasicStream str, Ice.Logger logger, TraceLevels tl) + trace(String heading, BasicStream str, Ice.Logger logger, TraceLevels tl) { if(tl.protocol >= 1) { @@ -91,105 +55,7 @@ public final class TraceUtil java.io.StringWriter s = new java.io.StringWriter(); s.write(heading); - printHeader(s, str); - - int requestId = str.readInt(); - s.write("\nrequest id = " + requestId); - - byte replyStatus = str.readByte(); - s.write("\nreply status = " + (int)replyStatus + ' '); - - switch(replyStatus) - { - case ReplyStatus.replyOK: - { - s.write("(ok)"); - break; - } - - case ReplyStatus.replyUserException: - { - s.write("(user exception)"); - break; - } - - case ReplyStatus.replyObjectNotExist: - case ReplyStatus.replyFacetNotExist: - case ReplyStatus.replyOperationNotExist: - { - switch(replyStatus) - { - case ReplyStatus.replyObjectNotExist: - { - s.write("(object not exist)"); - break; - } - - case ReplyStatus.replyFacetNotExist: - { - s.write("(facet not exist)"); - break; - } - - case ReplyStatus.replyOperationNotExist: - { - s.write("(operation not exist)"); - break; - } - - default: - { - assert(false); - break; - } - } - - printIdentityFacetOperation(s, str); - break; - } - - case ReplyStatus.replyUnknownException: - case ReplyStatus.replyUnknownLocalException: - case ReplyStatus.replyUnknownUserException: - { - switch(replyStatus) - { - case ReplyStatus.replyUnknownException: - { - s.write("(unknown exception)"); - break; - } - - case ReplyStatus.replyUnknownLocalException: - { - s.write("(unknown local exception)"); - break; - } - - case ReplyStatus.replyUnknownUserException: - { - s.write("(unknown user exception)"); - break; - } - - default: - { - assert(false); - break; - } - } - - String unknown = str.readString(); - s.write("\nunknown = " + unknown); - break; - } - - default: - { - s.write("(unknown)"); - break; - } - } + printMessage(s, str); logger.trace(tl.protocolCat, s.toString()); str.pos(p); @@ -304,6 +170,135 @@ public final class TraceUtil } private static void + printRequest(java.io.StringWriter s, BasicStream str) + { + int requestId = str.readInt(); + s.write("\nrequest id = " + requestId); + if(requestId == 0) + { + s.write(" (oneway)"); + } + + printRequestHeader(s, str); + } + + private static void + printBatchRequest(java.io.StringWriter s, BasicStream str) + { + int batchRequestNum = str.readInt(); + s.write("\nnumber of requests = " + batchRequestNum); + + for(int i = 0; i < batchRequestNum; ++i) + { + s.write("\nrequest #" + i + ':'); + printRequestHeader(s, str); + str.skipEncaps(); + } + } + + private static void + printReply(java.io.StringWriter s, BasicStream str) + { + int requestId = str.readInt(); + s.write("\nrequest id = " + requestId); + + byte replyStatus = str.readByte(); + s.write("\nreply status = " + (int)replyStatus + ' '); + + switch(replyStatus) + { + case ReplyStatus.replyOK: + { + s.write("(ok)"); + break; + } + + case ReplyStatus.replyUserException: + { + s.write("(user exception)"); + break; + } + + case ReplyStatus.replyObjectNotExist: + case ReplyStatus.replyFacetNotExist: + case ReplyStatus.replyOperationNotExist: + { + switch(replyStatus) + { + case ReplyStatus.replyObjectNotExist: + { + s.write("(object not exist)"); + break; + } + + case ReplyStatus.replyFacetNotExist: + { + s.write("(facet not exist)"); + break; + } + + case ReplyStatus.replyOperationNotExist: + { + s.write("(operation not exist)"); + break; + } + + default: + { + assert(false); + break; + } + } + + printIdentityFacetOperation(s, str); + break; + } + + case ReplyStatus.replyUnknownException: + case ReplyStatus.replyUnknownLocalException: + case ReplyStatus.replyUnknownUserException: + { + switch(replyStatus) + { + case ReplyStatus.replyUnknownException: + { + s.write("(unknown exception)"); + break; + } + + case ReplyStatus.replyUnknownLocalException: + { + s.write("(unknown local exception)"); + break; + } + + case ReplyStatus.replyUnknownUserException: + { + s.write("(unknown user exception)"); + break; + } + + default: + { + assert(false); + break; + } + } + + String unknown = str.readString(); + s.write("\nunknown = " + unknown); + break; + } + + default: + { + s.write("(unknown)"); + break; + } + } + } + + private static void printRequestHeader(java.io.Writer out, BasicStream stream) { printIdentityFacetOperation(out, stream); @@ -358,66 +353,28 @@ public final class TraceUtil } } - private static void + private static byte printHeader(java.io.Writer out, BasicStream stream) { - try - { - byte magic; - magic = stream.readByte(); // Don't bother printing the magic number - magic = stream.readByte(); - magic = stream.readByte(); - magic = stream.readByte(); - - byte pMajor = stream.readByte(); - byte pMinor = stream.readByte(); + byte magic; + magic = stream.readByte(); // Don't bother printing the magic number + magic = stream.readByte(); + magic = stream.readByte(); + magic = stream.readByte(); + + byte pMajor = stream.readByte(); + byte pMinor = stream.readByte(); // out.write("\nprotocol version = " + (int)pMajor + "." + (int)pMinor); - - byte eMajor = stream.readByte(); - byte eMinor = stream.readByte(); + + byte eMajor = stream.readByte(); + byte eMinor = stream.readByte(); // out.write("\nencoding version = " + (int)eMajor + "." + (int)eMinor); + + byte type = stream.readByte(); - byte type = stream.readByte(); - out.write("\nmessage type = " + (int)type + ' '); - switch(type) - { - case Protocol.requestMsg: - { - out.write("(request)"); - break; - } - - case Protocol.requestBatchMsg: - { - out.write("(batch request)"); - break; - } - - case Protocol.replyMsg: - { - out.write("(reply)"); - break; - } - - case Protocol.closeConnectionMsg: - { - out.write("(close connection)"); - break; - } - - case Protocol.validateConnectionMsg: - { - out.write("(validate connection)"); - break; - } - - default: - { - out.write("(unknown)"); - break; - } - } - + try + { + out.write("\nmessage type = " + (int)type + " (" + getMessageTypeAsString(type) + ')'); byte compress = stream.readByte(); out.write("\ncompression status = " + (int)compress + ' '); switch(compress) @@ -449,10 +406,73 @@ public final class TraceUtil int size = stream.readInt(); out.write("\nmessage size = " + size); + return type; } catch(java.io.IOException ex) { assert(false); + return 0; + } + } + + static private byte + printMessage(java.io.StringWriter s, BasicStream str) + { + byte type = printHeader(s, str); + + switch(type) + { + case Protocol.closeConnectionMsg: + case Protocol.validateConnectionMsg: + { + // We're done. + break; + } + + case Protocol.requestMsg: + { + printRequest(s, str); + break; + } + + case Protocol.requestBatchMsg: + { + printBatchRequest(s, str); + break; + } + + case Protocol.replyMsg: + { + printReply(s, str); + break; + } + + default: + { + break; + } + } + + return type; + } + + static private String + getMessageTypeAsString(byte type) + { + switch(type) + { + case Protocol.requestMsg: + return "request"; + case Protocol.requestBatchMsg: + return "batch request"; + case Protocol.replyMsg: + return "reply"; + case Protocol.closeConnectionMsg: + return "close connection"; + case Protocol.validateConnectionMsg: + return "validate connection"; + default: + return "unknown"; } } } diff --git a/java/src/IceInternal/Transceiver.java b/java/src/IceInternal/Transceiver.java index 260d59bde77..7dce61206b8 100644 --- a/java/src/IceInternal/Transceiver.java +++ b/java/src/IceInternal/Transceiver.java @@ -12,23 +12,60 @@ package IceInternal; public interface Transceiver { java.nio.channels.SelectableChannel fd(); + + // + // Initialize the transceiver. + // + // Returns the status if the initialize operation. If timeout is != 0, + // the status will always be SocketStatus.Finished. If timeout is 0, + // the operation won't block and will return SocketStatus.NeedRead or + // SocketStatus.NeedWrite if the initialization couldn't be completed + // without blocking. This operation should be called again once the + // socket is ready for reading or writing and until it returns + // SocketStatus.Finished. + // + SocketStatus initialize(int timeout); + void close(); void shutdownWrite(); void shutdownReadWrite(); + + // + // Write data. + // + // Returns true if all the data was written, false otherwise. If + // timeout is -1, this operation will block until all the data is + // written. If timeout is 0, it will return when the write can't + // be completed without blocking. If the timeout is > 0, it will + // block until all the data is written or the specified timeout + // expires. // // NOTE: In Java, write() can raise LocalExceptionWrapper to indicate that // retrying may not be safe, which is necessary to address an issue // in the IceSSL implementation for JDK 1.4. We can remove this if // we ever drop support for JDK 1.4 (also see Ice.ConnectionI). // - void write(BasicStream stream, int timeout) + boolean write(Buffer buf, int timeout) throws LocalExceptionWrapper; + // - // NOTE: In Java, read() returns a boolean to indicate whether the transceiver - // has read more data than requested. + // Read data. // - boolean read(BasicStream stream, int timeout); + // Returns true if all the requested data was read, false otherwise. + // If timeout is -1, this operation will block until all the data + // is read. If timeout is 0, it will return when the read can't be + // completed without blocking. If the timeout is > 0, it will + // block until all the data is read or the specified timeout + // expires. + // + // NOTE: In Java, read() returns a boolean in moreData to indicate + // whether the transceiver has read more data than requested. + // If moreData is true, read should be called again without + // calling select on the FD. + // + boolean read(Buffer buf, int timeout, Ice.BooleanHolder moreData); + String type(); String toString(); - void checkSendSize(BasicStream stream, int messageSizeMax); + void checkSendSize(Buffer buf, int messageSizeMax); } diff --git a/java/src/IceInternal/UdpConnector.java b/java/src/IceInternal/UdpConnector.java index e3c49b6955b..37964024236 100644 --- a/java/src/IceInternal/UdpConnector.java +++ b/java/src/IceInternal/UdpConnector.java @@ -11,18 +11,23 @@ package IceInternal; final class UdpConnector implements Connector, java.lang.Comparable { - final static short TYPE = 3; - public Transceiver connect(int timeout) { return new UdpTransceiver(_instance, _addr, _mcastInterface, _mcastTtl); } + public java.nio.channels.SelectableChannel + fd() + { + assert(false); // Shouldn't be called, startConnect always completes immediately. + return null; + } + public short type() { - return TYPE; + return UdpEndpointI.TYPE; } public String @@ -37,21 +42,6 @@ final class UdpConnector implements Connector, java.lang.Comparable return _hashCode; } - final public boolean - equivalent(String host, int port) - { - java.net.InetSocketAddress addr; - try - { - addr = Network.getAddress(host, port); - } - catch(Ice.DNSException ex) - { - return false; - } - return addr.equals(_addr); - } - // // Only for use by TcpEndpoint // diff --git a/java/src/IceInternal/UdpEndpointI.java b/java/src/IceInternal/UdpEndpointI.java index a87c6d9bed1..1d635a7dff2 100644 --- a/java/src/IceInternal/UdpEndpointI.java +++ b/java/src/IceInternal/UdpEndpointI.java @@ -501,19 +501,16 @@ final class UdpEndpointI extends EndpointI // Return connectors for this endpoint, or empty list if no connector // is available. // - public java.util.ArrayList + public java.util.List connectors() { - java.util.ArrayList connectors = new java.util.ArrayList(); - java.util.ArrayList addresses = Network.getAddresses(_host, _port); - java.util.Iterator p = addresses.iterator(); - while(p.hasNext()) - { - connectors.add( - new UdpConnector(_instance, (java.net.InetSocketAddress)p.next(), _mcastInterface, _mcastTtl, - _protocolMajor, _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); - } - return connectors; + return connectors(Network.getAddresses(_host, _port)); + } + + public void + connectors_async(EndpointI_connectors callback) + { + _instance.endpointHostResolver().resolve(_host, _port, this, callback); } // @@ -534,7 +531,7 @@ final class UdpEndpointI extends EndpointI // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public java.util.ArrayList + public java.util.List expand() { java.util.ArrayList endps = new java.util.ArrayList(); @@ -561,21 +558,21 @@ final class UdpEndpointI extends EndpointI } // - // Check whether the endpoint is equivalent to a specific Conenctor. + // Check whether the endpoint is equivalent to another one. // public boolean - equivalent(Connector connector) + equivalent(EndpointI endpoint) { - UdpConnector udpConnector = null; + UdpEndpointI udpEndpointI = null; try { - udpConnector = (UdpConnector)connector; + udpEndpointI = (UdpEndpointI)endpoint; } catch(ClassCastException ex) { return false; } - return udpConnector.equivalent(_host, _port); + return udpEndpointI._host.equals(_host) && udpEndpointI._port == _port; } public int @@ -712,6 +709,20 @@ final class UdpEndpointI extends EndpointI return false; } + public java.util.List + connectors(java.util.List addresses) + { + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = addresses.iterator(); + while(p.hasNext()) + { + connectors.add( + new UdpConnector(_instance, (java.net.InetSocketAddress)p.next(), _mcastInterface, _mcastTtl, + _protocolMajor, _protocolMinor, _encodingMajor, _encodingMinor, _connectionId)); + } + return connectors; + } + private void calcHashValue() { diff --git a/java/src/IceInternal/UdpTransceiver.java b/java/src/IceInternal/UdpTransceiver.java index 408379547f6..e04d4f0b84b 100644 --- a/java/src/IceInternal/UdpTransceiver.java +++ b/java/src/IceInternal/UdpTransceiver.java @@ -18,6 +18,15 @@ final class UdpTransceiver implements Transceiver return _fd; } + public SocketStatus + initialize(int timeout) + { + // + // Nothing to do. + // + return SocketStatus.Finished; + } + public synchronized void close() { @@ -38,6 +47,19 @@ final class UdpTransceiver implements Transceiver } _readSelector = null; } + + if(_writeSelector != null) + { + try + { + _writeSelector.close(); + } + catch(java.io.IOException ex) + { + // Ignore. + } + _writeSelector = null; + } } public void @@ -64,17 +86,19 @@ final class UdpTransceiver implements Transceiver { _readSelector.wakeup(); } + if(_writeSelector != null) + { + _writeSelector.wakeup(); + } } - public void - write(BasicStream stream, int timeout) // NOTE: timeout is not used + public boolean + write(Buffer buf, int timeout) throws LocalExceptionWrapper { - java.nio.ByteBuffer buf = stream.prepareWrite(); - - assert(buf.position() == 0); + assert(buf.b.position() == 0); final int packetSize = java.lang.Math.min(_maxPacketSize, _sndSize - _udpOverhead); - if(packetSize < buf.limit()) + if(packetSize < buf.size()) { // // We don't log a warning here because the client gets an exception anyway. @@ -82,12 +106,52 @@ final class UdpTransceiver implements Transceiver throw new Ice.DatagramLimitException(); } - while(buf.hasRemaining()) + while(buf.b.hasRemaining()) { try { assert(_fd != null); - int ret = _fd.write(buf); + + int ret = _fd.write(buf.b); + + if(ret == 0) + { + if(timeout == 0) + { + return false; + } + + synchronized(this) + { + if(_writeSelector == null) + { + _writeSelector = java.nio.channels.Selector.open(); + _fd.register(_writeSelector, java.nio.channels.SelectionKey.OP_WRITE, null); + } + } + + try + { + if(timeout > 0) + { + long start = IceInternal.Time.currentMonotonicTimeMillis(); + int n = _writeSelector.select(timeout); + if(n == 0 && IceInternal.Time.currentMonotonicTimeMillis() >= start + timeout) + { + throw new Ice.TimeoutException(); + } + } + else + { + _writeSelector.select(); + } + } + catch(java.io.InterruptedIOException ex) + { + // Ignore. + } + continue; + } if(_traceLevels.network >= 3) { @@ -100,7 +164,7 @@ final class UdpTransceiver implements Transceiver _stats.bytesSent(type(), ret); } - assert(ret == buf.limit()); + assert(ret == buf.b.limit()); break; } catch(java.nio.channels.AsynchronousCloseException ex) @@ -126,15 +190,18 @@ final class UdpTransceiver implements Transceiver throw se; } } + + return true; } public boolean - read(BasicStream stream, int timeout) // NOTE: timeout is not used + read(Buffer buf, int timeout, Ice.BooleanHolder moreData) { - assert(stream.pos() == 0); + assert(buf.b.position() == 0); + moreData.value = false; final int packetSize = java.lang.Math.min(_maxPacketSize, _rcvSize - _udpOverhead); - if(packetSize < stream.size()) + if(packetSize < buf.size()) { // // We log a warning here because this is the server side -- without the @@ -146,41 +213,8 @@ final class UdpTransceiver implements Transceiver } throw new Ice.DatagramLimitException(); } - stream.resize(packetSize, true); - java.nio.ByteBuffer buf = stream.prepareRead(); - buf.position(0); - - synchronized(this) - { - // - // Check for shutdown. - // - if(_fd == null) - { - throw new Ice.ConnectionLostException(); - } - if(_readSelector == null) - { - try - { - _readSelector = java.nio.channels.Selector.open(); - _fd.register(_readSelector, java.nio.channels.SelectionKey.OP_READ, null); - } - catch(java.io.IOException ex) - { - if(Network.connectionLost(ex)) - { - Ice.ConnectionLostException se = new Ice.ConnectionLostException(); - se.initCause(ex); - throw se; - } - - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - } + buf.resize(packetSize, true); + buf.b.position(0); int ret = 0; while(true) @@ -200,17 +234,48 @@ final class UdpTransceiver implements Transceiver try { - java.net.InetSocketAddress sender = (java.net.InetSocketAddress)fd.receive(buf); - if(sender == null || buf.position() == 0) + java.net.InetSocketAddress sender = (java.net.InetSocketAddress)fd.receive(buf.b); + + if(sender == null || buf.b.position() == 0) { - // - // Wait until packet arrives or socket is closed. - // - _readSelector.select(); + if(timeout == 0) + { + return false; + } + + synchronized(this) + { + if(_readSelector == null) + { + _readSelector = java.nio.channels.Selector.open(); + _fd.register(_readSelector, java.nio.channels.SelectionKey.OP_READ, null); + } + } + + try + { + if(timeout > 0) + { + long start = IceInternal.Time.currentMonotonicTimeMillis(); + int n = _readSelector.select(timeout); + if(n == 0 && IceInternal.Time.currentMonotonicTimeMillis() >= start + timeout) + { + throw new Ice.TimeoutException(); + } + } + else + { + _readSelector.select(); + } + } + catch(java.io.InterruptedIOException ex) + { + // Ignore. + } continue; } - ret = buf.position(); + ret = buf.b.position(); if(_connect) { @@ -272,10 +337,10 @@ final class UdpTransceiver implements Transceiver _stats.bytesReceived(type(), ret); } - stream.resize(ret, true); - stream.pos(ret); + buf.resize(ret, true); + buf.b.position(ret); - return false; + return true; } public String @@ -299,14 +364,14 @@ final class UdpTransceiver implements Transceiver } public void - checkSendSize(BasicStream stream, int messageSizeMax) + checkSendSize(Buffer buf, int messageSizeMax) { - if(stream.size() > messageSizeMax) + if(buf.size() > messageSizeMax) { throw new Ice.MemoryLimitException(); } final int packetSize = java.lang.Math.min(_maxPacketSize, _sndSize - _udpOverhead); - if(packetSize < stream.size()) + if(packetSize < buf.size()) { throw new Ice.DatagramLimitException(); } @@ -608,6 +673,7 @@ final class UdpTransceiver implements Transceiver private java.nio.channels.DatagramChannel _fd; private java.net.InetSocketAddress _addr; private java.nio.channels.Selector _readSelector; + private java.nio.channels.Selector _writeSelector; private boolean mcastServer = false; // diff --git a/java/src/IceInternal/UnknownEndpointI.java b/java/src/IceInternal/UnknownEndpointI.java index 226fe8f4bd0..638a81b52e9 100644 --- a/java/src/IceInternal/UnknownEndpointI.java +++ b/java/src/IceInternal/UnknownEndpointI.java @@ -238,12 +238,18 @@ final class UnknownEndpointI extends EndpointI // Return connectors for this endpoint, or empty list if no connector // is available. // - public java.util.ArrayList + public java.util.List connectors() { return new java.util.ArrayList(); } + public void + connectors_async(EndpointI_connectors callback) + { + callback.connectors(new java.util.ArrayList()); + } + // // Return an acceptor for this endpoint, or null if no acceptors // is available. In case an acceptor is created, this operation @@ -262,7 +268,7 @@ final class UnknownEndpointI extends EndpointI // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public java.util.ArrayList + public java.util.List expand() { java.util.ArrayList endps = new java.util.ArrayList(); @@ -271,10 +277,10 @@ final class UnknownEndpointI extends EndpointI } // - // Check whether the endpoint is equivalent to a specific Conenctor. + // Check whether the endpoint is equivalent to another one. // public boolean - equivalent(Connector connector) + equivalent(EndpointI endpoint) { return false; } diff --git a/java/src/IceSSL/AcceptorI.java b/java/src/IceSSL/AcceptorI.java index 04f2b3331ab..3d1ea382f35 100644 --- a/java/src/IceSSL/AcceptorI.java +++ b/java/src/IceSSL/AcceptorI.java @@ -37,14 +37,7 @@ final class AcceptorI implements IceInternal.Acceptor } if(fd != null) { - try - { - fd.close(); - } - catch(java.io.IOException ex) - { - // Ignore. - } + IceInternal.Network.closeSocketNoThrow(fd); } if(selector != null) { @@ -149,33 +142,6 @@ final class AcceptorI implements IceInternal.Acceptor } } - // - // Check whether this socket is the result of a call to connectToSelf. - // Despite the fact that connectToSelf immediately closes the socket, - // the server-side handshake process does not raise an exception. - // Furthermore, we can't simply proceed with the regular handshake - // process because we don't want to pass such a socket to the - // certificate verifier (if any). - // - // In order to detect a call to connectToSelf, we compare the remote - // address of the newly-accepted socket to that in _connectToSelfAddr. - // - java.net.SocketAddress remoteAddr = fd.socket().getRemoteSocketAddress(); - synchronized(this) - { - if(remoteAddr.equals(_connectToSelfAddr)) - { - try - { - fd.close(); - } - catch(java.io.IOException e) - { - } - return null; - } - } - javax.net.ssl.SSLEngine engine = null; try { @@ -199,24 +165,17 @@ final class AcceptorI implements IceInternal.Acceptor } catch(RuntimeException ex) { - try - { - fd.close(); - } - catch(java.io.IOException e) - { - // Ignore. - } + IceInternal.Network.closeSocketNoThrow(fd); throw ex; } if(_instance.networkTraceLevel() >= 1) { - _logger.trace(_instance.networkTraceCategory(), "attempting to accept ssl connection\n" + + _logger.trace(_instance.networkTraceCategory(), "accepting ssl connection\n" + IceInternal.Network.fdToString(fd)); } - return new TransceiverI(_instance, engine, fd, "", true, _adapterName); + return new TransceiverI(_instance, engine, fd, "", true, true, _adapterName); } public void @@ -224,17 +183,8 @@ final class AcceptorI implements IceInternal.Acceptor { java.nio.channels.SocketChannel fd = IceInternal.Network.createTcpSocket(); IceInternal.Network.setBlock(fd, false); - synchronized(this) - { - // - // connectToSelf is called to wake up the thread blocked in - // accept. We remember the originating address for use in - // accept. See accept for details. - // - IceInternal.Network.doConnect(fd, _addr, -1); - _connectToSelfAddr = (java.net.InetSocketAddress)fd.socket().getLocalSocketAddress(); - } - IceInternal.Network.closeSocket(fd); + IceInternal.Network.doConnect(fd, _addr, -1); + IceInternal.Network.closeSocketNoThrow(fd); } public String @@ -314,5 +264,4 @@ final class AcceptorI implements IceInternal.Acceptor private int _backlog; private java.net.InetSocketAddress _addr; private java.nio.channels.Selector _selector; - private java.net.InetSocketAddress _connectToSelfAddr; } diff --git a/java/src/IceSSL/ConnectorI.java b/java/src/IceSSL/ConnectorI.java index 9836a78753a..e2d25283302 100644 --- a/java/src/IceSSL/ConnectorI.java +++ b/java/src/IceSSL/ConnectorI.java @@ -11,8 +11,6 @@ package IceSSL; final class ConnectorI implements IceInternal.Connector, java.lang.Comparable { - final static short TYPE = 2; - public IceInternal.Transceiver connect(int timeout) { @@ -35,73 +33,24 @@ final class ConnectorI implements IceInternal.Connector, java.lang.Comparable java.nio.channels.SocketChannel fd = IceInternal.Network.createTcpSocket(); IceInternal.Network.setBlock(fd, false); IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger); - IceInternal.Network.doConnect(fd, _addr, timeout); + boolean connected = IceInternal.Network.doConnect(fd, _addr, timeout); - TransceiverI transceiver = null; try { javax.net.ssl.SSLEngine engine = _instance.createSSLEngine(false); - - transceiver = new TransceiverI(_instance, engine, fd, _host, false, ""); -/* - transceiver.waitForHandshake(timeout); - - // - // Check IceSSL.VerifyPeer. - // - int verifyPeer = - _instance.communicator().getProperties().getPropertyAsIntWithDefault("IceSSL.VerifyPeer", 2); - if(verifyPeer > 0) - { - try - { - engine.getSession().getPeerCertificates(); - } - catch(javax.net.ssl.SSLPeerUnverifiedException ex) - { - Ice.SecurityException e = new Ice.SecurityException(); - e.reason = "IceSSL: server did not supply a certificate"; - e.initCause(ex); - throw e; - } - } -*/ - -/* - if(!ctx.verifyPeer(fd, _host, false)) - { - Ice.SecurityException ex = new Ice.SecurityException(); - ex.reason = "IceSSL: outgoing connection rejected by certificate verifier"; - throw ex; - } -*/ + return new TransceiverI(_instance, engine, fd, _host, connected, false, ""); } catch(RuntimeException ex) { - try - { - fd.close(); - } - catch(java.io.IOException e) - { - // Ignore. - } + IceInternal.Network.closeSocketNoThrow(fd); throw ex; } - - if(_instance.networkTraceLevel() >= 1) - { - String s = "ssl connection established\n" + IceInternal.Network.fdToString(fd); - _logger.trace(_instance.networkTraceCategory(), s); - } - - return transceiver; } public short type() { - return TYPE; + return EndpointI.TYPE; } public String @@ -116,21 +65,6 @@ final class ConnectorI implements IceInternal.Connector, java.lang.Comparable return _hashCode; } - final boolean - equivalent(String host, int port) - { - java.net.InetSocketAddress addr; - try - { - addr = IceInternal.Network.getAddress(host, port); - } - catch(Ice.DNSException ex) - { - return false; - } - return addr.equals(_addr); - } - // // Only for use by EndpointI. // @@ -211,6 +145,13 @@ final class ConnectorI implements IceInternal.Connector, java.lang.Comparable return IceInternal.Network.compareAddress(_addr, p._addr); } + protected synchronized void + finalize() + throws Throwable + { + super.finalize(); + } + private Instance _instance; private Ice.Logger _logger; private String _host; diff --git a/java/src/IceSSL/EndpointI.java b/java/src/IceSSL/EndpointI.java index 8cf0f559fa4..f2a66c95f13 100644 --- a/java/src/IceSSL/EndpointI.java +++ b/java/src/IceSSL/EndpointI.java @@ -332,17 +332,16 @@ final class EndpointI extends IceInternal.EndpointI // Return connectors for this endpoint, or empty list if no connector // is available. // - public java.util.ArrayList + public java.util.List connectors() { - java.util.ArrayList connectors = new java.util.ArrayList(); - java.util.ArrayList addresses = IceInternal.Network.getAddresses(_host, _port); - java.util.Iterator p = addresses.iterator(); - while(p.hasNext()) - { - connectors.add(new ConnectorI(_instance, (java.net.InetSocketAddress)p.next(), _timeout, _connectionId)); - } - return connectors; + return connectors(IceInternal.Network.getAddresses(_host, _port)); + } + + public void + connectors_async(IceInternal.EndpointI_connectors callback) + { + _instance.endpointHostResolver().resolve(_host, _port, this, callback); } // @@ -364,7 +363,7 @@ final class EndpointI extends IceInternal.EndpointI // Expand endpoint out in to separate endpoints for each local // host if listening on INADDR_ANY. // - public java.util.ArrayList + public java.util.List expand() { java.util.ArrayList endps = new java.util.ArrayList(); @@ -393,18 +392,18 @@ final class EndpointI extends IceInternal.EndpointI // Check whether the endpoint is equivalent to a specific Connector. // public boolean - equivalent(IceInternal.Connector connector) + equivalent(IceInternal.EndpointI endpoint) { - ConnectorI sslConnector = null; + EndpointI sslEndpointI = null; try { - sslConnector = (ConnectorI)connector; + sslEndpointI = (EndpointI)endpoint; } catch(ClassCastException ex) { return false; } - return sslConnector.equivalent(_host, _port); + return sslEndpointI._host.equals(_host) && sslEndpointI._port == _port; } public int @@ -490,6 +489,18 @@ final class EndpointI extends IceInternal.EndpointI return false; } + public java.util.List + connectors(java.util.List addresses) + { + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = addresses.iterator(); + while(p.hasNext()) + { + connectors.add(new ConnectorI(_instance, (java.net.InetSocketAddress)p.next(), _timeout, _connectionId)); + } + return connectors; + } + private void calcHashValue() { diff --git a/java/src/IceSSL/Instance.java b/java/src/IceSSL/Instance.java index 0e6bb03a571..9d0251c5c13 100644 --- a/java/src/IceSSL/Instance.java +++ b/java/src/IceSSL/Instance.java @@ -507,6 +507,12 @@ class Instance return _facade.getCommunicator(); } + IceInternal.EndpointHostResolver + endpointHostResolver() + { + return _facade.getEndpointHostResolver(); + } + String defaultHost() { @@ -702,6 +708,7 @@ class Instance return _protocols; } + // TODO: Remove void traceConnection(java.nio.channels.SocketChannel fd, javax.net.ssl.SSLEngine engine, boolean incoming) { diff --git a/java/src/IceSSL/TransceiverI.java b/java/src/IceSSL/TransceiverI.java index b43a340c703..94d32b9f881 100644 --- a/java/src/IceSSL/TransceiverI.java +++ b/java/src/IceSSL/TransceiverI.java @@ -22,6 +22,48 @@ final class TransceiverI implements IceInternal.Transceiver return _fd; } + // + // All methods that can write to the socket are synchronized. + // + public synchronized IceInternal.SocketStatus + initialize(int timeout) + { + if(_state == StateNeedConnect && timeout == 0) + { + _state = StateConnectPending; + return IceInternal.SocketStatus.NeedConnect; + } + else if(_state <= StateConnectPending) + { + IceInternal.Network.doFinishConnect(_fd, timeout); + _state = StateConnected; + _desc = IceInternal.Network.fdToString(_fd); + } + assert(_state == StateConnected); + + IceInternal.SocketStatus status; + do + { + status = handshakeNonBlocking(); + if(timeout == 0) + { + return status; + } + + if(status != IceInternal.SocketStatus.Finished) + { + handleSocketStatus(status, timeout); + } + } + while(status != IceInternal.SocketStatus.Finished); + + return status; + } + + // + // All methods that can write to the socket are synchronized. + // + public void close() { @@ -78,13 +120,7 @@ final class TransceiverI implements IceInternal.Transceiver try { - _fd.close(); - } - catch(java.io.IOException ex) - { - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; + IceInternal.Network.closeSocket(_fd); } finally { @@ -98,6 +134,11 @@ final class TransceiverI implements IceInternal.Transceiver public synchronized void shutdownWrite() { + if(_state < StateConnected) + { + return; + } + if(_instance.networkTraceLevel() >= 2) { String s = "shutting down ssl connection for writing\n" + toString(); @@ -139,6 +180,11 @@ final class TransceiverI implements IceInternal.Transceiver public synchronized void shutdownReadWrite() { + if(_state < StateConnected) + { + return; + } + if(_instance.networkTraceLevel() >= 2) { String s = "shutting down ssl connection for reading and writing\n" + toString(); @@ -178,112 +224,58 @@ final class TransceiverI implements IceInternal.Transceiver // // All methods that can write to the socket are synchronized. // - public synchronized void - write(IceInternal.BasicStream stream, int timeout) + public synchronized boolean + write(IceInternal.Buffer buf, int timeout) throws IceInternal.LocalExceptionWrapper { - // - // Complete handshaking first if necessary. - // - if(!_handshakeComplete) - { - handshake(timeout); - } - - ByteBuffer buf = stream.prepareWrite(); + assert(_state == StateHandshakeComplete); - // - // Write any pending data to the socket. - // - flush(timeout); - - try + IceInternal.SocketStatus status; + do { - while(buf.hasRemaining()) + status = writeNonBlocking(buf.b); + if(status != IceInternal.SocketStatus.Finished) { - final int rem = buf.remaining(); - - // - // Encrypt the buffer. - // - SSLEngineResult result = _engine.wrap(buf, _netOutput); - switch(result.getStatus()) + if(timeout == 0) { - case BUFFER_OVERFLOW: - assert(false); - break; - case BUFFER_UNDERFLOW: - assert(false); - break; - case CLOSED: - throw new Ice.ConnectionLostException(); - case OK: - break; + assert(status == IceInternal.SocketStatus.NeedWrite); + return false; } - // - // Write the encrypted data to the socket. - // - if(result.bytesProduced() > 0) - { - flush(timeout); - - if(_instance.networkTraceLevel() >= 3) - { - String s = "sent " + result.bytesConsumed() + " of " + rem + " bytes via ssl\n" + toString(); - _logger.trace(_instance.networkTraceCategory(), s); - } - - if(_stats != null) - { - _stats.bytesSent(type(), result.bytesConsumed()); - } - } + handleSocketStatus(status, timeout); } - } - catch(SSLException ex) - { - Ice.SecurityException e = new Ice.SecurityException(); - e.reason = "IceSSL: error while encoding message"; - e.initCause(ex); - throw e; - } + } + while(status != IceInternal.SocketStatus.Finished); + + return true; } public boolean - read(IceInternal.BasicStream stream, int timeout) + read(IceInternal.Buffer buf, int timeout, Ice.BooleanHolder moreData) { - ByteBuffer buf = stream.prepareRead(); + assert(_state == StateHandshakeComplete); int rem = 0; if(_instance.networkTraceLevel() >= 3) { - rem = buf.remaining(); - } - - // - // Complete handshaking first if necessary. - // - if(!_handshakeComplete) - { - handshake(timeout); + rem = buf.b.remaining(); } // // Try to satisfy the request from data we've already decrypted. // - int pos = buf.position(); - fill(buf); + int pos = buf.b.position(); + fill(buf.b); - if(_instance.networkTraceLevel() >= 3 && buf.position() > pos) + if(_instance.networkTraceLevel() >= 3 && buf.b.position() > pos) { - String s = "received " + (buf.position() - pos) + " of " + rem + " bytes via ssl\n" + toString(); + String s = "received " + (buf.b.position() - pos) + " of " + rem + " bytes via ssl\n" + toString(); _logger.trace(_instance.networkTraceCategory(), s); } - if(_stats != null && buf.position() > pos) + if(_stats != null && buf.b.position() > pos) { - _stats.bytesReceived(type(), buf.position() - pos); + _stats.bytesReceived(type(), buf.b.position() - pos); } // @@ -293,7 +285,7 @@ final class TransceiverI implements IceInternal.Transceiver // try { - while(buf.hasRemaining()) + while(buf.b.hasRemaining()) { _netInput.flip(); SSLEngineResult result = _engine.unwrap(_netInput, _appInput); @@ -301,29 +293,53 @@ final class TransceiverI implements IceInternal.Transceiver switch(result.getStatus()) { case BUFFER_OVERFLOW: + { assert(false); break; + } case BUFFER_UNDERFLOW: - read(timeout); + { + IceInternal.SocketStatus status; + do + { + status = readNonBlocking(); + if(status != IceInternal.SocketStatus.Finished) + { + if(timeout == 0) + { + assert(status == IceInternal.SocketStatus.NeedRead); + moreData.value = false; + return false; + } + + handleSocketStatus(status, timeout); + } + } + while(status != IceInternal.SocketStatus.Finished); continue; + } case CLOSED: + { throw new Ice.ConnectionLostException(); + } case OK: + { break; } + } - pos = buf.position(); - fill(buf); + pos = buf.b.position(); + fill(buf.b); - if(_instance.networkTraceLevel() >= 3 && buf.position() > pos) + if(_instance.networkTraceLevel() >= 3 && buf.b.position() > pos) { - String s = "received " + (buf.position() - pos) + " of " + rem + " bytes via ssl\n" + toString(); + String s = "received " + (buf.b.position() - pos) + " of " + rem + " bytes via ssl\n" + toString(); _logger.trace(_instance.networkTraceCategory(), s); } - if(_stats != null && buf.position() > pos) + if(_stats != null && buf.b.position() > pos) { - _stats.bytesReceived(type(), buf.position() - pos); + _stats.bytesReceived(type(), buf.b.position() - pos); } } } @@ -338,7 +354,8 @@ final class TransceiverI implements IceInternal.Transceiver // // Return a boolean to indicate whether more data is available. // - return _netInput.position() > 0; + moreData.value = _netInput.position() > 0; + return true; } public String @@ -354,9 +371,9 @@ final class TransceiverI implements IceInternal.Transceiver } public void - checkSendSize(IceInternal.BasicStream stream, int messageSizeMax) + checkSendSize(IceInternal.Buffer buf, int messageSizeMax) { - if(stream.size() > messageSizeMax) + if(buf.size() > messageSizeMax) { throw new Ice.MemoryLimitException(); } @@ -376,7 +393,7 @@ final class TransceiverI implements IceInternal.Transceiver // Only for use by ConnectorI, AcceptorI. // TransceiverI(Instance instance, javax.net.ssl.SSLEngine engine, java.nio.channels.SocketChannel fd, - String host, boolean incoming, String adapterName) + String host, boolean connected, boolean incoming, String adapterName) { _instance = instance; _engine = engine; @@ -384,6 +401,7 @@ final class TransceiverI implements IceInternal.Transceiver _host = host; _adapterName = adapterName; _incoming = incoming; + _state = connected ? StateConnected : StateNeedConnect; _logger = instance.communicator().getLogger(); try { @@ -409,11 +427,9 @@ final class TransceiverI implements IceInternal.Transceiver } } - // TODO: Buffer cache? _appInput = ByteBuffer.allocateDirect(engine.getSession().getApplicationBufferSize() * 2); _netInput = ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize() * 2); _netOutput = ByteBuffer.allocateDirect(engine.getSession().getPacketBufferSize() * 2); - _handshakeComplete = false; } protected void @@ -425,185 +441,13 @@ final class TransceiverI implements IceInternal.Transceiver super.finalize(); } - private void - flush(int timeout) - { - _netOutput.flip(); - - int size = _netOutput.limit(); - int packetSize = 0; - if(_maxPacketSize > 0 && size > _maxPacketSize) - { - packetSize = _maxPacketSize; - _netOutput.limit(_netOutput.position() + packetSize); - } - - while(_netOutput.hasRemaining()) - { - try - { - assert(_fd != null); - int ret = _fd.write(_netOutput); - - if(ret == -1) - { - throw new Ice.ConnectionLostException(); - } - - if(ret == 0) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - - if(_writeSelector == null) - { - _writeSelector = java.nio.channels.Selector.open(); - _fd.register(_writeSelector, java.nio.channels.SelectionKey.OP_WRITE, null); - } - - try - { - if(timeout > 0) - { - long start = System.currentTimeMillis(); - int n = _writeSelector.select(timeout); - if(n == 0 && System.currentTimeMillis() >= start + timeout) - { - throw new Ice.TimeoutException(); - } - } - else - { - _writeSelector.select(); - } - } - catch(java.io.InterruptedIOException ex) - { - // Ignore. - } - - continue; - } - } - catch(java.io.InterruptedIOException ex) - { - continue; - } - catch(java.io.IOException ex) - { - if(IceInternal.Network.connectionLost(ex)) - { - Ice.ConnectionLostException se = new Ice.ConnectionLostException(); - se.initCause(ex); - throw se; - } - - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - - if(packetSize > 0) - { - assert(_netOutput.position() == _netOutput.limit()); - int position = _netOutput.position(); - if(size - position > packetSize) - { - _netOutput.limit(position + packetSize); - } - else - { - packetSize = 0; - _netOutput.limit(size); - } - } - } - _netOutput.clear(); - } - - private void - read(int timeout) - { - while(true) - { - try - { - assert(_fd != null); - int ret = _fd.read(_netInput); - - if(ret == -1) - { - throw new Ice.ConnectionLostException(); - } - - if(ret == 0) - { - if(timeout == 0) - { - throw new Ice.TimeoutException(); - } - - if(_readSelector == null) - { - _readSelector = java.nio.channels.Selector.open(); - _fd.register(_readSelector, java.nio.channels.SelectionKey.OP_READ, null); - } - - try - { - if(timeout > 0) - { - long start = System.currentTimeMillis(); - int n = _readSelector.select(timeout); - if(n == 0 && System.currentTimeMillis() >= start + timeout) - { - throw new Ice.TimeoutException(); - } - } - else - { - _readSelector.select(); - } - } - catch(java.io.InterruptedIOException ex) - { - // Ignore. - } - - continue; - } - - break; - } - catch(java.io.InterruptedIOException ex) - { - continue; - } - catch(java.io.IOException ex) - { - if(IceInternal.Network.connectionLost(ex)) - { - Ice.ConnectionLostException se = new Ice.ConnectionLostException(); - se.initCause(ex); - throw se; - } - - Ice.SocketException se = new Ice.SocketException(); - se.initCause(ex); - throw se; - } - } - } - - private void - handshake(int timeout) + private IceInternal.SocketStatus + handshakeNonBlocking() { try { HandshakeStatus status = _engine.getHandshakeStatus(); - while(!_handshakeComplete) + while(_state != StateHandshakeComplete) { SSLEngineResult result = null; switch(status) @@ -613,7 +457,6 @@ final class TransceiverI implements IceInternal.Transceiver break; case NEED_TASK: { - // TODO: Use separate threads & join with timeout? Runnable task; while((task = _engine.getDelegatedTask()) != null) { @@ -642,9 +485,15 @@ final class TransceiverI implements IceInternal.Transceiver assert(false); break; case BUFFER_UNDERFLOW: + { assert(status == javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_UNWRAP); - read(timeout); + IceInternal.SocketStatus ss = readNonBlocking(); + if(ss != IceInternal.SocketStatus.Finished) + { + return ss; + } break; + } case CLOSED: throw new Ice.ConnectionLostException(); case OK: @@ -660,7 +509,11 @@ final class TransceiverI implements IceInternal.Transceiver result = _engine.wrap(_emptyBuffer, _netOutput); if(result.bytesProduced() > 0) { - flush(timeout); + IceInternal.SocketStatus ss = flushNonBlocking(); + if(ss != IceInternal.SocketStatus.Finished) + { + return ss; + } } // // FINISHED is only returned from wrap or unwrap, not from engine.getHandshakeResult(). @@ -699,6 +552,314 @@ final class TransceiverI implements IceInternal.Transceiver e.initCause(ex); throw e; } + + return IceInternal.SocketStatus.Finished; + } + + private void + handshakeCompleted() + { + _state = StateHandshakeComplete; + + // + // IceSSL.VerifyPeer is translated into the proper SSLEngine configuration + // for a server, but we have to do it ourselves for a client. + // + if(!_incoming) + { + int verifyPeer = + _instance.communicator().getProperties().getPropertyAsIntWithDefault("IceSSL.VerifyPeer", 2); + if(verifyPeer > 0) + { + try + { + _engine.getSession().getPeerCertificates(); + } + catch(javax.net.ssl.SSLPeerUnverifiedException ex) + { + Ice.SecurityException e = new Ice.SecurityException(); + e.reason = "IceSSL: server did not supply a certificate"; + e.initCause(ex); + throw e; + } + } + } + + // + // Additional verification. + // + _info = Util.populateConnectionInfo(_engine.getSession(), _fd.socket(), _adapterName, _incoming); + _instance.verifyPeer(_info, _fd, _host, _incoming); + + if(_instance.networkTraceLevel() >= 1) + { + String s; + if(_incoming) + { + s = "accepted ssl connection\n" + _desc; + } + else + { + s = "ssl connection established\n" + _desc; + } + _logger.trace(_instance.networkTraceCategory(), s); + } + + if(_instance.securityTraceLevel() >= 1) + { + _instance.traceConnection(_fd, _engine, _incoming); + } + } + + private void + shutdown() + { + // + // Send the close_notify message. + // + _engine.closeOutbound(); + try + { + _netOutput.clear(); + while(!_engine.isOutboundDone()) + { + _engine.wrap(_emptyBuffer, _netOutput); + try + { + // + // We can't block to send the close_notify message as this is called from + // shutdownWrite and shutdownReadWrite which aren't suppose to block. In + // some cases, the close_notify message might therefore not be receieved + // by the peer. This is not a big issue since the Ice protocol isn't + // subject to truncation attacks. + // +// IceInternal.SocketStatus status; +// do +// { +// status = flushNonBlocking(); +// if(status != IceInternal.SocketStatus.Finished) +// { +// handleSocketStatus(status, -1); // TODO: Is waiting indefinitely really correct? +// } +// } +// while(status != IceInternal.SocketStatus.Finished); + flushNonBlocking(); + } + catch(Ice.ConnectionLostException ex) + { + // Ignore. + } + } + } + catch(SSLException ex) + { + Ice.SecurityException se = new Ice.SecurityException(); + se.reason = "IceSSL: SSL failure while shutting down socket"; + se.initCause(ex); + throw se; + } + } + + private IceInternal.SocketStatus + writeNonBlocking(ByteBuffer buf) + { + // + // This method has two purposes: encrypt the application's message buffer into our + // _netOutput buffer, and write the contents of _netOutput to the socket without + // blocking. + // + try + { + while(buf.hasRemaining() || _netOutput.position() > 0) + { + final int rem = buf.remaining(); + + if(rem > 0) + { + // + // Encrypt the buffer. + // + SSLEngineResult result = _engine.wrap(buf, _netOutput); + switch(result.getStatus()) + { + case BUFFER_OVERFLOW: + // + // Need to make room in _netOutput. + // + break; + case BUFFER_UNDERFLOW: + assert(false); + break; + case CLOSED: + throw new Ice.ConnectionLostException(); + case OK: + break; + } + + // + // If the SSL engine consumed any of the application's message buffer, + // then log it. + // + if(result.bytesConsumed() > 0) + { + if(_instance.networkTraceLevel() >= 3) + { + String s = "sent " + result.bytesConsumed() + " of " + rem + " bytes via ssl\n" + + toString(); + _logger.trace(_instance.networkTraceCategory(), s); + } + + if(_stats != null) + { + _stats.bytesSent(type(), result.bytesConsumed()); + } + } + } + + // + // Write the encrypted data to the socket. We continue writing until we've written + // all of _netOutput, or until flushNonBlocking indicates that it cannot write + // (i.e., by returning NeedWrite). + // + if(_netOutput.position() > 0) + { + IceInternal.SocketStatus ss = flushNonBlocking(); + if(ss != IceInternal.SocketStatus.Finished) + { + assert(ss == IceInternal.SocketStatus.NeedWrite); + return ss; + } + } + } + } + catch(SSLException ex) + { + Ice.SecurityException e = new Ice.SecurityException(); + e.reason = "IceSSL: error while encoding message"; + e.initCause(ex); + throw e; + } + + assert(_netOutput.position() == 0); + return IceInternal.SocketStatus.Finished; + } + + private IceInternal.SocketStatus + flushNonBlocking() + { + _netOutput.flip(); + + final int size = _netOutput.limit(); + int packetSize = size - _netOutput.position(); + if(_maxPacketSize > 0 && packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + _netOutput.limit(_netOutput.position() + packetSize); + } + + IceInternal.SocketStatus status = IceInternal.SocketStatus.Finished; + while(_netOutput.hasRemaining()) + { + try + { + assert(_fd != null); + int ret = _fd.write(_netOutput); + + if(ret == -1) + { + throw new Ice.ConnectionLostException(); + } + else if(ret == 0) + { + status = IceInternal.SocketStatus.NeedWrite; + break; + } + + if(packetSize == _maxPacketSize) + { + assert(_netOutput.position() == _netOutput.limit()); + packetSize = size - _netOutput.position(); + if(packetSize > _maxPacketSize) + { + packetSize = _maxPacketSize; + } + _netOutput.limit(_netOutput.position() + packetSize); + } + } + catch(java.io.InterruptedIOException ex) + { + continue; + } + catch(java.io.IOException ex) + { + if(IceInternal.Network.connectionLost(ex)) + { + Ice.ConnectionLostException se = new Ice.ConnectionLostException(); + se.initCause(ex); + throw se; + } + + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } + + if(status == IceInternal.SocketStatus.Finished) + { + _netOutput.clear(); + } + else + { + _netOutput.limit(size); + _netOutput.compact(); + } + + return status; + } + + + private IceInternal.SocketStatus + readNonBlocking() + { + while(true) + { + try + { + assert(_fd != null); + int ret = _fd.read(_netInput); + + if(ret == -1) + { + throw new Ice.ConnectionLostException(); + } + else if(ret == 0) + { + return IceInternal.SocketStatus.NeedRead; + } + + break; + } + catch(java.io.InterruptedIOException ex) + { + continue; + } + catch(java.io.IOException ex) + { + if(IceInternal.Network.connectionLost(ex)) + { + Ice.ConnectionLostException se = new Ice.ConnectionLostException(); + se.initCause(ex); + throw se; + } + + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; + } + } + + return IceInternal.SocketStatus.Finished; } private void @@ -747,89 +908,70 @@ final class TransceiverI implements IceInternal.Transceiver } private void - shutdown() + handleSocketStatus(IceInternal.SocketStatus status, int timeout) { - // - // Send the close_notify message. - // - _engine.closeOutbound(); + assert(timeout != 0); try { - _netOutput.clear(); - while(!_engine.isOutboundDone()) + java.nio.channels.Selector selector; + if(status == IceInternal.SocketStatus.NeedRead) { - _engine.wrap(_emptyBuffer, _netOutput); - try + if(_readSelector == null) { - flush(-1); + _readSelector = java.nio.channels.Selector.open(); + _fd.register(_readSelector, java.nio.channels.SelectionKey.OP_READ, null); } - catch(Ice.ConnectionLostException ex) + selector = _readSelector; + } + else + { + assert(status == IceInternal.SocketStatus.NeedWrite); + if(_writeSelector == null) { - // Ignore. + _writeSelector = java.nio.channels.Selector.open(); + _fd.register(_writeSelector, java.nio.channels.SelectionKey.OP_WRITE, null); } + selector = _writeSelector; } - } - catch(SSLException ex) - { - Ice.SecurityException se = new Ice.SecurityException(); - se.reason = "IceSSL: SSL failure while shutting down socket"; - se.initCause(ex); - throw se; - } - } - private void - handshakeCompleted() - { - _handshakeComplete = true; - - // - // IceSSL.VerifyPeer is translated into the proper SSLEngine configuration - // for a server, but we have to do it ourselves for a client. - // - if(!_incoming) - { - int verifyPeer = - _instance.communicator().getProperties().getPropertyAsIntWithDefault("IceSSL.VerifyPeer", 2); - if(verifyPeer > 0) + while(true) { try { - _engine.getSession().getPeerCertificates(); + if(timeout > 0) + { + long start = System.currentTimeMillis(); + int n = selector.select(timeout); + if(n == 0 && System.currentTimeMillis() >= start + timeout) + { + throw new Ice.TimeoutException(); + } + } + else + { + selector.select(); + } + + break; } - catch(javax.net.ssl.SSLPeerUnverifiedException ex) + catch(java.io.InterruptedIOException ex) { - Ice.SecurityException e = new Ice.SecurityException(); - e.reason = "IceSSL: server did not supply a certificate"; - e.initCause(ex); - throw e; + // Ignore. } } } - - // - // Additional verification. - // - _info = Util.populateConnectionInfo(_engine.getSession(), _fd.socket(), _adapterName, _incoming); - _instance.verifyPeer(_info, _fd, _host, _incoming); - - if(_instance.networkTraceLevel() >= 1) + catch(java.io.IOException ex) { - String s; - if(_incoming) - { - s = "accepted ssl connection\n" + IceInternal.Network.fdToString(_fd); - } - else + if(IceInternal.Network.connectionLost(ex)) { - s = "ssl connection established\n" + IceInternal.Network.fdToString(_fd); + Ice.ConnectionLostException se = new Ice.ConnectionLostException(); + se.initCause(ex); + throw se; } - _logger.trace(_instance.networkTraceCategory(), s); - } - if(_instance.securityTraceLevel() >= 1) - { - _instance.traceConnection(_fd, _engine, _incoming); + Ice.SocketException se = new Ice.SocketException(); + se.initCause(ex); + throw se; } } @@ -839,6 +981,7 @@ final class TransceiverI implements IceInternal.Transceiver private String _host; private String _adapterName; private boolean _incoming; + private int _state; private Ice.Logger _logger; private Ice.Stats _stats; private String _desc; @@ -847,8 +990,12 @@ final class TransceiverI implements IceInternal.Transceiver private ByteBuffer _netInput; // Holds encrypted data read from the socket. private ByteBuffer _netOutput; // Holds encrypted data to be written to the socket. private static ByteBuffer _emptyBuffer = ByteBuffer.allocate(0); // Used during handshaking. - private boolean _handshakeComplete; private java.nio.channels.Selector _readSelector; private java.nio.channels.Selector _writeSelector; private ConnectionInfo _info; + + private static final int StateNeedConnect = 0; + private static final int StateConnectPending = 1; + private static final int StateConnected = 2; + private static final int StateHandshakeComplete = 3; } diff --git a/java/test/Ice/background/Acceptor.java b/java/test/Ice/background/Acceptor.java new file mode 100644 index 00000000000..ba21d4f4bb9 --- /dev/null +++ b/java/test/Ice/background/Acceptor.java @@ -0,0 +1,61 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +class Acceptor implements IceInternal.Acceptor +{ + public java.nio.channels.ServerSocketChannel + fd() + { + return _acceptor.fd(); + } + + public void + close() + { + _acceptor.close(); + } + + public void + listen() + { + _acceptor.listen(); + } + + public IceInternal.Transceiver + accept(int timeout) + { + return new Transceiver(_acceptor.accept(timeout)); + } + + public void + connectToSelf() + { + _acceptor.connectToSelf(); + } + + public String + toString() + { + return _acceptor.toString(); + } + + Acceptor(IceInternal.Acceptor acceptor) + { + _acceptor = acceptor; + } + + protected synchronized void + finalize() + throws Throwable + { + super.finalize(); + } + + final private IceInternal.Acceptor _acceptor; +} diff --git a/java/test/Ice/background/AllTests.java b/java/test/Ice/background/AllTests.java new file mode 100644 index 00000000000..f9715df3a7e --- /dev/null +++ b/java/test/Ice/background/AllTests.java @@ -0,0 +1,1177 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +import Test.*; + +public class AllTests +{ + private static void + test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + private static class Callback + { + Callback() + { + _called = false; + } + + public synchronized boolean + check(boolean wait) + { + if(wait) + { + while(!_called) + { + try + { + wait(5000); + } + catch(InterruptedException ex) + { + continue; + } + + if(!_called) + { + return false; // Must be timeout. + } + } + + _called = false; + return true; + } + return _called; + } + + public synchronized void + called() + { + assert(!_called); + _called = true; + notify(); + } + + private boolean _called; + } + + static class OpThread extends Thread + { + OpThread(BackgroundPrx background) + { + _background = BackgroundPrxHelper.uncheckedCast(background.ice_oneway()); + start(); + } + + public void + run() + { + int count = 0; + while(true) + { + synchronized(this) + { + if(_destroyed) + { + return; + } + } + + try + { + if(++count == 10) // Don't blast the connection with only oneway's + { + count = 0; + _background.ice_twoway().ice_ping(); + } + _background.op(); + try + { + Thread.sleep(1); + } + catch(java.lang.InterruptedException ex) + { + } + } + catch(Ice.LocalException ex) + { + } + } + } + + public synchronized void + destroy() + { + _destroyed = true; + } + + private boolean _destroyed = false; + private BackgroundPrx _background = null; + } + + private static class OpAMICallback extends Test.AMI_Background_op + { + public void + ice_response() + { + callback.called(); + } + + public void + ice_exception(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + + public boolean + response(boolean wait) + { + return callback.check(wait); + } + + private Callback callback = new Callback(); + } + + private static class OpExAMICallback extends Test.AMI_Background_op + { + public void + ice_response() + { + test(false); + } + + public void + ice_exception(Ice.LocalException ex) + { + callback.called(); + } + + public boolean + exception(boolean wait) + { + return callback.check(wait); + } + + private Callback callback = new Callback(); + } + + private static class OpWithPayloadOnewayAMICallback extends Test.AMI_Background_opWithPayload + { + public void + ice_response() + { + test(false); + } + + public void + ice_exception(Ice.LocalException ex) + { + test(false); + } + } + + private static class FlushBatchRequestsCallback extends Ice.AMI_Object_ice_flushBatchRequests + { + public void + ice_exception(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + }; + + public static Test.BackgroundPrx + allTests(Ice.Communicator communicator, java.io.PrintStream out) + { + String sref = "background:default -p 12010 -t 10000"; + Ice.ObjectPrx obj = communicator.stringToProxy(sref); + test(obj != null); + + BackgroundPrx background = BackgroundPrxHelper.uncheckedCast(obj); + + sref = "backgroundController:tcp -p 12011 -t 10000"; + obj = communicator.stringToProxy(sref); + test(obj != null); + + BackgroundControllerPrx backgroundController = BackgroundControllerPrxHelper.uncheckedCast(obj); + + Configuration configuration = Configuration.getInstance(); + + System.out.print("testing connect... "); + System.out.flush(); + { + connectTests(configuration, background); + } + System.out.println("ok"); + + System.out.print("testing initialization... "); + System.out.flush(); + { + initializeTests(configuration, background, backgroundController); + } + System.out.println("ok"); + + System.out.print("testing connection validation... "); + System.out.flush(); + { + validationTests(configuration, background, backgroundController); + } + System.out.println("ok"); + + System.out.print("testing read/write... "); + System.out.flush(); + { + readWriteTests(configuration, background, backgroundController); + } + System.out.println("ok"); + + System.out.print("testing locator... "); + System.out.flush(); + { + Ice.LocatorPrx locator; + obj = communicator.stringToProxy("locator:default -p 12010 -t 500"); + locator = Ice.LocatorPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_locator(locator).ice_oneway(); + backgroundController.pauseCall("findAdapterById"); + try + { + obj.ice_ping(); + test(false); + } + catch(Ice.TimeoutException ex) + { + } + backgroundController.resumeCall("findAdapterById"); + + obj = communicator.stringToProxy("locator:default -p 12010 -t 10000"); + locator = Ice.LocatorPrxHelper.uncheckedCast(obj); + obj = obj.ice_locator(locator); + obj.ice_ping(); + + obj = communicator.stringToProxy("background@Test").ice_locator(locator); + BackgroundPrx bg = BackgroundPrxHelper.uncheckedCast(obj); + + backgroundController.pauseCall("findAdapterById"); + OpAMICallback cb = new OpAMICallback(); + bg.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + bg.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + backgroundController.resumeCall("findAdapterById"); + test(cb.response(true)); + test(cb2.response(true)); + } + System.out.println("ok"); + + System.out.print("testing router... "); + System.out.flush(); + { + Ice.RouterPrx router; + + obj = communicator.stringToProxy("router:default -p 12010 -t 500"); + router = Ice.RouterPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_router(router).ice_oneway(); + backgroundController.pauseCall("getClientProxy"); + try + { + obj.ice_ping(); + test(false); + } + catch(Ice.TimeoutException ex) + { + } + backgroundController.resumeCall("getClientProxy"); + + obj = communicator.stringToProxy("router:default -p 12010 -t 10000"); + router = Ice.RouterPrxHelper.uncheckedCast(obj); + obj = communicator.stringToProxy("background@Test").ice_router(router); + BackgroundPrx bg = BackgroundPrxHelper.uncheckedCast(obj); + test(bg.ice_getRouter() != null); + + backgroundController.pauseCall("getClientProxy"); + OpAMICallback cb = new OpAMICallback(); + bg.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + bg.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + backgroundController.resumeCall("getClientProxy"); + test(cb.response(true)); + test(cb2.response(true)); + } + System.out.println("ok"); + + return background; + } + + private static void + connectTests(Configuration configuration, Test.BackgroundPrx background) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + test(false); + } + background.ice_getConnection().close(false); + + OpExAMICallback cbEx = new OpExAMICallback(); + + try + { + configuration.connectorsException(new Ice.DNSException()); + background.op(); + test(false); + } + catch(Ice.DNSException ex) + { + configuration.connectorsException(null); + } + + configuration.connectorsException(new Ice.DNSException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectorsException(null); + + configuration.connectorsException(new Ice.DNSException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectorsException(null); + + try + { + configuration.connectException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.connectException(null); + } + + configuration.connectException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectException(null); + + configuration.connectException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.connectException(null); + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + test(false); + } + + configuration.connectException(new Ice.SocketException()); + background.ice_getCachedConnection().close(true); + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + configuration.connectException(null); + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + } + } + + thread1.destroy(); + thread2.destroy(); + + try + { + thread1.join(); + thread2.join(); + } + catch(InterruptedException e) + { + } + } + + private static void + initializeTests(Configuration configuration, Test.BackgroundPrx background, Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.initializeException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.initializeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + + configuration.initializeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedConnect); + background.op(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException ex) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + background.op(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + catch(Ice.LocalException ex) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + } + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + configuration.initializeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.initializeException(null); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + // + // Now run the same tests with the server side. + // + + try + { + ctl.initializeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.initializeException(false); + } + catch(Ice.SecurityException ex) + { + ctl.initializeException(false); + } + + try + { + ctl.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite.value()); + background.op(); + ctl.initializeSocketStatus(IceInternal.SocketStatus.Finished.value()); + } + catch(Ice.LocalException ex) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + ctl.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite.value()); + ctl.initializeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.initializeException(false); + ctl.initializeSocketStatus(IceInternal.SocketStatus.Finished.value()); + } + catch(Ice.SecurityException ex) + { + ctl.initializeException(false); + ctl.initializeSocketStatus(IceInternal.SocketStatus.Finished.value()); + } + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + test(false); + } + + configuration.initializeException(new Ice.SocketException()); + background.ice_getCachedConnection().close(true); + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + configuration.initializeException(null); + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + } + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + test(false); + } + + configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + background.ice_getCachedConnection().close(true); + background.ice_ping(); + configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + + ctl.initializeException(true); + background.ice_getCachedConnection().close(true); + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + ctl.initializeException(false); + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + } + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + ctl.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite.value()); + background.ice_getCachedConnection().close(true); + background.op(); + ctl.initializeSocketStatus(IceInternal.SocketStatus.Finished.value()); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + } + + thread1.destroy(); + thread2.destroy(); + + try + { + thread1.join(); + thread2.join(); + } + catch(InterruptedException e) + { + } + } + + private static void + validationTests(Configuration configuration, Test.BackgroundPrx background, Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the read() of connection validation to throw right away. + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.readException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + configuration.readException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + if(!background.ice_getCommunicator().getProperties().getProperty("Ice.Default.Protocol").equals("test-ssl")) + { + try + { + // Get the read() of the connection validation to return "would block" + configuration.readReady(false); + background.op(); + configuration.readReady(true); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the read() of the connection validation to return "would block" and then throw. + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.readException(null); + configuration.readReady(true); + } + + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + } + + ctl.holdAdapter(); // Hold to block in connection validation + OpAMICallback cb = new OpAMICallback(); + background.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + background.op_async(cb2); + test(!cb.response(false)); + test(!cb2.response(false)); + ctl.resumeAdapter(); + test(cb.response(true)); + test(cb2.response(true)); + + try + { + // Get the write() of connection validation to throw right away. + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.writeException(false); + } + + try + { + // Get the write() of the connection validation to return "would block" + ctl.writeReady(false); + background.op(); + ctl.writeReady(true); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + background.ice_getConnection().close(false); + + try + { + // Get the write() of the connection validation to return "would block" and then throw. + ctl.writeReady(false); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.writeException(false); + ctl.writeReady(true); + } + + + byte[] seq = new byte[512 * 1024]; + + BackgroundPrx backgroundBatchOneway = BackgroundPrxHelper.uncheckedCast(background.ice_batchOneway()); + + // + // First send small requests to test without auto-flushing. + // + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException ex) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests(); + + // + // Send bigger requests to test with auto-flushing. + // + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException ex) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests(); + + // + // Then try the same thing with async flush. + // + + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException ex) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + backgroundBatchOneway.op(); + ctl.resumeAdapter(); + backgroundBatchOneway.ice_flushBatchRequests_async(new FlushBatchRequestsCallback()); + backgroundBatchOneway.ice_getConnection().close(false); + + backgroundBatchOneway.ice_getConnection().close(false); + try + { + backgroundBatchOneway.ice_ping(); + test(false); + } + catch(Ice.CloseConnectionException ex) + { + } + ctl.holdAdapter(); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + backgroundBatchOneway.opWithPayload(seq); + ctl.resumeAdapter(); + FlushBatchRequestsCallback fcb = new FlushBatchRequestsCallback(); + backgroundBatchOneway.ice_flushBatchRequests_async(fcb); + // + // We can't close the connection before ensuring all the batches have been sent since + // with auto-flushing the close connection message might be sent once the first call + // opWithPayload is sent and before the flushBatchRequests (this would therefore result + // in the flush to report a CloseConnectionException). Instead we flush a second time + // with the same callback to wait for the first flush to complete. + // + //backgroundBatchOneway.ice_getConnection().close(false); + backgroundBatchOneway.ice_flushBatchRequests_async(fcb); + backgroundBatchOneway.ice_getConnection().close(false); + } + + private static void + readWriteTests(Configuration configuration, Test.BackgroundPrx background, Test.BackgroundControllerPrx ctl) + { + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + test(false); + } + + try + { + background.ice_ping(); + configuration.writeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.writeException(null); + } + + OpExAMICallback cbEx = new OpExAMICallback(); + + configuration.writeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + + configuration.writeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + + try + { + background.ice_ping(); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.readException(null); + } + + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + + try + { + background.ice_ping(); + configuration.writeReady(false); + background.op(); + configuration.writeReady(true); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + background.ice_ping(); + configuration.readReady(false); + background.op(); + configuration.readReady(true); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.writeReady(true); + configuration.writeException(null); + } + + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + configuration.writeReady(true); + + background.ice_ping(); + configuration.writeReady(false); + configuration.writeException(new Ice.SocketException()); + ((BackgroundPrx)background.ice_oneway()).op_async(cbEx); + test(cbEx.exception(true)); + configuration.writeException(null); + configuration.writeReady(true); + + try + { + background.ice_ping(); + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op(); + test(false); + } + catch(Ice.SocketException ex) + { + configuration.readException(null); + configuration.readReady(true); + } + + background.ice_ping(); + configuration.readReady(false); + configuration.readException(new Ice.SocketException()); + background.op_async(cbEx); + test(cbEx.exception(true)); + configuration.readException(null); + configuration.readReady(true); + + background.ice_ping(); // Establish the connection + + BackgroundPrx backgroundOneway = BackgroundPrxHelper.uncheckedCast(background.ice_oneway()); + test(backgroundOneway.ice_getConnection() == background.ice_getConnection()); + + ctl.holdAdapter(); // Hold to block in request send. + + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + OpAMICallback cb = new OpAMICallback(); + background.op_async(cb); + OpAMICallback cb2 = new OpAMICallback(); + background.op_async(cb2); + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + backgroundOneway.opWithPayload_async(new OpWithPayloadOnewayAMICallback(), new byte[512 * 1024]); + test(!cb.response(false)); + test(!cb2.response(false)); + ctl.resumeAdapter(); + test(cb.response(true)); + test(cb2.response(true)); + + try + { + background.ice_ping(); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.writeException(false); + } + + try + { + background.ice_ping(); + ctl.readException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.readException(false); + } + + try + { + background.ice_ping(); + ctl.writeReady(false); + background.op(); + ctl.writeReady(true); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + background.ice_ping(); + ctl.readReady(false); + background.op(); + ctl.readReady(true); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + background.ice_ping(); + ctl.writeReady(false); + ctl.writeException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.writeException(false); + ctl.writeReady(true); + } + + try + { + background.ice_ping(); + ctl.readReady(false); + ctl.readException(true); + background.op(); + test(false); + } + catch(Ice.ConnectionLostException ex) + { + ctl.readException(false); + ctl.readReady(true); + } + + OpThread thread1 = new OpThread(background); + OpThread thread2 = new OpThread(background); + + for(int i = 0; i < 5; i++) + { + try + { + background.ice_ping(); + } + catch(Ice.LocalException ex) + { + test(false); + } + + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + configuration.writeException(new Ice.SocketException()); + try + { + background.op(); + } + catch(Ice.LocalException ex) + { + } + configuration.writeException(null); + + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + + background.ice_ping(); + background.ice_getCachedConnection().close(true); + try + { + Thread.sleep(10); + } + catch(java.lang.InterruptedException ex) + { + } + + background.ice_getCachedConnection().close(true); + } + + thread1.destroy(); + thread2.destroy(); + + try + { + thread1.join(); + thread2.join(); + } + catch(InterruptedException e) + { + } + } +} diff --git a/java/test/Ice/background/BackgroundControllerI.java b/java/test/Ice/background/BackgroundControllerI.java new file mode 100644 index 00000000000..a5cbc4e7477 --- /dev/null +++ b/java/test/Ice/background/BackgroundControllerI.java @@ -0,0 +1,117 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +import Test.*; + +class BackgroundControllerI extends _BackgroundControllerDisp +{ + synchronized public void + pauseCall(String opName, Ice.Current current) + { + _pausedCalls.add(opName); + } + + synchronized public void + resumeCall(String opName, Ice.Current current) + { + _pausedCalls.remove(opName); + notifyAll(); + } + + synchronized public void + checkCallPause(Ice.Current current) + { + while(_pausedCalls.contains(current.operation)) + { + try + { + wait(); + break; + } + catch(java.lang.InterruptedException ex) + { + } + } + } + + public void + holdAdapter(Ice.Current current) + { + _adapter.hold(); + } + + public void + resumeAdapter(Ice.Current current) + { + _adapter.activate(); + } + + public void + initializeSocketStatus(int status, Ice.Current current) + { + switch(status) + { + case IceInternal.SocketStatus._Finished: + _configuration.initializeSocketStatus(IceInternal.SocketStatus.Finished); + break; + case IceInternal.SocketStatus._NeedConnect: + _configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedConnect); + break; + case IceInternal.SocketStatus._NeedRead: + _configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedRead); + break; + case IceInternal.SocketStatus._NeedWrite: + _configuration.initializeSocketStatus(IceInternal.SocketStatus.NeedWrite); + break; + default: + assert(false); + } + } + + public void + initializeException(boolean enable, Ice.Current current) + { + _configuration.initializeException(enable ? new Ice.SocketException() : null); + } + + public void + readReady(boolean enable, Ice.Current current) + { + _configuration.readReady(enable); + } + + public void + readException(boolean enable, Ice.Current current) + { + _configuration.readException(enable ? new Ice.SocketException() : null); + } + + public void + writeReady(boolean enable, Ice.Current current) + { + _configuration.writeReady(enable); + } + + public void + writeException(boolean enable, Ice.Current current) + { + _configuration.writeException(enable ? new Ice.SocketException() : null); + } + + public + BackgroundControllerI(Ice.ObjectAdapter adapter) + { + _adapter = adapter; + _configuration = Configuration.getInstance(); + } + + final private Ice.ObjectAdapter _adapter; + final private java.util.HashSet _pausedCalls = new java.util.HashSet(); + final private Configuration _configuration; +} diff --git a/java/test/Ice/background/BackgroundI.java b/java/test/Ice/background/BackgroundI.java new file mode 100644 index 00000000000..2c9005df3da --- /dev/null +++ b/java/test/Ice/background/BackgroundI.java @@ -0,0 +1,38 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +import Test.*; + +class BackgroundI extends _BackgroundDisp +{ + public void + op(Ice.Current current) + { + _controller.checkCallPause(current); + } + + public void + opWithPayload(byte[] seq, Ice.Current current) + { + _controller.checkCallPause(current); + } + + public void + shutdown(Ice.Current current) + { + current.adapter.getCommunicator().shutdown(); + } + + BackgroundI(BackgroundControllerI controller) + { + _controller = controller; + } + + private final BackgroundControllerI _controller; +} diff --git a/java/test/Ice/background/Client.java b/java/test/Ice/background/Client.java new file mode 100644 index 00000000000..15b71099467 --- /dev/null +++ b/java/test/Ice/background/Client.java @@ -0,0 +1,74 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +public class Client +{ + public static int + run(String[] args, Ice.Communicator communicator, java.io.PrintStream out) + { + Test.BackgroundPrx background = AllTests.allTests(communicator, out); + background.shutdown(); + return 0; + } + + public static void + main(String[] args) + { + int status = 0; + Ice.Communicator communicator = null; + + try + { + Ice.StringSeqHolder argsH = new Ice.StringSeqHolder(args); + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(argsH); + + // + // For this test, we want to disable retries. + // + initData.properties.setProperty("Ice.RetryIntervals", "-1"); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + initData.properties.setProperty("Ice.Plugin.Test", "PluginFactory"); + String defaultProtocol = initData.properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties.setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice.Util.initialize(argsH, initData); + status = run(argsH.value, communicator, System.out); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + status = 1; + } + + if(communicator != null) + { + try + { + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + status = 1; + } + } + + System.gc(); + System.exit(status); + } +} diff --git a/java/test/Ice/background/Configuration.java b/java/test/Ice/background/Configuration.java new file mode 100644 index 00000000000..192d99fc1f6 --- /dev/null +++ b/java/test/Ice/background/Configuration.java @@ -0,0 +1,161 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +public final class Configuration +{ + public synchronized void + connectorsException(Ice.LocalException ex) + { + _connectorsException = ex; + } + + public synchronized void + checkConnectorsException() + { + if(_connectorsException != null) + { + throw _connectorsException; + } + } + + public synchronized void + connectException(Ice.LocalException ex) + { + _connectException = ex; + } + + public synchronized void + checkConnectException() + { + if(_connectException != null) + { + throw _connectException; + } + } + + public synchronized void + initializeSocketStatus(IceInternal.SocketStatus status) + { + if(status == IceInternal.SocketStatus.Finished) + { + _initializeResetCount = 0; + return; + } + _initializeResetCount = 10; + _initializeSocketStatus = status; + } + + public synchronized void + initializeException(Ice.LocalException ex) + { + _initializeException = ex; + } + + public synchronized IceInternal.SocketStatus + initializeSocketStatus() + { + if(_initializeResetCount == 0) + { + return IceInternal.SocketStatus.Finished; + } + --_initializeResetCount; + return _initializeSocketStatus; + } + + public synchronized void + checkInitializeException() + { + if(_initializeException != null) + { + throw _initializeException; + } + } + + public synchronized void + readReady(boolean ready) + { + _readReadyCount = ready ? 0 : 10; + } + + public synchronized void + readException(Ice.LocalException ex) + { + _readException = ex; + } + + public synchronized boolean + readReady() + { + if(_readReadyCount == 0) + { + return true; + } + --_readReadyCount; + return false; + } + + public synchronized void + checkReadException() + { + if(_readException != null) + { + throw _readException; + } + } + + public synchronized void + writeReady(boolean ready) + { + _writeReadyCount = ready ? 0 : 10; + } + + public synchronized void + writeException(Ice.LocalException ex) + { + _writeException = ex; + } + + public synchronized boolean + writeReady() + { + if(_writeReadyCount == 0) + { + return true; + } + --_writeReadyCount; + return false; + } + + public synchronized void + checkWriteException() + { + if(_writeException != null) + { + throw _writeException; + } + } + + static public synchronized Configuration + getInstance() + { + return _instance; + } + + private Ice.LocalException _connectorsException; + private Ice.LocalException _connectException; + private IceInternal.SocketStatus _initializeSocketStatus; + private int _initializeResetCount; + private Ice.LocalException _initializeException; + private int _readReadyCount; + private Ice.LocalException _readException; + private int _writeReadyCount; + private Ice.LocalException _writeException; + + private final static Configuration _instance = new Configuration(); +} diff --git a/java/test/Ice/background/Connector.java b/java/test/Ice/background/Connector.java new file mode 100644 index 00000000000..0dccd087e44 --- /dev/null +++ b/java/test/Ice/background/Connector.java @@ -0,0 +1,94 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +final class Connector implements IceInternal.Connector, java.lang.Comparable +{ + public IceInternal.Transceiver + connect(int timeout) + { + _configuration.checkConnectException(); + return new Transceiver(_connector.connect(timeout)); + } + + public short + type() + { + return (short)(EndpointI.TYPE_BASE + _connector.type()); + } + + public String + toString() + { + return _connector.toString(); + } + + public int + hashCode() + { + return _connector.hashCode(); + } + + // + // Only for use by Endpoint + // + Connector(IceInternal.Connector connector) + { + _configuration = Configuration.getInstance(); + _connector = connector; + } + + // + // Compare connectors for sorting purposes + // + public boolean + equals(java.lang.Object obj) + { + return compareTo(obj) == 0; + } + + public int + compareTo(java.lang.Object obj) // From java.lang.Comparable + { + Connector p = null; + + try + { + p = (Connector)obj; + } + catch(ClassCastException ex) + { + try + { + IceInternal.Connector c = (IceInternal.Connector)obj; + return type() < c.type() ? -1 : 1; + } + catch(ClassCastException ee) + { + assert(false); + } + } + + if(this == p) + { + return 0; + } + + return _connector.compareTo(p._connector); + } + + protected synchronized void + finalize() + throws Throwable + { + super.finalize(); + } + + final private IceInternal.Connector _connector; + final private Configuration _configuration; +} diff --git a/java/test/Ice/background/EndpointFactory.java b/java/test/Ice/background/EndpointFactory.java new file mode 100644 index 00000000000..22683e84a7a --- /dev/null +++ b/java/test/Ice/background/EndpointFactory.java @@ -0,0 +1,48 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +final class EndpointFactory implements IceInternal.EndpointFactory +{ + EndpointFactory(IceInternal.EndpointFactory factory) + { + _factory = factory; + } + + public short + type() + { + return (short)(EndpointI.TYPE_BASE + _factory.type()); + } + + public String + protocol() + { + return "test-" + _factory.protocol(); + } + + public IceInternal.EndpointI + create(String str, boolean server) + { + return new EndpointI(_factory.create(str, server)); + } + + public IceInternal.EndpointI + read(IceInternal.BasicStream s) + { + s.readShort(); + return new EndpointI(_factory.read(s)); + } + + public void + destroy() + { + } + + private IceInternal.EndpointFactory _factory; +} diff --git a/java/test/Ice/background/EndpointI.java b/java/test/Ice/background/EndpointI.java new file mode 100644 index 00000000000..bb2cd6724ad --- /dev/null +++ b/java/test/Ice/background/EndpointI.java @@ -0,0 +1,322 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +final class EndpointI extends IceInternal.EndpointI +{ + final static short TYPE_BASE = 100; + + public + EndpointI(IceInternal.EndpointI endpoint) + { + _endpoint = endpoint; + _configuration = Configuration.getInstance(); + } + + // + // Marshal the endpoint + // + public void + streamWrite(IceInternal.BasicStream s) + { + s.writeShort(type()); + _endpoint.streamWrite(s); + } + + // + // Convert the endpoint to its string form + // + public String + _toString() + { + return "test-" + _endpoint.toString(); + } + + // + // Return the endpoint type + // + public short + type() + { + return (short)(TYPE_BASE + _endpoint.type()); + } + + // + // Return the timeout for the endpoint in milliseconds. 0 means + // non-blocking, -1 means no timeout. + // + public int + timeout() + { + return _endpoint.timeout(); + } + + // + // Return a new endpoint with a different timeout value, provided + // that timeouts are supported by the endpoint. Otherwise the same + // endpoint is returned. + // + public IceInternal.EndpointI + timeout(int timeout) + { + IceInternal.EndpointI endpoint = _endpoint.timeout(timeout); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return a new endpoint with a different connection id. + // + public IceInternal.EndpointI + connectionId(String connectionId) + { + IceInternal.EndpointI endpoint = _endpoint.connectionId(connectionId); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return true if the endpoints support bzip2 compress, or false + // otherwise. + // + public boolean + compress() + { + return _endpoint.compress(); + } + + // + // Return a new endpoint with a different compression value, + // provided that compression is supported by the + // endpoint. Otherwise the same endpoint is returned. + // + public IceInternal.EndpointI + compress(boolean compress) + { + IceInternal.EndpointI endpoint = _endpoint.compress(compress); + if(endpoint == _endpoint) + { + return this; + } + else + { + return new EndpointI(endpoint); + } + } + + // + // Return true if the endpoint is datagram-based. + // + public boolean + datagram() + { + return _endpoint.datagram(); + } + + // + // Return true if the endpoint is secure. + // + public boolean + secure() + { + return _endpoint.secure(); + } + + // + // Return true if the endpoint type is unknown. + // + public boolean + unknown() + { + return _endpoint.unknown(); + } + + // + // Return a server side transceiver for this endpoint, or null if a + // transceiver can only be created by an acceptor. In case a + // transceiver is created, this operation also returns a new + // "effective" endpoint, which might differ from this endpoint, + // for example, if a dynamic port number is assigned. + // + public IceInternal.Transceiver + transceiver(IceInternal.EndpointIHolder endpoint) + { + IceInternal.Transceiver transceiver = _endpoint.transceiver(endpoint); + if(endpoint.value == _endpoint) + { + endpoint.value = this; + } + else + { + endpoint.value = new EndpointI(endpoint.value); + } + + if(transceiver != null) + { + return new Transceiver(transceiver); + } + else + { + return null; + } + } + + // + // Return connectors for this endpoint, or empty list if no connector + // is available. + // + public java.util.List + connectors() + { + _configuration.checkConnectorsException(); + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = _endpoint.connectors().iterator(); + while(p.hasNext()) + { + connectors.add(new Connector((IceInternal.Connector)p.next())); + } + return connectors; + } + + public void + connectors_async(final IceInternal.EndpointI_connectors cb) + { + class Callback implements IceInternal.EndpointI_connectors + { + public void + connectors(java.util.List cons) + { + java.util.ArrayList connectors = new java.util.ArrayList(); + java.util.Iterator p = cons.iterator(); + while(p.hasNext()) + { + connectors.add(new Connector((IceInternal.Connector)p.next())); + } + cb.connectors(connectors); + } + + public void + exception(Ice.LocalException exception) + { + cb.exception(exception); + } + } + + try + { + _configuration.checkConnectorsException(); + _endpoint.connectors_async(new Callback()); + } + catch(Ice.LocalException ex) + { + cb.exception(ex); + } + } + + public IceInternal.Acceptor + acceptor(IceInternal.EndpointIHolder endpoint, String adapterName) + { + Acceptor p = new Acceptor(_endpoint.acceptor(endpoint, adapterName)); + endpoint.value = new EndpointI(endpoint.value); + return p; + } + + public java.util.List + expand() + { + java.util.ArrayList endps = new java.util.ArrayList(); + java.util.Iterator iter = _endpoint.expand().iterator(); + while(iter.hasNext()) + { + IceInternal.EndpointI endpt = (IceInternal.EndpointI)iter.next(); + endps.add(endpt == _endpoint ? this : new EndpointI(endpt)); + } + return endps; + } + + public boolean + equivalent(IceInternal.EndpointI endpoint) + { + EndpointI testEndpoint = null; + try + { + testEndpoint = (EndpointI)endpoint; + } + catch(ClassCastException ex) + { + return false; + } + return testEndpoint._endpoint.equivalent(_endpoint); + } + + public int + hashCode() + { + return _endpoint.hashCode(); + } + + // + // Compare endpoints for sorting purposes + // + public boolean + equals(java.lang.Object obj) + { + return compareTo(obj) == 0; + } + + public int + compareTo(java.lang.Object obj) // From java.lang.Comparable + { + EndpointI p = null; + + try + { + p = (EndpointI)obj; + } + catch(ClassCastException ex) + { + try + { + IceInternal.EndpointI e = (IceInternal.EndpointI)obj; + return type() < e.type() ? -1 : 1; + } + catch(ClassCastException ee) + { + assert(false); + } + } + + if(this == p) + { + return 0; + } + + return _endpoint.compareTo(p._endpoint); + } + + public boolean + requiresThreadPerConnection() + { + return _endpoint.requiresThreadPerConnection(); + } + + private IceInternal.EndpointI _endpoint; + private Configuration _configuration; +} diff --git a/java/test/Ice/background/PluginFactory.java b/java/test/Ice/background/PluginFactory.java new file mode 100644 index 00000000000..30d1bbfb290 --- /dev/null +++ b/java/test/Ice/background/PluginFactory.java @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +public class PluginFactory implements Ice.PluginFactory +{ + static class PluginI implements Ice.Plugin + { + public + PluginI(Ice.Communicator communicator) + { + _communicator = communicator; + } + + public void + initialize() + { + IceInternal.ProtocolPluginFacade facade = Ice.Util.getProtocolPluginFacade(_communicator); + for(short s = 0; s < 100; ++s) + { + IceInternal.EndpointFactory factory = facade.getEndpointFactory(s); + if(factory != null) + { + facade.addEndpointFactory(new EndpointFactory(factory)); + } + } + } + + public void + destroy() + { + } + + private final Ice.Communicator _communicator; + } + + public Ice.Plugin + create(Ice.Communicator communicator, String name, String[] args) + { + return new PluginI(communicator); + } +} diff --git a/java/test/Ice/background/Server.java b/java/test/Ice/background/Server.java new file mode 100644 index 00000000000..6075fabd271 --- /dev/null +++ b/java/test/Ice/background/Server.java @@ -0,0 +1,164 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +public class Server +{ + static public class LocatorI extends Ice._LocatorDisp + { + public void + findAdapterById_async(Ice.AMD_Locator_findAdapterById response, String adapter, Ice.Current current) + throws Ice.AdapterNotFoundException + { + _controller.checkCallPause(current); + Ice.Communicator communicator = current.adapter.getCommunicator(); + response.ice_response(current.adapter.createDirectProxy(communicator.stringToIdentity("dummy"))); + } + + public void + findObjectById_async(Ice.AMD_Locator_findObjectById response, Ice.Identity id, Ice.Current current) + throws Ice.ObjectNotFoundException + { + _controller.checkCallPause(current); + response.ice_response(current.adapter.createDirectProxy(id)); + } + + public Ice.LocatorRegistryPrx + getRegistry(Ice.Current current) + { + return null; + } + + LocatorI(BackgroundControllerI controller) + { + _controller = controller; + } + + final private BackgroundControllerI _controller; + } + + static public class RouterI extends Ice._RouterDisp + { + public Ice.ObjectPrx + getClientProxy(Ice.Current current) + { + _controller.checkCallPause(current); + return null; + } + + public Ice.ObjectPrx + getServerProxy(Ice.Current current) + { + _controller.checkCallPause(current); + return null; + } + + public void + addProxy(Ice.ObjectPrx proxy, Ice.Current current) + { + } + + public Ice.ObjectPrx[] + addProxies(Ice.ObjectPrx[] proxies, Ice.Current current) + { + return new Ice.ObjectPrx[0]; + } + + RouterI(BackgroundControllerI controller) + { + _controller = controller; + } + + final private BackgroundControllerI _controller; + } + + public static int + run(String[] args, Ice.Communicator communicator, java.io.PrintStream out) + { + // + // When running as a MIDlet the properties for the server may be + // overridden by configuration. If it isn't then we assume + // defaults. + // + if(communicator.getProperties().getProperty("TestAdapter.Endpoints").length() == 0) + { + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); + } + if(communicator.getProperties().getProperty("ControllerAdapter.Endpoints").length() == 0) + { + communicator.getProperties().setProperty("ControllerAdapter.Endpoints", "tcp -p 12011"); + communicator.getProperties().setProperty("ControllerAdapter.ThreadPool.Size", "1"); + } + + Ice.ObjectAdapter adapter = communicator.createObjectAdapter("TestAdapter"); + Ice.ObjectAdapter adapter2 = communicator.createObjectAdapter("ControllerAdapter"); + + BackgroundControllerI backgroundController = new BackgroundControllerI(adapter); + + adapter.add(new BackgroundI(backgroundController), communicator.stringToIdentity("background")); + adapter.add(new LocatorI(backgroundController), communicator.stringToIdentity("locator")); + adapter.add(new RouterI(backgroundController), communicator.stringToIdentity("router")); + adapter.activate(); + + adapter2.add(backgroundController, communicator.stringToIdentity("backgroundController")); + adapter2.activate(); + + communicator.waitForShutdown(); + return 0; + } + + public static void + main(String[] args) + { + int status = 0; + Ice.Communicator communicator = null; + + try + { + Ice.StringSeqHolder argsH = new Ice.StringSeqHolder(args); + Ice.InitializationData initData = new Ice.InitializationData(); + initData.properties = Ice.Util.createProperties(argsH); + + // + // This test kills connections, so we don't want warnings. + // + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + // + // Setup the test transport plugin. + // + initData.properties.setProperty("Ice.Plugin.Test", "PluginFactory"); + String defaultProtocol = initData.properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + initData.properties.setProperty("Ice.Default.Protocol", "test-" + defaultProtocol); + + communicator = Ice.Util.initialize(argsH, initData); + status = run(argsH.value, communicator, System.out); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + status = 1; + } + + if(communicator != null) + { + try + { + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + ex.printStackTrace(); + status = 1; + } + } + + System.gc(); + System.exit(status); + } +} diff --git a/java/test/Ice/background/Test.ice b/java/test/Ice/background/Test.ice new file mode 100644 index 00000000000..f85b9ac0065 --- /dev/null +++ b/java/test/Ice/background/Test.ice @@ -0,0 +1,46 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Background +{ + ["ami"] void op(); + ["ami"] void opWithPayload(Ice::ByteSeq seq); + + void shutdown(); +}; + +interface BackgroundController +{ + void pauseCall(string call); + void resumeCall(string call); + + void holdAdapter(); + void resumeAdapter(); + + void initializeSocketStatus(int status); + void initializeException(bool enable); + + void readReady(bool enable); + void readException(bool enable); + + void writeReady(bool enable); + void writeException(bool enable); +}; + +}; + +#endif diff --git a/java/test/Ice/background/Transceiver.java b/java/test/Ice/background/Transceiver.java new file mode 100644 index 00000000000..f8d6d3b5d3a --- /dev/null +++ b/java/test/Ice/background/Transceiver.java @@ -0,0 +1,153 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +final class Transceiver implements IceInternal.Transceiver +{ + public java.nio.channels.SelectableChannel + fd() + { + return _transceiver.fd(); + } + + public IceInternal.SocketStatus + initialize(int timeout) + { + if(timeout == 0) + { + IceInternal.SocketStatus status = _configuration.initializeSocketStatus(); + if(status == IceInternal.SocketStatus.NeedConnect) + { + return status; + } + else if(status == IceInternal.SocketStatus.NeedWrite) + { + if(!_initialized) + { + status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + _initialized = true; + } + return IceInternal.SocketStatus.NeedWrite; + } + else if(status == IceInternal.SocketStatus.NeedRead) + { + return status; + } + } + _configuration.checkInitializeException(); + if(!_initialized) + { + IceInternal.SocketStatus status = _transceiver.initialize(timeout); + if(status != IceInternal.SocketStatus.Finished) + { + return status; + } + _initialized = true; + } + return IceInternal.SocketStatus.Finished; + } + + public void + close() + { + _transceiver.close(); + } + + public void + shutdownWrite() + { + _transceiver.shutdownWrite(); + } + + public void + shutdownReadWrite() + { + _transceiver.shutdownReadWrite(); + } + + public boolean + write(IceInternal.Buffer buf, int timeout) + throws IceInternal.LocalExceptionWrapper + { + if(!_initialized) + { + throw new Ice.SocketException(); + } + + if(timeout == 0) + { + if(!_configuration.writeReady()) + { + return false; + } + } + _configuration.checkWriteException(); + return _transceiver.write(buf, timeout); + } + + public boolean + read(IceInternal.Buffer buf, int timeout, Ice.BooleanHolder moreData) + { + if(!_initialized) + { + throw new Ice.SocketException(); + } + + if(timeout == 0 && !moreData.value) + { + if(!_configuration.readReady()) + { + return false; + } + } + _configuration.checkReadException(); + return _transceiver.read(buf, timeout, moreData); + } + + public String + type() + { + return "test-" + _transceiver.type(); + } + + public String + toString() + { + return _transceiver.toString(); + } + + public void + checkSendSize(IceInternal.Buffer buf, int messageSizeMax) + { + _transceiver.checkSendSize(buf, messageSizeMax); + } + + // + // Only for use by Connector, Acceptor + // + Transceiver(IceInternal.Transceiver transceiver) + { + _transceiver = transceiver; + _configuration = Configuration.getInstance(); + } + + protected synchronized void + finalize() + throws Throwable + { + super.finalize(); + } + + final private IceInternal.Transceiver _transceiver; + final private Configuration _configuration; + private boolean _initialized = false; +} diff --git a/java/test/Ice/background/build.xml b/java/test/Ice/background/build.xml new file mode 100644 index 00000000000..6ddf33d84b7 --- /dev/null +++ b/java/test/Ice/background/build.xml @@ -0,0 +1,51 @@ +<!-- + ********************************************************************** + + Copyright (c) 2003-2007 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. + + ********************************************************************** +--> + +<project name="test_Ice_background" default="all" basedir="."> + + <!-- set global properties for this build --> + <property name="top.dir" value="../../.."/> + + <!-- import common definitions --> + <import file="${top.dir}/config/common.xml"/> + + <target name="generate" depends="init"> + <!-- Create the output directory for generated code --> + <mkdir dir="${generated.dir}"/> + <slice2java outputdir="${generated.dir}"> + <meta value="${java2metadata}"/> + <fileset dir="." includes="Test.ice"/> + <includepath> + <pathelement path="${slice.dir}" /> + </includepath> + </slice2java> + </target> + + <target name="compile" depends="generate"> + <mkdir dir="${class.dir}"/> + <javac srcdir="${generated.dir}" destdir="${class.dir}" + source="${jdk.version}" classpath="${lib.dir}" debug="${debug}"> + <compilerarg value="${javac.lint}" compiler="${javac.lint.compiler}"/> + </javac> + <javac srcdir="." destdir="${class.dir}" source="${jdk.version}" + classpath="${lib.dir}" excludes="generated/**" debug="${debug}"> + <compilerarg value="${javac.lint}" compiler="${javac.lint.compiler}"/> + </javac> + </target> + + <target name="all" depends="compile"/> + + <target name="clean"> + <delete dir="${generated.dir}"/> + <delete dir="${class.dir}"/> + </target> + +</project> diff --git a/java/test/Ice/background/run.py b/java/test/Ice/background/run.py new file mode 100755 index 00000000000..e66e382b56b --- /dev/null +++ b/java/test/Ice/background/run.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2007 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. +# +# ********************************************************************** + +import os, sys + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "config", "TestUtil.py")): + break +else: + raise "can't find toplevel directory!" + +sys.path.append(os.path.join(toplevel, "config")) +import TestUtil + +name = os.path.join("Ice", "background") +testdir = os.path.dirname(os.path.abspath(__file__)) + +classpath = os.getenv("CLASSPATH", "") +os.environ["CLASSPATH"] = os.path.join(testdir, "classes") + os.pathsep + classpath +TestUtil.clientServerTest(name) +sys.exit(0) diff --git a/java/test/Ice/build.xml b/java/test/Ice/build.xml index 25a4e4b71a9..285e8f00a03 100644 --- a/java/test/Ice/build.xml +++ b/java/test/Ice/build.xml @@ -13,6 +13,7 @@ <target name="all"> <ant dir="adapterDeactivation"/> + <ant dir="background"/> <ant dir="binding"/> <ant dir="exceptions"/> <ant dir="exceptionsAMD"/> @@ -42,6 +43,7 @@ <target name="clean"> <ant dir="adapterDeactivation" target="clean"/> + <ant dir="background" target="clean"/> <ant dir="binding" target="clean"/> <ant dir="exceptions" target="clean"/> <ant dir="exceptionsAMD" target="clean"/> diff --git a/java/test/Ice/location/Client.java b/java/test/Ice/location/Client.java index 956ba1c726f..074cb63d2bb 100644 --- a/java/test/Ice/location/Client.java +++ b/java/test/Ice/location/Client.java @@ -30,7 +30,7 @@ public class Client communicator = Ice.Util.initialize(args, initData); status = run(args, communicator); } - catch (Ice.LocalException ex) + catch(Exception ex) { ex.printStackTrace(); status = 1; diff --git a/java/test/Ice/location/Server.java b/java/test/Ice/location/Server.java index ab2ef85f018..486d081e332 100644 --- a/java/test/Ice/location/Server.java +++ b/java/test/Ice/location/Server.java @@ -19,6 +19,7 @@ public class Server // Ice.Properties properties = communicator.getProperties(); properties.setProperty("Ice.ThreadPool.Server.Size", "2"); + properties.setProperty("Ice.ThreadPool.Server.SizeWarn", "0"); properties.setProperty("ServerManagerAdapter.Endpoints", "default -p 12010 -t 30000:udp"); Ice.ObjectAdapter adapter = communicator.createObjectAdapter("ServerManagerAdapter"); diff --git a/java/test/Ice/operations/AllTests.java b/java/test/Ice/operations/AllTests.java index f72b6b831a7..71be3c760d8 100644 --- a/java/test/Ice/operations/AllTests.java +++ b/java/test/Ice/operations/AllTests.java @@ -24,6 +24,11 @@ public class AllTests derived.opDerived(); System.out.println("ok"); + System.out.print("testing oneway operations... "); + System.out.flush(); + Oneways.oneways(communicator, cl); + System.out.println("ok"); + if(!collocated) { System.out.print("testing twoway operations with AMI... "); @@ -32,6 +37,11 @@ public class AllTests TwowaysAMI.twowaysAMI(communicator, derived); System.out.println("ok"); + System.out.print("testing oneway operations with AMI... "); + System.out.flush(); + OnewaysAMI.onewaysAMI(communicator, cl); + System.out.println("ok"); + System.out.print("testing batch oneway operations... "); System.out.flush(); BatchOneways.batchOneways(cl); diff --git a/java/test/Ice/operations/Oneways.java b/java/test/Ice/operations/Oneways.java new file mode 100644 index 00000000000..c1a59c11355 --- /dev/null +++ b/java/test/Ice/operations/Oneways.java @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +class Oneways +{ + private static void + test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + static void + oneways(Ice.Communicator communicator, Test.MyClassPrx p) + { + p = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + + { + p.opVoid(); + } + + { + + Ice.ByteHolder b = new Ice.ByteHolder(); + byte r; + try + { + r = p.opByte((byte)0xff, (byte)0x0f, b); + test(false); + } + catch(Ice.TwowayOnlyException ex) + { + } + } + } +}
\ No newline at end of file diff --git a/java/test/Ice/operations/OnewaysAMI.java b/java/test/Ice/operations/OnewaysAMI.java new file mode 100644 index 00000000000..f50b003375f --- /dev/null +++ b/java/test/Ice/operations/OnewaysAMI.java @@ -0,0 +1,161 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 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. +// +// ********************************************************************** + +class OnewaysAMI +{ + private static void + test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + private static class Callback + { + Callback() + { + _called = false; + } + + public synchronized boolean + check() + { + while(!_called) + { + try + { + wait(5000); + } + catch(InterruptedException ex) + { + continue; + } + + if(!_called) + { + return false; // Must be timeout. + } + } + + _called = false; + return true; + } + + public synchronized void + called() + { + assert(!_called); + _called = true; + notify(); + } + + private boolean _called; + } + + private static class AMI_MyClass_opVoidI extends Test.AMI_MyClass_opVoid + { + public void + ice_response() + { + test(false); + } + + public void + ice_exception(Ice.LocalException ex) + { + test(false); + } + } + + private static class AMI_MyClass_opVoidExI extends Test.AMI_MyClass_opVoid + { + public void + ice_response() + { + test(false); + } + + public void + ice_exception(Ice.LocalException ex) + { + test(ex instanceof Ice.NoEndpointException); + callback.called(); + } + + public boolean + check() + { + return callback.check(); + } + + private Callback callback = new Callback(); + } + + private static class AMI_MyClass_opByteExI extends Test.AMI_MyClass_opByte + { + public void + ice_response(byte r, byte b) + { + test(false); + } + + public void + ice_exception(Ice.LocalException ex) + { + test(ex instanceof Ice.TwowayOnlyException); + callback.called(); + } + + public boolean + check() + { + return callback.check(); + } + + private Callback callback = new Callback(); + } + + static void + onewaysAMI(Ice.Communicator communicator, Test.MyClassPrx p) + { + p = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + + { + AMI_MyClass_opVoidI cb = new AMI_MyClass_opVoidI(); + p.opVoid_async(cb); + // Let's check if we can reuse the same callback object for another call. + p.opVoid_async(cb); + } + + { + // Check that a call to a void operation raises NoEndpointException + // in the ice_exception() callback instead of at the point of call. + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); + AMI_MyClass_opVoidExI cb = new AMI_MyClass_opVoidExI(); + try + { + indirect.opVoid_async(cb); + } + catch(java.lang.Exception ex) + { + test(false); + } + test(cb.check()); + } + + { + AMI_MyClass_opByteExI cb = new AMI_MyClass_opByteExI(); + p.opByte_async(cb, (byte)0xff, (byte)0x0f); + test(cb.check()); + } + + } +}
\ No newline at end of file diff --git a/java/test/Ice/operations/TwowaysAMI.java b/java/test/Ice/operations/TwowaysAMI.java index 650ba513b83..9ed12f6878a 100644 --- a/java/test/Ice/operations/TwowaysAMI.java +++ b/java/test/Ice/operations/TwowaysAMI.java @@ -94,7 +94,7 @@ class TwowaysAMI public void ice_exception(Ice.LocalException ex) { - test(ex instanceof Ice.TwowayOnlyException); + test(ex instanceof Ice.NoEndpointException); callback.called(); } @@ -143,7 +143,7 @@ class TwowaysAMI public void ice_exception(Ice.LocalException ex) { - test(ex instanceof Ice.TwowayOnlyException); + test(ex instanceof Ice.NoEndpointException); callback.called(); } @@ -1078,13 +1078,13 @@ class TwowaysAMI twowaysAMI(Ice.Communicator communicator, Test.MyClassPrx p) { { - // Check that a call to a void operation raises TwowayOnlyException + // Check that a call to a void operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test.MyClassPrx oneway = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); AMI_MyClass_opVoidExI cb = new AMI_MyClass_opVoidExI(); try { - oneway.opVoid_async(cb); + indirect.opVoid_async(cb); } catch(java.lang.Exception ex) { @@ -1094,13 +1094,13 @@ class TwowaysAMI } { - // Check that a call to a twoway operation raises TwowayOnlyException + // Check that a call to a twoway operation raises NoEndpointException // in the ice_exception() callback instead of at the point of call. - Test.MyClassPrx oneway = Test.MyClassPrxHelper.uncheckedCast(p.ice_oneway()); + Test.MyClassPrx indirect = Test.MyClassPrxHelper.uncheckedCast(p.ice_adapterId("dummy")); AMI_MyClass_opByteExI cb = new AMI_MyClass_opByteExI(); try { - oneway.opByte_async(cb, (byte)0, (byte)0); + indirect.opByte_async(cb, (byte)0, (byte)0); } catch(java.lang.Exception ex) { diff --git a/java/test/Ice/timeout/AllTests.java b/java/test/Ice/timeout/AllTests.java index 146c0da600d..13e57260870 100644 --- a/java/test/Ice/timeout/AllTests.java +++ b/java/test/Ice/timeout/AllTests.java @@ -266,7 +266,7 @@ public class AllTests to.holdAdapter(500); try { - byte[] seq = new byte[100000]; + byte[] seq = new byte[512 * 1024]; to.sendData(seq); } catch(Ice.TimeoutException ex) @@ -313,7 +313,7 @@ public class AllTests // TimeoutPrx to = TimeoutPrxHelper.uncheckedCast(obj.ice_timeout(500)); to.holdAdapter(2000); - byte[] seq = new byte[100000]; + byte[] seq = new byte[512 * 1024]; AMISendDataEx cb = new AMISendDataEx(); to.sendData_async(cb, seq); test(cb.check()); @@ -325,7 +325,7 @@ public class AllTests timeout.op(); // Ensure adapter is active. TimeoutPrx to = TimeoutPrxHelper.uncheckedCast(obj.ice_timeout(1500)); to.holdAdapter(500); - byte[] seq = new byte[100000]; + byte[] seq = new byte[512 * 1024]; AMISendData cb = new AMISendData(); to.sendData_async(cb, seq); test(cb.check()); diff --git a/java/test/Ice/timeout/Client.java b/java/test/Ice/timeout/Client.java index 3fcec904a74..4c2fea2cba2 100644 --- a/java/test/Ice/timeout/Client.java +++ b/java/test/Ice/timeout/Client.java @@ -39,11 +39,6 @@ public class Client // initData.properties.setProperty("Ice.Warn.Connections", "0"); - // - // Check for AMI timeouts every second. - // - initData.properties.setProperty("Ice.MonitorConnections", "1"); - communicator = Ice.Util.initialize(argsH, initData); status = run(argsH.value, communicator, System.out); } diff --git a/slice/Glacier2/PermissionsVerifier.ice b/slice/Glacier2/PermissionsVerifier.ice index 256363f1be5..09390b999e2 100644 --- a/slice/Glacier2/PermissionsVerifier.ice +++ b/slice/Glacier2/PermissionsVerifier.ice @@ -38,7 +38,8 @@ interface PermissionsVerifier * @return True if access is granted, or false otherwise. * **/ - ["nonmutating", "cpp:const"] idempotent bool checkPermissions(string userId, string password, out string reason); + ["ami", "nonmutating", "cpp:const"] idempotent bool checkPermissions(string userId, string password, + out string reason); }; /** @@ -64,7 +65,7 @@ interface SSLPermissionsVerifier * @see SSLInfo * **/ - ["nonmutating", "cpp:const"] idempotent bool authorize(SSLInfo info, out string reason); + ["ami", "nonmutating", "cpp:const"] idempotent bool authorize(SSLInfo info, out string reason); }; }; diff --git a/slice/Glacier2/Router.ice b/slice/Glacier2/Router.ice index dc94a93a216..1fdfece168e 100644 --- a/slice/Glacier2/Router.ice +++ b/slice/Glacier2/Router.ice @@ -107,7 +107,7 @@ interface Router extends Ice::Router * cannot be created. * **/ - Session* createSession(string userId, string password) + ["amd"] Session* createSession(string userId, string password) throws PermissionDeniedException, CannotCreateSessionException; /** @@ -139,7 +139,7 @@ interface Router extends Ice::Router * cannot be created. * **/ - Session* createSessionFromSecureConnection() + ["amd"] Session* createSessionFromSecureConnection() throws PermissionDeniedException, CannotCreateSessionException; /** diff --git a/slice/Glacier2/Session.ice b/slice/Glacier2/Session.ice index d8c725a99e4..58ef26a05fe 100644 --- a/slice/Glacier2/Session.ice +++ b/slice/Glacier2/Session.ice @@ -55,7 +55,7 @@ interface Session * [Router] is destroyed. * **/ - void destroy(); + ["ami"] void destroy(); }; /** @@ -228,7 +228,7 @@ interface SessionManager * cannot be created. * **/ - Session* create(string userId, SessionControl* control) + ["ami"] Session* create(string userId, SessionControl* control) throws CannotCreateSessionException; }; @@ -260,7 +260,7 @@ interface SSLSessionManager * cannot be created. * **/ - Session* create(SSLInfo info, SessionControl* control) + ["ami"] Session* create(SSLInfo info, SessionControl* control) throws CannotCreateSessionException; }; diff --git a/slice/Ice/Locator.ice b/slice/Ice/Locator.ice index e8b1d4063ff..55fd66edef5 100644 --- a/slice/Ice/Locator.ice +++ b/slice/Ice/Locator.ice @@ -91,7 +91,7 @@ interface Locator * be found. * **/ - ["amd", "nonmutating", "cpp:const"] idempotent Object* findObjectById(Ice::Identity id) + ["ami", "amd", "nonmutating", "cpp:const"] idempotent Object* findObjectById(Ice::Identity id) throws ObjectNotFoundException; /** @@ -107,7 +107,7 @@ interface Locator * found. * **/ - ["amd", "nonmutating", "cpp:const"] idempotent Object* findAdapterById(string id) + ["ami", "amd", "nonmutating", "cpp:const"] idempotent Object* findAdapterById(string id) throws AdapterNotFoundException; /** diff --git a/slice/Ice/Router.ice b/slice/Ice/Router.ice index 09e1ba2dae3..4d2895a4894 100644 --- a/slice/Ice/Router.ice +++ b/slice/Ice/Router.ice @@ -32,7 +32,7 @@ interface Router * @return The router's client proxy. * **/ - ["nonmutating", "cpp:const"] idempotent Object* getClientProxy(); + ["ami", "nonmutating", "cpp:const"] idempotent Object* getClientProxy(); /** * @@ -66,7 +66,7 @@ interface Router * @return Proxies discarded by the router. * **/ - idempotent ObjectProxySeq addProxies(ObjectProxySeq proxies); + ["ami"] idempotent ObjectProxySeq addProxies(ObjectProxySeq proxies); }; }; |