summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2019-11-03 11:06:24 -0500
committerGitHub <noreply@github.com>2019-11-03 11:06:24 -0500
commit3981787ebd09050d461b7dad7c66d040b06abc0a (patch)
tree1eceacb4d90e9ef153f0d8e5fa4fa2c1b8940ffe /cpp
parentFixed dependency of ice-test.xcodeproj to not depend on carthage (diff)
downloadice-3981787ebd09050d461b7dad7c66d040b06abc0a.tar.bz2
ice-3981787ebd09050d461b7dad7c66d040b06abc0a.tar.xz
ice-3981787ebd09050d461b7dad7c66d040b06abc0a.zip
Move response, error and sent functions given to the client Async API (#610)
instead of copying them.
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/OutgoingAsync.h15
-rw-r--r--cpp/include/Ice/Proxy.h40
-rw-r--r--cpp/src/slice2cpp/Gen.cpp5
-rw-r--r--cpp/test/Ice/ami/AllTests.cpp42
4 files changed, 90 insertions, 12 deletions
diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h
index d426b372eea..29a51926bf8 100644
--- a/cpp/include/Ice/OutgoingAsync.h
+++ b/cpp/include/Ice/OutgoingAsync.h
@@ -463,7 +463,12 @@ public:
std::function<void(bool)> sent) :
OutgoingAsyncT<R>(proxy, false), LambdaInvoke(std::move(ex), std::move(sent))
{
+#if ICE_CPLUSPLUS >= 201402L
+ // Move capture with C++14
+ _response = [this, response = std::move(response)](bool ok)
+#else
_response = [this, response](bool ok)
+#endif
{
if(!ok)
{
@@ -499,7 +504,12 @@ public:
std::function<void(bool)> sent) :
OutgoingAsyncT<void>(proxy, false), LambdaInvoke(std::move(ex), std::move(sent))
{
+#if ICE_CPLUSPLUS >= 201402L
+ // Move capture with C++14
+ _response = [this, response = std::move(response)](bool ok)
+#else
_response = [this, response](bool ok)
+#endif
{
if(!ok)
{
@@ -535,7 +545,12 @@ public:
std::function<void(bool)> sent) :
OutgoingAsync(proxy, false), LambdaInvoke(std::move(ex), std::move(sent))
{
+#if ICE_CPLUSPLUS >= 201402L
+ // Move capture with C++14
+ _response = [this, read = std::move(read)](bool ok)
+#else
_response = [this, read](bool ok)
+#endif
{
if(!ok)
{
diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h
index a5bf67c494c..340651c5081 100644
--- a/cpp/include/Ice/Proxy.h
+++ b/cpp/include/Ice/Proxy.h
@@ -178,7 +178,12 @@ public:
{
if(response)
{
+#if ICE_CPLUSPLUS >= 201402L
+ // Move capture with C++14
+ _response = [this, response = std::move(response)](bool ok)
+#else
_response = [this, response](bool ok)
+#endif
{
if(this->_is.b.empty())
{
@@ -235,7 +240,11 @@ public:
::std::function<void(bool)> sent) :
ProxyGetConnection(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent))
{
+#if ICE_CPLUSPLUS >= 201402L
+ _response = [&, response = std::move(response)](bool)
+#else
_response = [&, response](bool)
+#endif
{
response(getConnection());
};
@@ -354,7 +363,8 @@ public:
::std::function<void(bool)> sent = nullptr,
const ::Ice::Context& context = ::Ice::noExplicitContext)
{
- return _makeLamdaOutgoing<bool>(response, ex, sent, this, &ObjectPrx::_iceI_isA, typeId, context);
+ return _makeLamdaOutgoing<bool>(std::move(response), std::move(ex), std::move(sent), this,
+ &ObjectPrx::_iceI_isA, typeId, context);
}
/**
@@ -399,7 +409,8 @@ public:
::std::function<void(bool)> sent = nullptr,
const ::Ice::Context& context = ::Ice::noExplicitContext)
{
- return _makeLamdaOutgoing<void>(response, ex, sent, this, &ObjectPrx::_iceI_ping, context);
+ return _makeLamdaOutgoing<void>(std::move(response), std::move(ex), std::move(sent), this,
+ &ObjectPrx::_iceI_ping, context);
}
/**
@@ -445,7 +456,8 @@ public:
::std::function<void(bool)> sent = nullptr,
const ::Ice::Context& context = ::Ice::noExplicitContext)
{
- return _makeLamdaOutgoing<::std::vector<::std::string>>(response, ex, sent, this, &ObjectPrx::_iceI_ids, context);
+ return _makeLamdaOutgoing<::std::vector<::std::string>>(std::move(response), std::move(ex), std::move(sent),
+ this, &ObjectPrx::_iceI_ids, context);
}
/**
@@ -490,7 +502,8 @@ public:
::std::function<void(bool)> sent = nullptr,
const ::Ice::Context& context = ::Ice::noExplicitContext)
{
- return _makeLamdaOutgoing<::std::string>(response, ex, sent, this, &ObjectPrx::_iceI_id, context);
+ return _makeLamdaOutgoing<::std::string>(std::move(response), std::move(ex), std::move(sent), this,
+ &ObjectPrx::_iceI_id, context);
}
/**
@@ -583,12 +596,16 @@ public:
::std::function<void(::Ice::Object::Ice_invokeResult&&)> r;
if(response)
{
+#if ICE_CPLUSPLUS >= 201402L
+ r = [response = std::move(response)](::Ice::Object::Ice_invokeResult&& result)
+#else
r = [response](::Ice::Object::Ice_invokeResult&& result)
+#endif
{
response(result.returnValue, std::move(result.outParams));
};
}
- auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent);
+ auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), std::move(r), std::move(ex), std::move(sent));
outAsync->invoke(operation, mode, ::IceInternal::makePair(inParams), context);
return [outAsync]() { outAsync->cancel(); };
}
@@ -669,12 +686,16 @@ public:
::std::function<void(Result&&)> r;
if(response)
{
+#if ICE_CPLUSPLUS >= 201402L
+ r = [response = std::move(response)](Result&& result)
+#else
r = [response](Result&& result)
+#endif
{
response(::std::get<0>(result), ::std::move(::std::get<1>(result)));
};
}
- auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent);
+ auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), std::move(r), std::move(ex), std::move(sent));
outAsync->invoke(operation, mode, inParams, context);
return [outAsync]() { outAsync->cancel(); };
}
@@ -1023,7 +1044,7 @@ public:
::std::function<void(bool)> sent = nullptr)
{
using LambdaOutgoing = ::IceInternal::ProxyGetConnectionLambda;
- auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), response, ex, sent);
+ auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), std::move(response), std::move(ex), std::move(sent));
_iceI_getConnection(outAsync);
return [outAsync]() { outAsync->cancel(); };
}
@@ -1073,7 +1094,7 @@ public:
::std::function<void(bool)> sent = nullptr)
{
using LambdaOutgoing = ::IceInternal::ProxyFlushBatchLambda;
- auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), ex, sent);
+ auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), std::move(ex), std::move(sent));
_iceI_flushBatchRequests(outAsync);
return [outAsync]() { outAsync->cancel(); };
}
@@ -1128,7 +1149,8 @@ protected:
template<typename R, typename Re, typename E, typename S, typename Obj, typename Fn, typename... Args>
::std::function<void()> _makeLamdaOutgoing(Re r, E e, S s, Obj obj, Fn fn, Args&&... args)
{
- auto outAsync = ::std::make_shared<::IceInternal::LambdaOutgoing<R>>(shared_from_this(), r, e, s);
+ auto outAsync = ::std::make_shared<::IceInternal::LambdaOutgoing<R>>(shared_from_this(),
+ std::move(r), std::move(e), std::move(s));
(obj->*fn)(outAsync, std::forward<Args>(args)...);
return [outAsync]() { outAsync->cancel(); };
}
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index ce8b0c040a2..49e0e1f3eff 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -7194,7 +7194,10 @@ Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p)
H << nl << "return _makeLamdaOutgoing<" << futureT << ">" << spar;
- H << (futureOutParams.size() > 1 ? "_responseCb" : responseParam) << exParam << sentParam << "this";
+ H << "std::move(" + (futureOutParams.size() > 1 ? "_responseCb" : responseParam) + ")"
+ << "std::move(" + exParam + ")"
+ << "std::move(" + sentParam + ")"
+ << "this";
H << string("&" + getUnqualified(scoped, clScope.substr(2)) + "_iceI_" + name);
for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q)
{
diff --git a/cpp/test/Ice/ami/AllTests.cpp b/cpp/test/Ice/ami/AllTests.cpp
index 6697fd024dc..3832ba58684 100644
--- a/cpp/test/Ice/ami/AllTests.cpp
+++ b/cpp/test/Ice/ami/AllTests.cpp
@@ -1162,17 +1162,55 @@ allTests(Test::TestHelper* helper, bool collocated)
test(promise.get_future().get() == 15);
}
{
+ // Count copies made
+ class CopyCounter
+ {
+ public:
+ CopyCounter(int& count) : _count(count)
+ {
+ }
+
+ CopyCounter(const CopyCounter& o) : _count(o._count)
+ {
+ _count++;
+ }
+
+ CopyCounter(CopyCounter&&) = default;
+
+ private:
+ int& _count;
+ };
+
+ int responseCopyCount = 0;
+ int errorCopyCount = 0;
+ int sentCopyCount = 0;
+ CopyCounter responseCopyCounter(responseCopyCount);
+ CopyCounter errorCopyCounter(errorCopyCount);
+ CopyCounter sentCopyCounter(sentCopyCount);
+
promise<int> promise;
p->opWithResultAsync(
- [&](int result)
+ [&promise, responseCopyCounter](int result)
{
promise.set_value(result);
},
- [&](exception_ptr ex)
+ [&promise, errorCopyCounter](exception_ptr ex)
{
promise.set_exception(ex);
+ },
+ [sentCopyCounter](bool)
+ {
+ // no-op
});
test(promise.get_future().get() == 15);
+#if ICE_CPLUSPLUS >= 201402L
+ // Move capture with C++14 saves one copy (see Proxy.h and OutgoingAsync.h)
+ test(responseCopyCount == 1);
+#else
+ test(responseCopyCount == 2);
+#endif
+ test(errorCopyCount == 1);
+ test(sentCopyCount == 1);
}
{
promise<int> promise;