diff options
author | Benoit Foucher <benoit@zeroc.com> | 2017-03-23 15:29:25 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2017-03-23 15:29:25 +0100 |
commit | 1597a75419cd8049252cfbca6fce6ae95ef8b2c7 (patch) | |
tree | 2b2c858df1dbe68c1d576cae06c4713fd2ad5c40 /cpp | |
parent | Use Ice\None with PHP namespace mapping (diff) | |
download | ice-1597a75419cd8049252cfbca6fce6ae95ef8b2c7.tar.bz2 ice-1597a75419cd8049252cfbca6fce6ae95ef8b2c7.tar.xz ice-1597a75419cd8049252cfbca6fce6ae95ef8b2c7.zip |
Fix for ICE-7125 - Added support for Ice.ClassGraphDepthMax
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Ice/InputStream.h | 25 | ||||
-rw-r--r-- | cpp/src/Ice/InputStream.cpp | 52 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.cpp | 14 | ||||
-rw-r--r-- | cpp/src/Ice/Instance.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.cpp | 3 | ||||
-rw-r--r-- | cpp/src/Ice/PropertyNames.h | 2 | ||||
-rw-r--r-- | cpp/src/Ice/ThreadPool.cpp | 11 | ||||
-rw-r--r-- | cpp/test/Ice/echo/BlobjectI.cpp | 41 | ||||
-rw-r--r-- | cpp/test/Ice/echo/BlobjectI.h | 6 | ||||
-rw-r--r-- | cpp/test/Ice/echo/Server.cpp | 5 | ||||
-rw-r--r-- | cpp/test/Ice/echo/Test.ice | 1 | ||||
-rw-r--r-- | cpp/test/Ice/echo/test.py | 5 | ||||
-rw-r--r-- | cpp/test/Ice/exceptions/AllTests.cpp | 40 | ||||
-rw-r--r-- | cpp/test/Ice/objects/AllTests.cpp | 32 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Collocated.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Server.cpp | 1 | ||||
-rw-r--r-- | cpp/test/Ice/objects/Test.ice | 8 | ||||
-rw-r--r-- | cpp/test/Ice/objects/TestI.cpp | 11 | ||||
-rw-r--r-- | cpp/test/Ice/objects/TestI.h | 3 |
19 files changed, 233 insertions, 30 deletions
diff --git a/cpp/include/Ice/InputStream.h b/cpp/include/Ice/InputStream.h index 4684d0eda69..363f41767ed 100644 --- a/cpp/include/Ice/InputStream.h +++ b/cpp/include/Ice/InputStream.h @@ -138,6 +138,8 @@ public: void setTraceSlicing(bool); + void setClassGraphDepthMax(size_t); + void* getClosure() const; void* setClosure(void*); @@ -738,8 +740,10 @@ private: protected: - EncapsDecoder(InputStream* stream, Encaps* encaps, bool sliceValues, const Ice::ValueFactoryManagerPtr& f) : - _stream(stream), _encaps(encaps), _sliceValues(sliceValues), _valueFactoryManager(f), _typeIdIndex(0) + EncapsDecoder(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + _stream(stream), _encaps(encaps), _sliceValues(sliceValues), _classGraphDepthMax(classGraphDepthMax), + _classGraphDepth(0), _valueFactoryManager(f), _typeIdIndex(0) { } @@ -756,6 +760,7 @@ private: { PatchFunc patchFunc; void* patchAddr; + size_t classGraphDepth; }; typedef std::vector<PatchEntry> PatchList; typedef std::map<Int, PatchList> PatchMap; @@ -763,6 +768,8 @@ private: InputStream* _stream; Encaps* _encaps; const bool _sliceValues; + const size_t _classGraphDepthMax; + size_t _classGraphDepth; Ice::ValueFactoryManagerPtr _valueFactoryManager; // Encapsulation attributes for object un-marshalling @@ -781,8 +788,10 @@ private: { public: - EncapsDecoder10(InputStream* stream, Encaps* encaps, bool sliceValues, const Ice::ValueFactoryManagerPtr& f) : - EncapsDecoder(stream, encaps, sliceValues, f), _sliceType(NoSlice) + EncapsDecoder10(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f), + _sliceType(NoSlice) { } @@ -814,8 +823,10 @@ private: { public: - EncapsDecoder11(InputStream* stream, Encaps* encaps, bool sliceValues, const Ice::ValueFactoryManagerPtr& f) : - EncapsDecoder(stream, encaps, sliceValues, f), _preAllocatedInstanceData(0), _current(0), _valueIdIndex(1) + EncapsDecoder11(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax, + const Ice::ValueFactoryManagerPtr& f) : + EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f), + _preAllocatedInstanceData(0), _current(0), _valueIdIndex(1) { } @@ -956,6 +967,8 @@ private: bool _traceSlicing; + size_t _classGraphDepthMax; + void* _closure; bool _sliceValues; diff --git a/cpp/src/Ice/InputStream.cpp b/cpp/src/Ice/InputStream.cpp index e10bc107df9..61f71c7b5ba 100644 --- a/cpp/src/Ice/InputStream.cpp +++ b/cpp/src/Ice/InputStream.cpp @@ -167,6 +167,7 @@ Ice::InputStream::initialize(Instance* instance, const EncodingVersion& encoding _collectObjects = _instance->collectObjects(); #endif _traceSlicing = _instance->traceLevels()->slicing > 0; + _classGraphDepthMax = _instance->classGraphDepthMax(); } void @@ -179,6 +180,7 @@ Ice::InputStream::initialize(const EncodingVersion& encoding) _collectObjects = false; #endif _traceSlicing = false; + _classGraphDepthMax = 0x7fffffff; _closure = 0; _sliceValues = true; _startSeq = -1; @@ -241,6 +243,19 @@ Ice::InputStream::setTraceSlicing(bool b) _traceSlicing = b; } +void +Ice::InputStream::setClassGraphDepthMax(size_t classGraphDepthMax) +{ + if(classGraphDepthMax < 1) + { + _classGraphDepthMax = 0x7fffffff; + } + else + { + _classGraphDepthMax = classGraphDepthMax; + } +} + void* Ice::InputStream::getClosure() const { @@ -266,6 +281,7 @@ Ice::InputStream::swap(InputStream& other) std::swap(_collectObjects, other._collectObjects); #endif std::swap(_traceSlicing, other._traceSlicing); + std::swap(_classGraphDepthMax, other._classGraphDepthMax); std::swap(_closure, other._closure); std::swap(_sliceValues, other._sliceValues); @@ -1740,11 +1756,11 @@ Ice::InputStream::initEncaps() ValueFactoryManagerPtr vfm = valueFactoryManager(); if(_currentEncaps->encoding == Encoding_1_0) { - _currentEncaps->decoder = new EncapsDecoder10(this, _currentEncaps, _sliceValues, vfm); + _currentEncaps->decoder = new EncapsDecoder10(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm); } else { - _currentEncaps->decoder = new EncapsDecoder11(this, _currentEncaps, _sliceValues, vfm); + _currentEncaps->decoder = new EncapsDecoder11(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm); } } } @@ -1884,6 +1900,7 @@ Ice::InputStream::EncapsDecoder::addPatchEntry(Int index, PatchFunc patchFunc, v PatchEntry e; e.patchFunc = patchFunc; e.patchAddr = patchAddr; + e.classGraphDepth = _classGraphDepth; q->second.push_back(e); } @@ -2233,6 +2250,30 @@ Ice::InputStream::EncapsDecoder10::readInstance() } // + // Compute the biggest class graph depth of this object. To compute this, + // we get the class graph depth of each ancestor from the patch map and + // keep the biggest one. + // + _classGraphDepth = 0; + PatchMap::iterator patchPos = _patchMap.find(index); + if(patchPos != _patchMap.end()) + { + assert(patchPos->second.size() > 0); + for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k) + { + if(k->classGraphDepth > _classGraphDepth) + { + _classGraphDepth = k->classGraphDepth; + } + } + } + + if(++_classGraphDepth > _classGraphDepthMax) + { + throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached"); + } + + // // Unmarshal the instance and add it to the map of unmarshaled instances. // unmarshal(index, v); @@ -2668,11 +2709,18 @@ Ice::InputStream::EncapsDecoder11::readInstance(Int index, PatchFunc patchFunc, startSlice(); // Read next Slice header for next iteration. } + if(++_classGraphDepth > _classGraphDepthMax) + { + throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached"); + } + // // Unmarshal the object. // unmarshal(index, v); + --_classGraphDepth; + if(!_current && !_patchMap.empty()) { // diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index c49e386d2e9..cba9085ba4f 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -948,6 +948,7 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi _initData(initData), _messageSizeMax(0), _batchAutoFlushSize(0), + _classGraphDepthMax(0), _collectObjects(false), _toStringMode(ICE_ENUM(ToStringMode, Unicode)), _implicitContext(0), @@ -1189,6 +1190,19 @@ IceInternal::Instance::Instance(const CommunicatorPtr& communicator, const Initi } } + { + static const int defaultValue = 100; + Int num = _initData.properties->getPropertyAsIntWithDefault("Ice.ClassGraphDepthMax", defaultValue); + if(num < 1 || static_cast<size_t>(num) > static_cast<size_t>(0x7fffffff)) + { + const_cast<size_t&>(_classGraphDepthMax) = static_cast<size_t>(0x7fffffff); + } + else + { + const_cast<size_t&>(_classGraphDepthMax) = static_cast<size_t>(num); + } + } + const_cast<bool&>(_collectObjects) = _initData.properties->getPropertyAsInt("Ice.CollectObjects") > 0; string toStringModeStr = _initData.properties->getPropertyWithDefault("Ice.ToStringMode", "Unicode"); diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h index ba1d367b84f..9bcc78e0990 100644 --- a/cpp/src/Ice/Instance.h +++ b/cpp/src/Ice/Instance.h @@ -108,6 +108,7 @@ public: Ice::PluginManagerPtr pluginManager() const; size_t messageSizeMax() const { return _messageSizeMax; } size_t batchAutoFlushSize() const { return _batchAutoFlushSize; } + size_t classGraphDepthMax() const { return _classGraphDepthMax; } bool collectObjects() const { return _collectObjects; } Ice::ToStringMode toStringMode() const { return _toStringMode; } const ACMConfig& clientACM() const; @@ -176,6 +177,7 @@ private: const DefaultsAndOverridesPtr _defaultsAndOverrides; // Immutable, not reset by destroy(). const size_t _messageSizeMax; // Immutable, not reset by destroy(). const size_t _batchAutoFlushSize; // Immutable, not reset by destroy(). + const size_t _classGraphDepthMax; // Immutable, not reset by destroy(). const bool _collectObjects; // Immutable, not reset by destroy(). const Ice::ToStringMode _toStringMode; // Immutable, not reset by destroy() ACMConfig _clientACM; diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp index 02ee0f7ac2c..527d7e84d6d 100644 --- a/cpp/src/Ice/PropertyNames.cpp +++ b/cpp/src/Ice/PropertyNames.cpp @@ -6,7 +6,7 @@ // ICE_LICENSE file included in this distribution. // // ********************************************************************** -// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017 +// Generated by makeprops.py from file ./config/PropertyNames.xml, Thu Mar 23 15:24:16 2017 // IMPORTANT: Do not edit this file -- any edits made here will be lost! @@ -77,6 +77,7 @@ const IceInternal::Property IcePropsData[] = IceInternal::Property("Ice.BatchAutoFlush", true, 0), IceInternal::Property("Ice.BatchAutoFlushSize", false, 0), IceInternal::Property("Ice.ChangeUser", false, 0), + IceInternal::Property("Ice.ClassGraphDepthMax", false, 0), IceInternal::Property("Ice.ClientAccessPolicyProtocol", false, 0), IceInternal::Property("Ice.Compression.Level", false, 0), IceInternal::Property("Ice.CollectObjects", false, 0), diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h index 171fa1bed8c..485d4afaaa1 100644 --- a/cpp/src/Ice/PropertyNames.h +++ b/cpp/src/Ice/PropertyNames.h @@ -6,7 +6,7 @@ // ICE_LICENSE file included in this distribution. // // ********************************************************************** -// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017 +// Generated by makeprops.py from file ./config/PropertyNames.xml, Thu Mar 23 15:24:16 2017 // IMPORTANT: Do not edit this file -- any edits made here will be lost! diff --git a/cpp/src/Ice/ThreadPool.cpp b/cpp/src/Ice/ThreadPool.cpp index 946a05e2b08..4b14a7e1ce8 100644 --- a/cpp/src/Ice/ThreadPool.cpp +++ b/cpp/src/Ice/ThreadPool.cpp @@ -346,7 +346,16 @@ IceInternal::ThreadPool::ThreadPool(const InstancePtr& instance, const string& p _selector.setup(_sizeIO); #endif - int stackSize = properties->getPropertyAsInt(_prefix + ".StackSize"); +#if defined(__APPLE__) + // + // We use a default stack size of 1MB on macOS and the new C++11 mapping to allow transmitting + // class graphs with a depth of 100 (maximum default), 512KB is not enough otherwise. + // + int defaultStackSize = 1024 * 1024; // 1MB +#else + int defaultStackSize = 0; +#endif + int stackSize = properties->getPropertyAsIntWithDefault(_prefix + ".StackSize", defaultStackSize); if(stackSize < 0) { Warning out(_instance->initializationData().logger); diff --git a/cpp/test/Ice/echo/BlobjectI.cpp b/cpp/test/Ice/echo/BlobjectI.cpp index 024b239ac4f..894e217569c 100644 --- a/cpp/test/Ice/echo/BlobjectI.cpp +++ b/cpp/test/Ice/echo/BlobjectI.cpp @@ -54,6 +54,14 @@ BlobjectI::BlobjectI() : } void +BlobjectI::setConnection(const Ice::ConnectionPtr& connection) +{ + Lock sync(*this); + _connection = connection; + notifyAll(); +} + +void BlobjectI::startBatch() { assert(!_batchProxy); @@ -75,8 +83,9 @@ BlobjectI::ice_invokeAsync(std::vector<Ice::Byte> inEncaps, std::function<void(std::exception_ptr)> ex, const Ice::Current& current) { + auto connection = getConnection(current); const bool twoway = current.requestId > 0; - auto obj = current.con->createProxy(current.id); + auto obj = connection->createProxy(current.id); if(!twoway) { if(_startBatch) @@ -124,8 +133,9 @@ void BlobjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCb, const vector<Ice::Byte>& inEncaps, const Ice::Current& current) { + Ice::ConnectionPtr connection = getConnection(current); const bool twoway = current.requestId > 0; - Ice::ObjectPrx obj = current.con->createProxy(current.id); + Ice::ObjectPrx obj = connection->createProxy(current.id); if(!twoway) { if(_startBatch) @@ -171,3 +181,30 @@ BlobjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCb, const ve } } #endif + +Ice::ConnectionPtr +BlobjectI::getConnection(const Ice::Current& current) +{ + Lock sync(*this); + if(!_connection) + { + return current.con; + } + + try + { + _connection->throwException(); + } + catch(const Ice::ConnectionLostException&) + { + // If we lost the connection, wait 5 seconds for the server to re-establish it. Some tests, + // involve connection closure (e.g.: exceptions MemoryLimitException test) and the server + // automatically re-establishes the connection with the echo server. + timedWait(IceUtil::Time::seconds(5)); + if(!_connection) + { + throw; + } + } + return _connection; +} diff --git a/cpp/test/Ice/echo/BlobjectI.h b/cpp/test/Ice/echo/BlobjectI.h index fe8091c8f88..16db90e0b5c 100644 --- a/cpp/test/Ice/echo/BlobjectI.h +++ b/cpp/test/Ice/echo/BlobjectI.h @@ -12,7 +12,7 @@ #include <Ice/Object.h> -class BlobjectI : public Ice::BlobjectAsync +class BlobjectI : public Ice::BlobjectAsync, private IceUtil::Monitor<IceUtil::Mutex> { public: @@ -20,6 +20,7 @@ public: void startBatch(); void flushBatch(); + void setConnection(const Ice::ConnectionPtr&); #ifdef ICE_CPP11_MAPPING @@ -35,8 +36,11 @@ public: private: + Ice::ConnectionPtr getConnection(const Ice::Current&); + bool _startBatch; Ice::ObjectPrxPtr _batchProxy; + Ice::ConnectionPtr _connection; }; ICE_DEFINE_PTR(BlobjectIPtr, BlobjectI); diff --git a/cpp/test/Ice/echo/Server.cpp b/cpp/test/Ice/echo/Server.cpp index 56cd9f534bf..b0576241b02 100644 --- a/cpp/test/Ice/echo/Server.cpp +++ b/cpp/test/Ice/echo/Server.cpp @@ -25,6 +25,11 @@ public: { } + virtual void setConnection(const Ice::Current& current) + { + _blob->setConnection(current.con); + } + virtual void startBatch(const Ice::Current&) { _blob->startBatch(); diff --git a/cpp/test/Ice/echo/Test.ice b/cpp/test/Ice/echo/Test.ice index 57f7e92da21..7cf7ec721bd 100644 --- a/cpp/test/Ice/echo/Test.ice +++ b/cpp/test/Ice/echo/Test.ice @@ -17,6 +17,7 @@ module Test // interface Echo { + void setConnection(); void startBatch(); void flushBatch(); void shutdown(); diff --git a/cpp/test/Ice/echo/test.py b/cpp/test/Ice/echo/test.py index 3f25f4bfa15..717826f73a2 100644 --- a/cpp/test/Ice/echo/test.py +++ b/cpp/test/Ice/echo/test.py @@ -9,7 +9,10 @@ class EchoServerTestCase(ClientServerTestCase): + def __init__(self): + ClientServerTestCase.__init__(self, "server", server=Server(quiet=True, waitForShutdown=False)) + def runClientSide(self, current): pass -TestSuite(__name__, [EchoServerTestCase(name="server", server=Server(quiet=True, waitForShutdown=False))]) +TestSuite(__name__, [EchoServerTestCase()]) diff --git a/cpp/test/Ice/exceptions/AllTests.cpp b/cpp/test/Ice/exceptions/AllTests.cpp index 7fb9c1a930a..32302c5c6d8 100644 --- a/cpp/test/Ice/exceptions/AllTests.cpp +++ b/cpp/test/Ice/exceptions/AllTests.cpp @@ -988,32 +988,42 @@ allTests(const Ice::CommunicatorPtr& communicator) catch(const Ice::ConnectionLostException&) { } + catch(const Ice::UnknownLocalException&) + { + // Expected with JS bidir server + } catch(const Ice::LocalException& ex) { cerr << ex << endl; test(false); } - ThrowerPrxPtr thrower2 = - ICE_UNCHECKED_CAST(ThrowerPrx, communicator->stringToProxy("thrower:" + getTestEndpoint(communicator, 1))); - try - { - thrower2->throwMemoryLimitException(Ice::ByteSeq(2 * 1024 * 1024)); // 2MB (no limits) - } - catch(const Ice::MemoryLimitException&) - { - } - ThrowerPrxPtr thrower3 = - ICE_UNCHECKED_CAST(ThrowerPrx, communicator->stringToProxy("thrower:" + getTestEndpoint(communicator, 2))); try { - thrower3->throwMemoryLimitException(Ice::ByteSeq(1024)); // 1KB limit - test(false); + ThrowerPrxPtr thrower2 = + ICE_UNCHECKED_CAST(ThrowerPrx, communicator->stringToProxy("thrower:" + getTestEndpoint(communicator, 1))); + try + { + thrower2->throwMemoryLimitException(Ice::ByteSeq(2 * 1024 * 1024)); // 2MB (no limits) + } + catch(const Ice::MemoryLimitException&) + { + } + ThrowerPrxPtr thrower3 = + ICE_UNCHECKED_CAST(ThrowerPrx, communicator->stringToProxy("thrower:" + getTestEndpoint(communicator, 2))); + try + { + thrower3->throwMemoryLimitException(Ice::ByteSeq(1024)); // 1KB limit + test(false); + } + catch(const Ice::ConnectionLostException&) + { + } } - catch(const Ice::ConnectionLostException&) + catch(const Ice::ConnectionRefusedException&) { + // Expected with JS bidir server } - cout << "ok" << endl; } diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp index 5e6ba0460b8..95d44d6b962 100644 --- a/cpp/test/Ice/objects/AllTests.cpp +++ b/cpp/test/Ice/objects/AllTests.cpp @@ -323,6 +323,38 @@ allTests(const Ice::CommunicatorPtr& communicator) test(retS.size() == 1 && outS.size() == 1); cout << "ok" << endl; + cout << "testing recursive type... " << flush; + RecursivePtr top = ICE_MAKE_SHARED(Recursive); + RecursivePtr p = top; + int depth = 0; + try + { + for(; depth <= 2000; ++depth) + { + p->v = ICE_MAKE_SHARED(Recursive); + p = p->v; + if((depth < 10 && (depth % 10) == 0) || + (depth < 1000 && (depth % 100) == 0) || + (depth < 10000 && (depth % 1000) == 0) || + (depth % 10000) == 0) + { + initial->setRecursive(top); + } + } + test(!initial->supportsClassGraphDepthMax()); + } + catch(const Ice::UnknownLocalException&) + { + // Expected marshal exception from the server (max class graph depth reached) + test(depth == 100); // The default is 100. + } + catch(const Ice::UnknownException&) + { + // Expected stack overflow from the server (Java only) + } + initial->setRecursive(ICE_MAKE_SHARED(Recursive)); + cout << "ok" << endl; + cout << "testing compact ID..." << flush; try { diff --git a/cpp/test/Ice/objects/Collocated.cpp b/cpp/test/Ice/objects/Collocated.cpp index 60330b7061b..8c2d71b399b 100644 --- a/cpp/test/Ice/objects/Collocated.cpp +++ b/cpp/test/Ice/objects/Collocated.cpp @@ -154,6 +154,7 @@ main(int argc, char* argv[]) try { Ice::InitializationData initData = getTestInitData(argc, argv); + initData.properties->setProperty("Ice.Warn.Dispatch", "0"); Ice::CommunicatorHolder ich(argc, argv, initData); return run(argc, argv, ich.communicator()); } diff --git a/cpp/test/Ice/objects/Server.cpp b/cpp/test/Ice/objects/Server.cpp index 991233bfa0a..a501281b29b 100644 --- a/cpp/test/Ice/objects/Server.cpp +++ b/cpp/test/Ice/objects/Server.cpp @@ -88,6 +88,7 @@ main(int argc, char* argv[]) try { Ice::InitializationData initData = getTestInitData(argc, argv); + initData.properties->setProperty("Ice.Warn.Dispatch", "0"); Ice::CommunicatorHolder ich(argc, argv, initData); return run(argc, argv, ich.communicator()); } diff --git a/cpp/test/Ice/objects/Test.ice b/cpp/test/Ice/objects/Test.ice index 134a1aa2ea5..7d64f20614e 100644 --- a/cpp/test/Ice/objects/Test.ice +++ b/cpp/test/Ice/objects/Test.ice @@ -167,6 +167,11 @@ exception EDerived extends EBase A1 a4; }; +class Recursive +{ + Recursive v; +}; + interface Initial { void shutdown(); @@ -177,6 +182,9 @@ interface Initial E getE(); F getF(); + void setRecursive(Recursive p); + bool supportsClassGraphDepthMax(); + ["marshaled-result"] B getMB(); ["amd", "marshaled-result"] B getAMDMB(); diff --git a/cpp/test/Ice/objects/TestI.cpp b/cpp/test/Ice/objects/TestI.cpp index f17e1a7960d..803a278fba7 100644 --- a/cpp/test/Ice/objects/TestI.cpp +++ b/cpp/test/Ice/objects/TestI.cpp @@ -161,6 +161,17 @@ InitialI::getF(const Ice::Current&) return _f; } +void +InitialI::setRecursive(ICE_IN(RecursivePtr), const Ice::Current&) +{ +} + +bool +InitialI::supportsClassGraphDepthMax(const Ice::Current&) +{ + return true; +} + #ifdef ICE_CPP11_MAPPING InitialI::GetMBMarshaledResult InitialI::getMB(const Ice::Current& current) diff --git a/cpp/test/Ice/objects/TestI.h b/cpp/test/Ice/objects/TestI.h index a7243ed95f6..1a467fc0f33 100644 --- a/cpp/test/Ice/objects/TestI.h +++ b/cpp/test/Ice/objects/TestI.h @@ -94,6 +94,9 @@ public: virtual Test::EPtr getE(const Ice::Current&); virtual Test::FPtr getF(const Ice::Current&); + virtual void setRecursive(ICE_IN(Test::RecursivePtr), const Ice::Current&); + virtual bool supportsClassGraphDepthMax(const Ice::Current&); + #ifdef ICE_CPP11_MAPPING virtual GetMBMarshaledResult getMB(const Ice::Current&); virtual void getAMDMBAsync(std::function<void(const GetAMDMBMarshaledResult&)>, |