Skip to content
Snippets Groups Projects
Commit fcff618e authored by Craig Tiller's avatar Craig Tiller
Browse files

Clarify some of the call stuff

parent e22fb4e3
No related branches found
No related tags found
No related merge requests found
......@@ -59,6 +59,9 @@ void FillMetadataMap(grpc_metadata_array* arr,
grpc_metadata* FillMetadataArray(
const std::multimap<grpc::string, grpc::string>& metadata);
/// Default argument for CallOpSet. I is unused by the class, but can be
/// used for generating multiple names for the same thing.
template <int I>
class CallNoOp {
protected:
void AddOp(grpc_op* ops, size_t* nops) {}
......@@ -344,9 +347,16 @@ class CallOpClientRecvStatus {
size_t status_details_capacity_;
};
/// An abstract collection of call ops, used to generate the
/// grpc_call_op structure to pass down to the lower layers,
/// and as it is-a CompletionQueueTag, also massages the final
/// completion into the correct form for consumption in the C++
/// API.
class CallOpSetInterface : public CompletionQueueTag {
public:
CallOpSetInterface() : max_message_size_(0) {}
/// Fills in grpc_op, starting from ops[*nops] and moving
/// upwards.
virtual void FillOps(grpc_op* ops, size_t* nops) = 0;
void set_max_message_size(int max_message_size) {
......@@ -357,36 +367,39 @@ class CallOpSetInterface : public CompletionQueueTag {
int max_message_size_;
};
template <class T, int I>
class WrapAndDerive : public T {};
template <class Op1 = CallNoOp, class Op2 = CallNoOp, class Op3 = CallNoOp,
class Op4 = CallNoOp, class Op5 = CallNoOp, class Op6 = CallNoOp>
/// Primary implementaiton of CallOpSetInterface.
/// Since we cannot use variadic templates, we declare slots up to
/// the maximum count of ops we'll need in a set. We leverage the
/// empty base class optimization to slim this class (especially
/// when there are many unused slots used). To avoid duplicate base classes,
/// the template parmeter for CallNoOp is varied by argument position.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>, class Op3 = CallNoOp<3>,
class Op4 = CallNoOp<4>, class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class CallOpSet : public CallOpSetInterface,
public WrapAndDerive<Op1, 1>,
public WrapAndDerive<Op2, 2>,
public WrapAndDerive<Op3, 3>,
public WrapAndDerive<Op4, 4>,
public WrapAndDerive<Op5, 5>,
public WrapAndDerive<Op6, 6> {
public Op1,
public Op2,
public Op3,
public Op4,
public Op5,
public Op6 {
public:
CallOpSet() : return_tag_(this) {}
void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE {
this->WrapAndDerive<Op1, 1>::AddOp(ops, nops);
this->WrapAndDerive<Op2, 2>::AddOp(ops, nops);
this->WrapAndDerive<Op3, 3>::AddOp(ops, nops);
this->WrapAndDerive<Op4, 4>::AddOp(ops, nops);
this->WrapAndDerive<Op5, 5>::AddOp(ops, nops);
this->WrapAndDerive<Op6, 6>::AddOp(ops, nops);
this->Op1::AddOp(ops, nops);
this->Op2::AddOp(ops, nops);
this->Op3::AddOp(ops, nops);
this->Op4::AddOp(ops, nops);
this->Op5::AddOp(ops, nops);
this->Op6::AddOp(ops, nops);
}
bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
this->WrapAndDerive<Op1, 1>::FinishOp(status, max_message_size_);
this->WrapAndDerive<Op2, 2>::FinishOp(status, max_message_size_);
this->WrapAndDerive<Op3, 3>::FinishOp(status, max_message_size_);
this->WrapAndDerive<Op4, 4>::FinishOp(status, max_message_size_);
this->WrapAndDerive<Op5, 5>::FinishOp(status, max_message_size_);
this->WrapAndDerive<Op6, 6>::FinishOp(status, max_message_size_);
this->Op1::FinishOp(status, max_message_size_);
this->Op2::FinishOp(status, max_message_size_);
this->Op3::FinishOp(status, max_message_size_);
this->Op4::FinishOp(status, max_message_size_);
this->Op5::FinishOp(status, max_message_size_);
this->Op6::FinishOp(status, max_message_size_);
*tag = return_tag_;
return true;
}
......@@ -397,9 +410,12 @@ class CallOpSet : public CallOpSetInterface,
void* return_tag_;
};
// SneakyCallOpBuffer does not post completions to the completion queue
template <class Op1 = CallNoOp, class Op2 = CallNoOp, class Op3 = CallNoOp,
class Op4 = CallNoOp, class Op5 = CallNoOp, class Op6 = CallNoOp>
/// A CallOpSet that does not post completions to the completion queue.
///
/// Allows hiding some completions that the C core must generate from
/// C++ users.
template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>, class Op3 = CallNoOp<3>,
class Op4 = CallNoOp<4>, class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
class SneakyCallOpSet GRPC_FINAL
: public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
public:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment