aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++
diff options
context:
space:
mode:
authorGravatar Muxi Yan <mxyan@google.com>2017-08-11 16:15:53 -0700
committerGravatar Muxi Yan <mxyan@google.com>2017-08-11 16:15:53 -0700
commit229125abb1510dea47e8608779dd93d968ce3fd9 (patch)
tree1fb2ba60bccb9795cc5659672c3d9cf71d520344 /include/grpc++
parentd36283ab594c4cf8fdffac700efeffa2705e6dc0 (diff)
parent71cc205aadd7ea2a48298a8e67d2c0d2858841f6 (diff)
Merge remote-tracking branch 'upstream/master' into stream_compression_config
Diffstat (limited to 'include/grpc++')
-rw-r--r--include/grpc++/impl/codegen/call.h37
-rw-r--r--include/grpc++/support/slice.h14
2 files changed, 44 insertions, 7 deletions
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 4ae0127c52..f1f1f1f356 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -366,6 +366,28 @@ class CallOpRecvMessage {
bool allow_not_getting_message_;
};
+namespace CallOpGenericRecvMessageHelper {
+class DeserializeFunc {
+ public:
+ virtual Status Deserialize(grpc_byte_buffer* buf) = 0;
+ virtual ~DeserializeFunc() {}
+};
+
+template <class R>
+class DeserializeFuncType final : public DeserializeFunc {
+ public:
+ DeserializeFuncType(R* message) : message_(message) {}
+ Status Deserialize(grpc_byte_buffer* buf) override {
+ return SerializationTraits<R>::Deserialize(buf, message_);
+ }
+
+ ~DeserializeFuncType() override {}
+
+ private:
+ R* message_; // Not a managed pointer because management is external to this
+};
+} // namespace CallOpGenericRecvMessageHelper
+
class CallOpGenericRecvMessage {
public:
CallOpGenericRecvMessage()
@@ -373,9 +395,11 @@ class CallOpGenericRecvMessage {
template <class R>
void RecvMessage(R* message) {
- deserialize_ = [message](grpc_byte_buffer* buf) -> Status {
- return SerializationTraits<R>::Deserialize(buf, message);
- };
+ // Use an explicit base class pointer to avoid resolution error in the
+ // following unique_ptr::reset for some old implementations.
+ CallOpGenericRecvMessageHelper::DeserializeFunc* func =
+ new CallOpGenericRecvMessageHelper::DeserializeFuncType<R>(message);
+ deserialize_.reset(func);
}
// Do not change status if no message is received.
@@ -398,7 +422,7 @@ class CallOpGenericRecvMessage {
if (recv_buf_) {
if (*status) {
got_message = true;
- *status = deserialize_(recv_buf_).ok();
+ *status = deserialize_->Deserialize(recv_buf_).ok();
} else {
got_message = false;
g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_);
@@ -409,12 +433,11 @@ class CallOpGenericRecvMessage {
*status = false;
}
}
- deserialize_ = DeserializeFunc();
+ deserialize_.reset();
}
private:
- typedef std::function<Status(grpc_byte_buffer*)> DeserializeFunc;
- DeserializeFunc deserialize_;
+ std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
grpc_byte_buffer* recv_buf_;
bool allow_not_getting_message_;
};
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index 0b4ba7cecb..bbf97f280e 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -67,6 +67,20 @@ class Slice final {
return *this;
}
+ /// Create a slice pointing at some data. Calls malloc to allocate a refcount
+ /// for the object, and arranges that destroy will be called with the
+ /// user data pointer passed in at destruction. Can be the same as buf or
+ /// different (e.g., if data is part of a larger structure that must be
+ /// destroyed when the data is no longer needed)
+ Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data);
+
+ /// Specialization of above for common case where buf == user_data
+ Slice(void* buf, size_t len, void (*destroy)(void*))
+ : Slice(buf, len, destroy, buf) {}
+
+ /// Similar to the above but has a destroy that also takes slice length
+ Slice(void* buf, size_t len, void (*destroy)(void*, size_t));
+
/// Byte size.
size_t size() const { return GRPC_SLICE_LENGTH(slice_); }