diff options
author | Benoit Foucher <benoit@zeroc.com> | 2014-10-22 16:33:13 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2014-10-22 16:33:13 +0200 |
commit | d8da15a2d803da81b76568d0c8f620f8ed26d0fa (patch) | |
tree | f193067905624d61e0e8a3e6cd7d2498b9bf1873 /cpp/src | |
parent | Fixed demo dist to allow gradle build of java demos (diff) | |
download | ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.tar.bz2 ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.tar.xz ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.zip |
Fixed ICE-3490: guarantee invocation serialization for proxies which are equal
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/CollocatedRequestHandler.cpp | 2 | ||||
-rw-r--r-- | cpp/src/Ice/CollocatedRequestHandler.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectRequestHandler.cpp | 72 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectRequestHandler.h | 6 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectionRequestHandler.cpp | 16 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectionRequestHandler.h | 3 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.cpp | 21 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.h | 5 | ||||
-rw-r--r-- | cpp/src/Ice/Makefile | 1 | ||||
-rw-r--r-- | cpp/src/Ice/Makefile.mak | 1 | ||||
-rw-r--r-- | cpp/src/Ice/OutgoingAsync.cpp | 5 | ||||
-rw-r--r-- | cpp/src/Ice/Proxy.cpp | 25 | ||||
-rw-r--r-- | cpp/src/Ice/RequestHandler.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/RequestHandlerFactory.cpp | 71 | ||||
-rw-r--r-- | cpp/src/Ice/RequestHandlerFactory.h | 41 | ||||
-rw-r--r-- | cpp/src/Ice/Selector.cpp | 22 | ||||
-rw-r--r-- | cpp/src/Ice/winrt/Makefile.mak | 1 |
17 files changed, 219 insertions, 77 deletions
diff --git a/cpp/src/Ice/CollocatedRequestHandler.cpp b/cpp/src/Ice/CollocatedRequestHandler.cpp index f97fadf6c02..543a1b50153 100644 --- a/cpp/src/Ice/CollocatedRequestHandler.cpp +++ b/cpp/src/Ice/CollocatedRequestHandler.cpp @@ -153,7 +153,7 @@ CollocatedRequestHandler::~CollocatedRequestHandler() } RequestHandlerPtr -CollocatedRequestHandler::connect() +CollocatedRequestHandler::connect(const Ice::ObjectPrx&) { return this; } diff --git a/cpp/src/Ice/CollocatedRequestHandler.h b/cpp/src/Ice/CollocatedRequestHandler.h index 3930c12ce1c..8561ba6eb2e 100644 --- a/cpp/src/Ice/CollocatedRequestHandler.h +++ b/cpp/src/Ice/CollocatedRequestHandler.h @@ -43,7 +43,7 @@ public: CollocatedRequestHandler(const ReferencePtr&, const Ice::ObjectAdapterPtr&); virtual ~CollocatedRequestHandler(); - virtual RequestHandlerPtr connect(); + virtual RequestHandlerPtr connect(const Ice::ObjectPrx&); virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); virtual void prepareBatchRequest(BasicStream*); diff --git a/cpp/src/Ice/ConnectRequestHandler.cpp b/cpp/src/Ice/ConnectRequestHandler.cpp index a1458484a57..55f1c508d5a 100644 --- a/cpp/src/Ice/ConnectRequestHandler.cpp +++ b/cpp/src/Ice/ConnectRequestHandler.cpp @@ -9,6 +9,7 @@ #include <Ice/ConnectRequestHandler.h> #include <Ice/ConnectionRequestHandler.h> +#include <Ice/RequestHandlerFactory.h> #include <Ice/Instance.h> #include <Ice/Proxy.h> #include <Ice/ConnectionI.h> @@ -31,8 +32,7 @@ ConnectRequestHandler::ConnectRequestHandler(const ReferencePtr& ref, const Ice: _flushing(false), _batchRequestInProgress(false), _batchRequestsSize(sizeof(requestBatchHdr)), - _batchStream(ref->getInstance().get(), Ice::currentProtocolEncoding, _batchAutoFlush), - _updateRequestHandler(false) + _batchStream(ref->getInstance().get(), Ice::currentProtocolEncoding, _batchAutoFlush) { } @@ -41,17 +41,23 @@ ConnectRequestHandler::~ConnectRequestHandler() } RequestHandlerPtr -ConnectRequestHandler::connect() +ConnectRequestHandler::connect(const Ice::ObjectPrx& proxy) { - Ice::ObjectPrx proxy = _proxy; - try + // + // Initiate the connection if connect() is called by the proxy that + // created the handler. + // + if(proxy.get() == _proxy.get()) { _reference->getConnection(this); + } + try + { Lock sync(*this); if(!initialized()) { - _updateRequestHandler = true; // The proxy request handler will be updated when the connection is set. + _proxies.push_back(proxy); return this; } } @@ -61,11 +67,15 @@ ConnectRequestHandler::connect() throw; } - assert(_connection); - - RequestHandlerPtr handler = new ConnectionRequestHandler(_reference, _connection, _compress); - proxy->__setRequestHandler(this, handler); - return handler; + if(_connectionRequestHandler) + { + proxy->__setRequestHandler(this, _connectionRequestHandler); + return _connectionRequestHandler; + } + else + { + return this; + } } RequestHandlerPtr @@ -335,15 +345,19 @@ ConnectRequestHandler::setException(const Ice::LocalException& ex) Lock sync(*this); assert(!_initialized && !_exception.get()); _exception.reset(ex.ice_clone()); + _proxies.clear(); _proxy = 0; // Break cyclic reference count. - // - // If some requests were queued, we notify them of the failure. This is done from a thread - // from the client thread pool since this will result in ice_exception callbacks to be - // called. - // flushRequestsWithException(); + try + { + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, this); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } notifyAll(); } @@ -467,15 +481,18 @@ ConnectRequestHandler::flushRequests() } // - // We've finished sending the queued requests and the request handler now sends - // the requests over the connection directly. It's time to substitute the - // request handler of the proxy with the more efficient connection request - // handler which does not have any synchronization. This also breaks the cyclic - // reference count with the proxy. + // If we aren't caching the connection, don't bother creating a + // connection request handler. Otherwise, update the proxies + // request handler to use the more efficient connection request + // handler. // - if(_updateRequestHandler && !_exception.get()) + if(_reference->getCacheConnection() && !_exception.get()) { - _proxy->__setRequestHandler(this, new ConnectionRequestHandler(_reference, _connection, _compress)); + _connectionRequestHandler = new ConnectionRequestHandler(_reference, _connection, _compress); + for(vector<Ice::ObjectPrx>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + { + (*p)->__setRequestHandler(this, _connectionRequestHandler); + } } { @@ -486,6 +503,15 @@ ConnectRequestHandler::flushRequests() _initialized = true; _flushing = false; } + try + { + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, this); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } + _proxies.clear(); _proxy = 0; // Break cyclic reference count. notifyAll(); } diff --git a/cpp/src/Ice/ConnectRequestHandler.h b/cpp/src/Ice/ConnectRequestHandler.h index c5bc6602766..53c9e33e070 100644 --- a/cpp/src/Ice/ConnectRequestHandler.h +++ b/cpp/src/Ice/ConnectRequestHandler.h @@ -35,7 +35,7 @@ public: ConnectRequestHandler(const ReferencePtr&, const Ice::ObjectPrx&); virtual ~ConnectRequestHandler(); - virtual RequestHandlerPtr connect(); + virtual RequestHandlerPtr connect(const Ice::ObjectPrx&); virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); virtual void prepareBatchRequest(BasicStream*); @@ -75,6 +75,7 @@ private: }; Ice::ObjectPrx _proxy; + std::vector<Ice::ObjectPrx> _proxies; const bool _batchAutoFlush; @@ -88,7 +89,8 @@ private: bool _batchRequestInProgress; size_t _batchRequestsSize; BasicStream _batchStream; - bool _updateRequestHandler; + + RequestHandlerPtr _connectionRequestHandler; }; typedef IceUtil::Handle<ConnectRequestHandler> ConnectRequestHandlerPtr; diff --git a/cpp/src/Ice/ConnectionRequestHandler.cpp b/cpp/src/Ice/ConnectionRequestHandler.cpp index a94d3e7180a..423a637c70c 100644 --- a/cpp/src/Ice/ConnectionRequestHandler.cpp +++ b/cpp/src/Ice/ConnectionRequestHandler.cpp @@ -18,17 +18,6 @@ using namespace std; using namespace IceInternal; -ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference, const Ice::ObjectPrx& proxy) : - RequestHandler(reference) -{ - _connection = _reference->getConnection(_compress); - RouterInfoPtr ri = reference->getRouterInfo(); - if(ri) - { - ri->addProxy(proxy); - } -} - ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference, const Ice::ConnectionIPtr& connection, bool compress) : @@ -39,10 +28,9 @@ ConnectionRequestHandler::ConnectionRequestHandler(const ReferencePtr& reference } RequestHandlerPtr -ConnectionRequestHandler::connect() +ConnectionRequestHandler::connect(const Ice::ObjectPrx&) { - assert(false); // This request handler is only created after connection binding. - return 0; + return this; } RequestHandlerPtr diff --git a/cpp/src/Ice/ConnectionRequestHandler.h b/cpp/src/Ice/ConnectionRequestHandler.h index 211e8f02819..78feee8736f 100644 --- a/cpp/src/Ice/ConnectionRequestHandler.h +++ b/cpp/src/Ice/ConnectionRequestHandler.h @@ -21,10 +21,9 @@ class ConnectionRequestHandler : public RequestHandler { public: - ConnectionRequestHandler(const ReferencePtr&, const Ice::ObjectPrx&); ConnectionRequestHandler(const ReferencePtr&, const Ice::ConnectionIPtr&, bool); - virtual RequestHandlerPtr connect(); + virtual RequestHandlerPtr connect(const Ice::ObjectPrx&); virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&); virtual void prepareBatchRequest(BasicStream*); diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index d45c0b9e758..261cecf46d3 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -29,6 +29,7 @@ #include <Ice/Network.h> #include <Ice/NetworkProxy.h> #include <Ice/EndpointFactoryManager.h> +#include <Ice/RequestHandlerFactory.h> #include <Ice/RetryQueue.h> #include <Ice/DynamicLibrary.h> #include <Ice/PluginManagerI.h> @@ -349,6 +350,20 @@ IceInternal::Instance::referenceFactory() const return _referenceFactory; } +RequestHandlerFactoryPtr +IceInternal::Instance::requestHandlerFactory() const +{ + IceUtil::RecMutex::Lock sync(*this); + + if(_state == StateDestroyed) + { + throw CommunicatorDestroyedException(__FILE__, __LINE__); + } + + assert(_requestHandlerFactory); + return _requestHandlerFactory; +} + ProxyFactoryPtr IceInternal::Instance::proxyFactory() const { @@ -1269,7 +1284,9 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi _locatorManager = new LocatorManager(_initData.properties); _referenceFactory = new ReferenceFactory(this, communicator); - + + _requestHandlerFactory = new RequestHandlerFactory(this); + _proxyFactory = new ProxyFactory(this); bool ipv4 = _initData.properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; @@ -1714,6 +1731,8 @@ IceInternal::Instance::destroy() //_referenceFactory->destroy(); // No destroy function defined. _referenceFactory = 0; + + _requestHandlerFactory = 0; // _proxyFactory->destroy(); // No destroy function defined. _proxyFactory = 0; diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h index c4047d1d0b4..4a41a6b8773 100644 --- a/cpp/src/Ice/Instance.h +++ b/cpp/src/Ice/Instance.h @@ -60,6 +60,9 @@ typedef IceUtil::Handle<Timer> TimerPtr; class MetricsAdminI; typedef IceUtil::Handle<MetricsAdminI> MetricsAdminIPtr; +class RequestHandlerFactory; +typedef IceUtil::Handle<RequestHandlerFactory> RequestHandlerFactoryPtr; + class Instance : public IceUtil::Shared, public IceUtil::RecMutex { public: @@ -71,6 +74,7 @@ public: RouterManagerPtr routerManager() const; LocatorManagerPtr locatorManager() const; ReferenceFactoryPtr referenceFactory() const; + RequestHandlerFactoryPtr requestHandlerFactory() const; ProxyFactoryPtr proxyFactory() const; OutgoingConnectionFactoryPtr outgoingConnectionFactory() const; ObjectFactoryManagerPtr servantFactoryManager() const; @@ -145,6 +149,7 @@ private: RouterManagerPtr _routerManager; LocatorManagerPtr _locatorManager; ReferenceFactoryPtr _referenceFactory; + RequestHandlerFactoryPtr _requestHandlerFactory; ProxyFactoryPtr _proxyFactory; OutgoingConnectionFactoryPtr _outgoingConnectionFactory; ObjectFactoryManagerPtr _servantFactoryManager; diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile index f44e0c977a8..e50882118c4 100644 --- a/cpp/src/Ice/Makefile +++ b/cpp/src/Ice/Makefile @@ -117,6 +117,7 @@ OBJS = Acceptor.o \ Reference.o \ ReferenceFactory.o \ RequestHandler.o \ + RequestHandlerFactory.o \ ResponseHandler.o \ RetryQueue.o \ RouterInfo.o \ diff --git a/cpp/src/Ice/Makefile.mak b/cpp/src/Ice/Makefile.mak index fcc4d3eb3e9..f920f1d709c 100644 --- a/cpp/src/Ice/Makefile.mak +++ b/cpp/src/Ice/Makefile.mak @@ -119,6 +119,7 @@ OBJS = .\Acceptor.obj \ .\Reference.obj \ .\ReferenceFactory.obj \ .\RequestHandler.obj \ + .\RequestHandlerFactory.obj \ .\ResponseHandler.obj \ .\RetryQueue.obj \ .\RouterInfo.obj \ diff --git a/cpp/src/Ice/OutgoingAsync.cpp b/cpp/src/Ice/OutgoingAsync.cpp index fca1013252e..1719adc6b35 100644 --- a/cpp/src/Ice/OutgoingAsync.cpp +++ b/cpp/src/Ice/OutgoingAsync.cpp @@ -98,6 +98,11 @@ ProxyOutgoingAsyncBase::completed(const Exception& exc) // try { + // + // It's important to let the retry queue do the retry even if + // the retry interval is 0. This method can be called with the + // connection locked so we can't just retry here. + // _instance->retryQueue()->add(this, handleException(exc)); return false; } diff --git a/cpp/src/Ice/Proxy.cpp b/cpp/src/Ice/Proxy.cpp index d18a38a96e5..7618ff6eeb0 100644 --- a/cpp/src/Ice/Proxy.cpp +++ b/cpp/src/Ice/Proxy.cpp @@ -14,9 +14,7 @@ #include <Ice/ObjectAdapterFactory.h> #include <Ice/Outgoing.h> #include <Ice/OutgoingAsync.h> -#include <Ice/ConnectRequestHandler.h> -#include <Ice/CollocatedRequestHandler.h> -#include <Ice/ConnectionRequestHandler.h> +#include <Ice/RequestHandlerFactory.h> #include <Ice/Reference.h> #include <Ice/EndpointI.h> #include <Ice/Instance.h> @@ -1626,14 +1624,14 @@ IceProxy::Ice::Object::__getRequestHandler() { return _requestHandler; } - handler = createRequestHandler(); + handler = _reference->getInstance()->requestHandlerFactory()->getRequestHandler(_reference, this); _requestHandler = handler; } else { - handler = createRequestHandler(); + handler = _reference->getInstance()->requestHandlerFactory()->getRequestHandler(_reference, this); } - return handler->connect(); + return handler->connect(this); } void @@ -1663,21 +1661,6 @@ IceProxy::Ice::Object::__newInstance() const return new Object; } -RequestHandlerPtr -IceProxy::Ice::Object::createRequestHandler() -{ - if(_reference->getCollocationOptimized()) - { - ObjectAdapterPtr adapter = _reference->getInstance()->objectAdapterFactory()->findObjectAdapter(this); - if(adapter) - { - return new ::IceInternal::CollocatedRequestHandler(_reference, adapter); - } - } - - return new ::IceInternal::ConnectRequestHandler(_reference, this); -} - void IceProxy::Ice::Object::setup(const ReferencePtr& ref) { diff --git a/cpp/src/Ice/RequestHandler.h b/cpp/src/Ice/RequestHandler.h index 68ff00d647d..8cae95275ba 100644 --- a/cpp/src/Ice/RequestHandler.h +++ b/cpp/src/Ice/RequestHandler.h @@ -63,7 +63,7 @@ class RequestHandler : public CancellationHandler { public: - virtual RequestHandlerPtr connect() = 0; + virtual RequestHandlerPtr connect(const Ice::ObjectPrx&) = 0; virtual RequestHandlerPtr update(const RequestHandlerPtr&, const RequestHandlerPtr&) = 0; virtual void prepareBatchRequest(BasicStream*) = 0; diff --git a/cpp/src/Ice/RequestHandlerFactory.cpp b/cpp/src/Ice/RequestHandlerFactory.cpp new file mode 100644 index 00000000000..e21344c98d9 --- /dev/null +++ b/cpp/src/Ice/RequestHandlerFactory.cpp @@ -0,0 +1,71 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/RequestHandlerFactory.h> +#include <Ice/CollocatedRequestHandler.h> +#include <Ice/ConnectRequestHandler.h> +#include <Ice/CollocatedRequestHandler.h> +#include <Ice/Reference.h> +#include <Ice/ObjectAdapterFactory.h> +#include <Ice/Instance.h> + +using namespace std; +using namespace IceInternal; + +RequestHandlerFactory::RequestHandlerFactory(const InstancePtr& instance) : _instance(instance) +{ +} + +RequestHandlerPtr +IceInternal::RequestHandlerFactory::getRequestHandler(const ReferencePtr& ref, const Ice::ObjectPrx& proxy) +{ + if(ref->getCollocationOptimized()) + { + Ice::ObjectAdapterPtr adapter = _instance->objectAdapterFactory()->findObjectAdapter(proxy); + if(adapter) + { + return new CollocatedRequestHandler(ref, adapter); + } + } + + if(ref->getCacheConnection()) + { + Lock sync(*this); + + map<ReferencePtr, RequestHandlerPtr>::iterator p = _handlers.find(ref); + if(p != _handlers.end()) + { + return p->second; + } + + RequestHandlerPtr handler = new ConnectRequestHandler(ref, proxy); + _handlers.insert(make_pair(ref, handler)); + return handler; + } + else + { + return new ConnectRequestHandler(ref, proxy); + } +} + +void +IceInternal::RequestHandlerFactory::removeRequestHandler(const ReferencePtr& ref, const RequestHandlerPtr& handler) +{ + if(ref->getCacheConnection()) + { + Lock sync(*this); + map<ReferencePtr, RequestHandlerPtr>::iterator p = _handlers.find(ref); + assert(p != _handlers.end() && p->second.get() == handler.get()); + if(p != _handlers.end()) + { + _handlers.erase(p); + } + } +} + diff --git a/cpp/src/Ice/RequestHandlerFactory.h b/cpp/src/Ice/RequestHandlerFactory.h new file mode 100644 index 00000000000..b7a0b5d7cc0 --- /dev/null +++ b/cpp/src/Ice/RequestHandlerFactory.h @@ -0,0 +1,41 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_REQUEST_HANDLER_FACTORY_H +#define ICE_REQUEST_HANDLER_FACTORY_H + +#include <IceUtil/Shared.h> +#include <IceUtil/Mutex.h> + +#include <Ice/RequestHandlerF.h> +#include <Ice/ProxyF.h> +#include <Ice/ReferenceF.h> +#include <Ice/InstanceF.h> + +namespace IceInternal +{ + +class RequestHandlerFactory : public IceUtil::Shared, private IceUtil::Mutex +{ +public: + + RequestHandlerFactory(const InstancePtr&); + + RequestHandlerPtr getRequestHandler(const ReferencePtr&, const Ice::ObjectPrx&); + void removeRequestHandler(const ReferencePtr&, const RequestHandlerPtr&); + +private: + + const InstancePtr _instance; + std::map<ReferencePtr, RequestHandlerPtr> _handlers; +}; + +} + +#endif diff --git a/cpp/src/Ice/Selector.cpp b/cpp/src/Ice/Selector.cpp index 12f0c508496..1073d245804 100644 --- a/cpp/src/Ice/Selector.cpp +++ b/cpp/src/Ice/Selector.cpp @@ -420,18 +420,18 @@ Selector::finish(EventHandler* handler, bool closeNow) if(handler->_registered) { update(handler, handler->_registered, SocketOperationNone); + } #if defined(ICE_USE_KQUEUE) - if(closeNow && !_changes.empty()) - { - // - // Update selector now to remove the FD from the kqueue if - // we're going to close it now. This isn't necessary for - // epoll since we always update the epoll FD immediately. - // - updateSelector(); - } -#endif + if(closeNow && !_changes.empty()) + { + // + // Update selector now to remove the FD from the kqueue if + // we're going to close it now. This isn't necessary for + // epoll since we always update the epoll FD immediately. + // + updateSelector(); } +#endif return closeNow; } @@ -509,7 +509,7 @@ Selector::select(vector<pair<EventHandler*, SocketOperation> >& handlers, int ti if(ev.flags & EV_ERROR) { Ice::Error out(_instance->initializationData().logger); - out << "error while updating selector:\n" << IceUtilInternal::errorToString(ev.data); + out << "selector returned error:\n" << IceUtilInternal::errorToString(ev.data); continue; } p.first = reinterpret_cast<EventHandler*>(ev.udata); diff --git a/cpp/src/Ice/winrt/Makefile.mak b/cpp/src/Ice/winrt/Makefile.mak index d2569a4a9a1..5c3d793db06 100644 --- a/cpp/src/Ice/winrt/Makefile.mak +++ b/cpp/src/Ice/winrt/Makefile.mak @@ -95,6 +95,7 @@ OBJS = $(ARCH)\$(CONFIG)\Acceptor.obj \ $(ARCH)\$(CONFIG)\RemoteLogger.obj \ $(ARCH)\$(CONFIG)\RetryQueue.obj \ $(ARCH)\$(CONFIG)\RequestHandler.obj \ + $(ARCH)\$(CONFIG)\RequestHandlerFactory.obj \ $(ARCH)\$(CONFIG)\ResponseHandler.obj \ $(ARCH)\$(CONFIG)\RouterInfo.obj \ $(ARCH)\$(CONFIG)\Router.obj \ |