aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/cpp/helloworld/greeter_async_client.cc52
-rw-r--r--examples/cpp/helloworld/greeter_async_server.cc60
-rw-r--r--examples/cpp/helloworld/greeter_client.cc24
-rw-r--r--examples/cpp/helloworld/greeter_server.cc15
-rw-r--r--include/grpc++/channel.h13
-rw-r--r--include/grpc++/client_context.h103
-rw-r--r--include/grpc++/completion_queue.h91
-rw-r--r--include/grpc++/create_channel.h19
-rw-r--r--include/grpc++/grpc++.h64
-rw-r--r--include/grpc++/security/auth_context.h26
-rw-r--r--include/grpc++/security/credentials.h100
-rw-r--r--include/grpc++/security/server_credentials.h12
-rw-r--r--include/grpc++/server.h65
-rw-r--r--include/grpc++/server_builder.h63
-rw-r--r--include/grpc++/support/async_stream.h37
-rw-r--r--include/grpc++/support/byte_buffer.h14
-rw-r--r--include/grpc++/support/channel_arguments.h25
-rw-r--r--include/grpc++/support/slice.h26
-rw-r--r--include/grpc++/support/status.h12
-rw-r--r--include/grpc++/support/status_code_enum.h153
-rw-r--r--include/grpc++/support/string_ref.h13
-rw-r--r--include/grpc++/support/sync_stream.h89
-rw-r--r--include/grpc/grpc.h8
-rw-r--r--src/core/surface/completion_queue.h2
-rw-r--r--src/cpp/util/byte_buffer.cc6
25 files changed, 786 insertions, 306 deletions
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index 605fb7fb3a..923c8ffa74 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -35,13 +35,8 @@
#include <memory>
#include <string>
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
+#include <grpc++/grpc++.h>
+
#include "helloworld.grpc.pb.h"
using grpc::Channel;
@@ -58,39 +53,72 @@ class GreeterClient {
explicit GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
+ // Assambles the client's payload, sends it and presents the response back
+ // from the server.
std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
HelloRequest request;
request.set_name(user);
+
+ // Container for the data we expect from the server.
HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
ClientContext context;
+
+ // The producer-consumer queue we use to communicate asynchronously with the
+ // gRPC runtime.
CompletionQueue cq;
+
+ // Storage for the status of the RPC upon completion.
Status status;
+ // stub_->AsyncSayHello() perform the RPC call, returning an instance we
+ // store in "rpc". Because we are using the asynchronous API, we need the
+ // hold on to the "rpc" instance in order to get updates on the ongoig RPC.
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
+
+ // Request that, upon completion of the RPC, "reply" be updated with the
+ // server's response; "status" with the indication of whether the operation
+ // was successful. Tag the request with the integer 1.
rpc->Finish(&reply, &status, (void*)1);
void* got_tag;
bool ok = false;
+ // Block until the next result is available in the completion queue "cq".
cq.Next(&got_tag, &ok);
- GPR_ASSERT(ok);
+
+ // Verify that the result from "cq" corresponds, by its tag, our previous
+ // request.
GPR_ASSERT(got_tag == (void*)1);
+ // ... and that the request was completed successfully. Note that "ok"
+ // corresponds solely to the request for updates introduced by Finish().
+ GPR_ASSERT(ok);
+ // Act upon the status of the actual RPC.
if (status.ok()) {
return reply.message();
} else {
- return "Rpc failed";
+ return "RPC failed";
}
}
private:
+ // Out of the passed in Channel comes the stub, stored here, our view of the
+ // server's exposed services.
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
- GreeterClient greeter(grpc::CreateChannel(
- "localhost:50051", grpc::InsecureCredentials()));
+ // Instantiate the client. It requires a channel, out of which the actual RPCs
+ // are created. This channel models a connection to an endpoint (in this case,
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureCredentials()).
+ GreeterClient greeter(
+ grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
std::string user("world");
- std::string reply = greeter.SayHello(user);
+ std::string reply = greeter.SayHello(user); // The actual RPC call!
std::cout << "Greeter received: " << reply << std::endl;
return 0;
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
index 189c3afe6d..b2047a8ce5 100644
--- a/examples/cpp/helloworld/greeter_async_server.cc
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -36,13 +36,8 @@
#include <string>
#include <thread>
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
+#include <grpc++/grpc++.h>
+
#include "helloworld.grpc.pb.h"
using grpc::Server;
@@ -59,6 +54,7 @@ class ServerImpl final {
public:
~ServerImpl() {
server_->Shutdown();
+ // Always shutdown the completion queue after the server.
cq_->Shutdown();
}
@@ -67,56 +63,102 @@ class ServerImpl final {
std::string server_address("0.0.0.0:50051");
ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service_" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *asynchronous* service.
builder.RegisterAsyncService(&service_);
+ // Get hold of the completion queue used for the asynchronous communication
+ // with the gRPC runtime.
cq_ = builder.AddCompletionQueue();
+ // Finally assemble the server.
server_ = builder.BuildAndStart();
std::cout << "Server listening on " << server_address << std::endl;
+ // Proceed to the server's main loop.
HandleRpcs();
}
private:
+ // Class encompasing the state and logic needed to serve a request.
class CallData {
public:
+ // Take in the "service" instance (in this case representing an asynchronous
+ // server) and the completion queue "cq" used for asynchronous communication
+ // with the gRPC runtime.
CallData(Greeter::AsyncService* service, ServerCompletionQueue* cq)
: service_(service), cq_(cq), responder_(&ctx_), status_(CREATE) {
+ // Invoke the serving logic right away.
Proceed();
}
void Proceed() {
if (status_ == CREATE) {
+ // As part of the initial CREATE state, we *request* that the system
+ // start processing SayHello requests. In this request, "this" acts are
+ // the tag uniquely identifying the request (so that different CallData
+ // instances can serve different requests concurrently), in this case
+ // the memory address of this CallData instance.
service_->RequestSayHello(&ctx_, &request_, &responder_, cq_, cq_,
this);
+ // Make this instance progress to the PROCESS state.
status_ = PROCESS;
} else if (status_ == PROCESS) {
+ // Spawn a new CallData instance to serve new clients while we process
+ // the one for this CallData. The instance will deallocate itself as
+ // part of its FINISH state.
new CallData(service_, cq_);
+
+ // The actual processing.
std::string prefix("Hello ");
reply_.set_message(prefix + request_.name());
+
+ // And we are done! Let the gRPC runtime know we've finished, using the
+ // memory address of this instance as the uniquely identifying tag for
+ // the event.
responder_.Finish(reply_, Status::OK, this);
status_ = FINISH;
} else {
+ GPR_ASSERT(status_ == FINISH);
+ // Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
}
private:
+ // The means of communication with the gRPC runtime for an asynchronous
+ // server.
Greeter::AsyncService* service_;
+ // The producer-consumer queue where for asynchronous server notifications.
ServerCompletionQueue* cq_;
+ // Context for the rpc, allowing to tweak aspects of it such as the use
+ // of compression, authentication, as well as to send metadata back to the
+ // client.
ServerContext ctx_;
+
+ // What we get from the client.
HelloRequest request_;
+ // What we send back to the client.
HelloReply reply_;
+
+ // The means to get back to the client.
ServerAsyncResponseWriter<HelloReply> responder_;
+
+ // Let's implement a tiny state machine with the following states.
enum CallStatus { CREATE, PROCESS, FINISH };
- CallStatus status_;
+ CallStatus status_; // The current serving state.
};
// This can be run in multiple threads if needed.
void HandleRpcs() {
+ // Spawn a new CallData instance to serve new clients.
new CallData(&service_, cq_.get());
- void* tag;
+ void* tag; // uniquely identifies a request.
bool ok;
while (true) {
+ // Block waiting to read the next event from the completion queue. The
+ // event is uniquely identified by its tag, which in this case is the
+ // memory address of a CallData instance.
cq_->Next(&tag, &ok);
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
index bfb7c12724..6cd8353a9f 100644
--- a/examples/cpp/helloworld/greeter_client.cc
+++ b/examples/cpp/helloworld/greeter_client.cc
@@ -35,11 +35,8 @@
#include <memory>
#include <string>
-#include <grpc/grpc.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
+#include <grpc++/grpc++.h>
+
#include "helloworld.grpc.pb.h"
using grpc::Channel;
@@ -54,17 +51,28 @@ class GreeterClient {
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
+ // Assambles the client's payload, sends it and presents the response back
+ // from the server.
std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
HelloRequest request;
request.set_name(user);
+
+ // Container for the data we expect from the server.
HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
ClientContext context;
+ // The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
+
+ // Act upon its status.
if (status.ok()) {
return reply.message();
} else {
- return "Rpc failed";
+ return "RPC failed";
}
}
@@ -73,6 +81,10 @@ class GreeterClient {
};
int main(int argc, char** argv) {
+ // Instantiate the client. It requires a channel, out of which the actual RPCs
+ // are created. This channel models a connection to an endpoint (in this case,
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureCredentials()).
GreeterClient greeter(
grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
std::string user("world");
diff --git a/examples/cpp/helloworld/greeter_server.cc b/examples/cpp/helloworld/greeter_server.cc
index b434752d87..9eab32c62b 100644
--- a/examples/cpp/helloworld/greeter_server.cc
+++ b/examples/cpp/helloworld/greeter_server.cc
@@ -35,11 +35,8 @@
#include <memory>
#include <string>
-#include <grpc/grpc.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
+#include <grpc++/grpc++.h>
+
#include "helloworld.grpc.pb.h"
using grpc::Server;
@@ -50,6 +47,7 @@ using helloworld::HelloRequest;
using helloworld::HelloReply;
using helloworld::Greeter;
+// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
@@ -64,10 +62,17 @@ void RunServer() {
GreeterServiceImpl service;
ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
+ // Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
+
+ // Wait for the server to shutdown. Note that some other thread must be
+ // responsible for shutting down the server for this call to ever return.
server->Wait();
}
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index a8af74175b..60c816d58a 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -65,18 +65,19 @@ class ClientAsyncReaderWriter;
template <class R>
class ClientAsyncResponseReader;
+/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel GRPC_FINAL : public GrpcLibrary,
public CallHook,
public std::enable_shared_from_this<Channel> {
public:
~Channel();
- // Get the current channel state. If the channel is in IDLE and try_to_connect
- // is set to true, try to connect.
+ /// Get the current channel state. If the channel is in IDLE and
+ /// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect);
- // Return the tag on cq when the channel state is changed or deadline expires.
- // GetState needs to called to get the current state.
+ /// Return the \a tag on \a cq when the channel state is changed or \a
+ /// deadline expires. \a GetState needs to called to get the current state.
template <typename T>
void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
CompletionQueue* cq, void* tag) {
@@ -84,8 +85,8 @@ class Channel GRPC_FINAL : public GrpcLibrary,
NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
}
- // Blocking wait for channel state change or deadline expiration.
- // GetState needs to called to get the current state.
+ /// Blocking wait for channel state change or \a deadline expiration.
+ /// \a GetState needs to called to get the current state.
template <typename T>
bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
TimePoint<T> deadline_tp(deadline);
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 917a1222a8..7046f939e5 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -31,6 +31,21 @@
*
*/
+/// A ClientContext allows the person implementing a service client to:
+///
+/// - Add custom metadata key-value pairs that will propagated to the server
+/// side.
+/// - Control call settings such as compression and authentication.
+/// - Initial and trailing metadata coming from the server.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call they are invoked with, that
+/// is to say, they aren't sticky. Some of these settings, such as the
+/// compression options, can be made persistant at channel construction time
+/// (see \a grpc::CreateCustomChannel).
+///
+/// \warning ClientContext instances should \em not be reused across rpcs.
+
#ifndef GRPCXX_CLIENT_CONTEXT_H
#define GRPCXX_CLIENT_CONTEXT_H
@@ -72,6 +87,11 @@ template <class R>
class ClientAsyncResponseReader;
class ServerContext;
+/// Options for \a ClientContext::FromServerContext specifying which traits from
+/// the \a ServerContext to propagate (copy) from it into a new \a
+/// ClientContext.
+///
+/// \see ClientContext::FromServerContext
class PropagationOptions {
public:
PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
@@ -131,26 +151,66 @@ class ClientContext {
ClientContext();
~ClientContext();
- /// Create a new ClientContext that propagates some or all of its attributes
+ /// Create a new \a ClientContext as a child of an incoming server call,
+ /// according to \a options (\see PropagationOptions).
+ ///
+ /// \param server_context The source server context to use as the basis for
+ /// constructing the client context.
+ /// \param options The options controlling what to copy from the \a
+ /// server_context.
+ ///
+ /// \return A newly constructed \a ClientContext instance based on \a
+ /// server_context, with traits propagated (copied) according to \a options.
static std::unique_ptr<ClientContext> FromServerContext(
const ServerContext& server_context,
PropagationOptions options = PropagationOptions());
+ /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
+ /// a client call. These are made available at the server side by the \a
+ /// grpc::ServerContext::client_metadata() method.
+ ///
+ /// \warning This method should only be called before invoking the rpc.
+ ///
+ /// \param meta_key The metadata key. If \a meta_value is binary data, it must
+ /// end in "-bin".
+ /// \param meta_value The metadata value. If its value is binary, it must be
+ /// base64-encoding (see https://tools.ietf.org/html/rfc4648#section-4) and \a
+ /// meta_key must end in "-bin".
void AddMetadata(const grpc::string& meta_key,
const grpc::string& meta_value);
+ /// Return a collection of initial metadata key-value pairs. Note that keys
+ /// may happen more than once (ie, a \a std::multimap is returned).
+ ///
+ /// \warning This method should only be called after initial metadata has been
+ /// received. For streaming calls, see \a
+ /// ClientReaderInterface::WaitForInitialMetadata().
+ ///
+ /// \return A multimap of initial metadata key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerInitialMetadata() {
GPR_ASSERT(initial_metadata_received_);
return recv_initial_metadata_;
}
+ /// Return a collection of trailing metadata key-value pairs. Note that keys
+ /// may happen more than once (ie, a \a std::multimap is returned).
+ ///
+ /// \warning This method is only callable once the stream has finished.
+ ///
+ /// \return A multimap of metadata trailing key-value pairs from the server.
const std::multimap<grpc::string_ref, grpc::string_ref>&
GetServerTrailingMetadata() {
// TODO(yangg) check finished
return trailing_metadata_;
}
+ /// Set the deadline for the client call.
+ ///
+ /// \warning This method should only be called before invoking the rpc.
+ ///
+ /// \param deadline the deadline for the client call. Units are determined by
+ /// the type used.
template <typename T>
void set_deadline(const T& deadline) {
TimePoint<T> deadline_tp(deadline);
@@ -158,40 +218,65 @@ class ClientContext {
}
#ifndef GRPC_CXX0X_NO_CHRONO
+ /// Return the deadline for the client call.
std::chrono::system_clock::time_point deadline() {
return Timespec2Timepoint(deadline_);
}
#endif // !GRPC_CXX0X_NO_CHRONO
+ /// Return a \a gpr_timespec representation of the client call's deadline.
gpr_timespec raw_deadline() { return deadline_; }
+ /// Set the per call authority header (see
+ /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
void set_authority(const grpc::string& authority) { authority_ = authority; }
- // Set credentials for the rpc.
+ /// Return the authentication context for this client call.
+ ///
+ /// \see grpc::AuthContext.
+ std::shared_ptr<const AuthContext> auth_context() const;
+
+ /// Set credentials for the client call.
+ ///
+ /// A credentials object encapsulates all the state needed by a client to
+ /// authenticate with a server and make various assertions, e.g., about the
+ /// client’s identity, role, or whether it is authorized to make a particular
+ /// call.
+ ///
+ /// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
void set_credentials(const std::shared_ptr<Credentials>& creds) {
creds_ = creds;
}
+ /// Return the compression algorithm to be used by the client call.
grpc_compression_algorithm compression_algorithm() const {
return compression_algorithm_;
}
+ /// Set \a algorithm to be the compression algorithm used for the client call.
+ ///
+ /// \param algorith The compression algorithm used for the client call.
void set_compression_algorithm(grpc_compression_algorithm algorithm);
- std::shared_ptr<const AuthContext> auth_context() const;
-
- // Return the peer uri in a string.
- // WARNING: this value is never authenticated or subject to any security
- // related code. It must not be used for any authentication related
- // functionality. Instead, use auth_context.
+ /// Return the peer uri in a string.
+ ///
+ /// \warning This value is never authenticated or subject to any security
+ /// related code. It must not be used for any authentication related
+ /// functionality. Instead, use auth_context.
+ ///
+ /// \return The call's peer URI.
grpc::string peer() const;
- // Get and set census context
+ /// Get and set census context
void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
struct census_context* census_context() const {
return census_context_;
}
+ /// Send a best-effort out-of-band cancel. The call could be in any stage.
+ /// e.g. if it is already finished, it may still return success.
+ ///
+ /// There is no guarantee the call will be cancelled.
void TryCancel();
private:
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index d81d2e735d..0ea970417e 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -31,6 +31,8 @@
*
*/
+/// A completion queue implements a concurrent producer-consumer queue, with two
+/// main methods, \a Next and \a AsyncNext.
#ifndef GRPCXX_COMPLETION_QUEUE_H
#define GRPCXX_COMPLETION_QUEUE_H
@@ -67,53 +69,79 @@ class UnknownMethodHandler;
class Channel;
class ClientContext;
+class CompletionQueueTag;
class CompletionQueue;
class RpcMethod;
class Server;
class ServerBuilder;
class ServerContext;
-class CompletionQueueTag {
- public:
- virtual ~CompletionQueueTag() {}
- // Called prior to returning from Next(), return value
- // is the status of the operation (return status is the default thing
- // to do)
- // If this function returns false, the tag is dropped and not returned
- // from the completion queue
- virtual bool FinalizeResult(void** tag, bool* status) = 0;
-};
-
-// grpc_completion_queue wrapper class
+/// A thin wrapper around \a grpc_completion_queue (see / \a
+/// src/core/surface/completion_queue.h).
class CompletionQueue : public GrpcLibrary {
public:
+ /// Default constructor. Implicitly creates a \a grpc_completion_queue
+ /// instance.
CompletionQueue();
+
+ /// Wrap \a take, taking ownership of the instance.
+ ///
+ /// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
- ~CompletionQueue() GRPC_OVERRIDE;
- // Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT
- enum NextStatus { SHUTDOWN, GOT_EVENT, TIMEOUT };
+ /// Destructor. Destroys the owned wrapped completion queue / instance.
+ ~CompletionQueue() GRPC_OVERRIDE;
- // Nonblocking (until deadline) read from queue.
- // Cannot rely on result of tag or ok if return is TIMEOUT
+ /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
+ enum NextStatus {
+ SHUTDOWN, ///< The completion queue has been shutdown.
+ GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
+ ///< associated value; \a ok indicating its success.
+ TIMEOUT ///< deadline was reached.
+ };
+
+ /// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
+ /// Both \a tag and \a ok are updated upon success (if an event is available
+ /// within the \a deadline). A \a tag points to an arbitrary location usually
+ /// employed to uniquely identify an event.
+ ///
+ /// \param tag[out] Upon sucess, updated to point to the event's tag.
+ /// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
+ /// \param deadline[in] How long to block in wait for an event.
+ ///
+ /// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
- // Blocking read from queue.
- // Returns false if the queue is ready for destruction, true if event
-
+ /// Read from the queue, blocking until an event is available or the queue is
+ /// shutting down.
+ ///
+ /// \param tag[out] Updated to point to the read event's tag.
+ /// \param ok[out] true if read a regular event, false otherwise.
+ ///
+ /// \return true if read a regular event, false if the queue is shutting down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
SHUTDOWN);
}
- // Shutdown has to be called, and the CompletionQueue can only be
- // destructed when false is returned from Next().
+ /// Request the shutdown of the queue.
+ ///
+ /// \warning This method must be called at some point. Once invoked, \a Next
+ /// will start to return false and \a AsyncNext will return \a
+ /// NextStatus::SHUTDOWN. Only once either one of these methods does that
+ /// (that is, once the queue has been \em drained) can an instance of this
+ /// class be destroyed.
void Shutdown();
+ /// Returns a \em raw pointer to the underlying \a grpc_completion_queue
+ /// instance.
+ ///
+ /// \warning Remember that the returned instance is owned. No transfer of
+ /// owership is performed.
grpc_completion_queue* cq() { return cq_; }
private:
@@ -150,16 +178,29 @@ class CompletionQueue : public GrpcLibrary {
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
- // Wraps grpc_completion_queue_pluck.
- // Cannot be mixed with calls to Next().
+ /// Wraps \a grpc_completion_queue_pluck.
+ /// \warning Must not be mixed with calls to \a Next.
bool Pluck(CompletionQueueTag* tag);
- // Does a single polling pluck on tag
+ /// Performs a single polling pluck on \a tag.
void TryPluck(CompletionQueueTag* tag);
grpc_completion_queue* cq_; // owned
};
+/// An interface allowing implementors to process and filter event tags.
+class CompletionQueueTag {
+ public:
+ virtual ~CompletionQueueTag() {}
+ // Called prior to returning from Next(), return value is the status of the
+ // operation (return status is the default thing to do). If this function
+ // returns false, the tag is dropped and not returned from the completion
+ // queue
+ virtual bool FinalizeResult(void** tag, bool* status) = 0;
+};
+
+/// A specific type of completion queue used by the processing of notifications
+/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
private:
friend class ServerBuilder;
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 72f05174e1..196d2927a9 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -42,13 +42,24 @@
namespace grpc {
-// If creds does not hold an object or is invalid, a lame channel is returned.
+/// Create a new \a Channel pointing to \a target
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not hold
+/// an object or is invalid, a lame channel is returned.
+/// \param args Options for channel creation.
std::shared_ptr<Channel> CreateChannel(
const grpc::string& target, const std::shared_ptr<Credentials>& creds);
-// For advanced use and testing ONLY. Override default channel arguments only
-// if necessary.
-// If creds does not hold an object or is invalid, a lame channel is returned.
+/// Create a new \em custom \a Channel pointing to \a target
+///
+/// \warning For advanced use and testing ONLY. Override default channel
+/// arguments only if necessary.
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not hold
+/// an object or is invalid, a lame channel is returned.
+/// \param args Options for channel creation.
std::shared_ptr<Channel> CreateCustomChannel(
const grpc::string& target, const std::shared_ptr<Credentials>& creds,
const ChannelArguments& args);
diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h
new file mode 100644
index 0000000000..b7d5fb0bbc
--- /dev/null
+++ b/include/grpc++/grpc++.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/// \mainpage gRPC C++ API
+///
+/// The gRPC C++ API mainly consists of the following classes:
+/// - grpc::Channel, which represents the connection to an endpoint. See [the
+/// gRPC Concepts page](http://www.grpc.io/docs/guides/concepts.html) for more
+/// details. Channels are created by the factory function grpc::CreateChannel.
+/// - grpc::CompletionQueue, the producer-consumer queue used for all
+/// asynchronous communication with the gRPC runtime.
+/// - grpc::ClientContext and grpc::ServerContext, where optional configuration
+/// for an RPC can be set, such as setting custom metadata to be conveyed to the
+/// peer, compression settings, authentication, etc.
+/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
+///
+/// Refer to the
+/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
+/// for code putting these pieces into play.
+
+#ifndef GRPCXX_GRPCXX_H
+#define GRPCXX_GRPCXX_H
+
+#include <grpc/grpc.h>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/completion_queue.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+
+#endif // GRPCXX_GRPCXX_H
diff --git a/include/grpc++/security/auth_context.h b/include/grpc++/security/auth_context.h
index fc2701e806..4b1bbd85bc 100644
--- a/include/grpc++/security/auth_context.h
+++ b/include/grpc++/security/auth_context.h
@@ -37,6 +37,7 @@
#include <iterator>
#include <vector>
+#include <grpc/grpc_security.h>
#include <grpc++/support/config.h>
#include <grpc++/support/string_ref.h>
@@ -73,26 +74,41 @@ class AuthPropertyIterator
const char* name_;
};
+/// Class encapsulating the Authentication Information.
+///
+/// It includes the secure identity of the peer, the type of secure transport
+/// used as well as any other properties required by the authorization layer.
class AuthContext {
public:
virtual ~AuthContext() {}
- // Returns true if the peer is authenticated.
+ /// Returns true if the peer is authenticated.
virtual bool IsPeerAuthenticated() const = 0;
- // A peer identity, in general is one or more properties (in which case they
- // have the same name).
+ /// A peer identity.
+ ///
+ /// It is, in general, comprised of one or more properties (in which case they
+ /// have the same name).
virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
virtual grpc::string GetPeerIdentityPropertyName() const = 0;
- // Returns all the property values with the given name.
+ /// Returns all the property values with the given name.
virtual std::vector<grpc::string_ref> FindPropertyValues(
const grpc::string& name) const = 0;
- // Iteration over all the properties.
+ /// Iteration over all the properties.
virtual AuthPropertyIterator begin() const = 0;
virtual AuthPropertyIterator end() const = 0;
+ static string transport_security_type_property_name() {
+ return GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME;
+ }
+ static string ssl_transport_security_type() {
+ return GRPC_SSL_TRANSPORT_SECURITY_TYPE;
+ }
+ static string x509_cn_property_name() { return GRPC_X509_CN_PROPERTY_NAME; }
+ static string x509_san_property_name() { return GRPC_X509_SAN_PROPERTY_NAME; }
+
// Mutation functions: should only be used by an AuthMetadataProcessor.
virtual void AddProperty(const grpc::string& key,
const grpc::string_ref& value) = 0;
diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h
index ce5a9e0606..e423849714 100644
--- a/include/grpc++/security/credentials.h
+++ b/include/grpc++/security/credentials.h
@@ -44,9 +44,17 @@ class ChannelArguments;
class Channel;
class SecureCredentials;
+/// A credentials object encapsulates all the state needed by a client to
+/// authenticate with a server and make various assertions, e.g., about the
+/// client’s identity, role, or whether it is authorized to make a particular
+/// call.
+///
+/// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
class Credentials : public GrpcLibrary {
public:
~Credentials() GRPC_OVERRIDE;
+
+ /// Apply this instance's credentials to \a call.
virtual bool ApplyToCall(grpc_call* call) = 0;
protected:
@@ -65,68 +73,96 @@ class Credentials : public GrpcLibrary {
const grpc::string& target, const ChannelArguments& args) = 0;
};
-// Options used to build SslCredentials
-// pem_roots_cert is the buffer containing the PEM encoding of the server root
-// certificates. If this parameter is empty, the default roots will be used.
-// pem_private_key is the buffer containing the PEM encoding of the client's
-// private key. This parameter can be empty if the client does not have a
-// private key.
-// pem_cert_chain is the buffer containing the PEM encoding of the client's
-// certificate chain. This parameter can be empty if the client does not have
-// a certificate chain.
+/// Options used to build SslCredentials.
struct SslCredentialsOptions {
+ /// The buffer containing the PEM encoding of the server root certificates. If
+ /// this parameter is empty, the default roots will be used. The default
+ /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
+ /// environment variable pointing to a file on the file system containing the
+ /// roots.
grpc::string pem_root_certs;
+
+ /// The buffer containing the PEM encoding of the client's private key. This
+ /// parameter can be empty if the client does not have a private key.
grpc::string pem_private_key;
+
+ /// The buffer containing the PEM encoding of the client's certificate chain.
+ /// This parameter can be empty if the client does not have a certificate
+ /// chain.
grpc::string pem_cert_chain;
};
-// Factories for building different types of Credentials
-// The functions may return empty shared_ptr when credentials cannot be created.
-// If a Credentials pointer is returned, it can still be invalid when used to
-// create a channel. A lame channel will be created then and all rpcs will
-// fail on it.
-
-// Builds credentials with reasonable defaults.
+// Factories for building different types of Credentials The functions may
+// return empty shared_ptr when credentials cannot be created. If a
+// Credentials pointer is returned, it can still be invalid when used to create
+// a channel. A lame channel will be created then and all rpcs will fail on it.
+
+/// Builds credentials with reasonable defaults.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
std::shared_ptr<Credentials> GoogleDefaultCredentials();
-// Builds SSL Credentials given SSL specific options
+/// Builds SSL Credentials given SSL specific options
std::shared_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options);
-// Builds credentials for use when running in GCE
+/// Builds credentials for use when running in GCE
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
std::shared_ptr<Credentials> GoogleComputeEngineCredentials();
-// Builds Service Account JWT Access credentials.
-// json_key is the JSON key string containing the client's private key.
-// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
-// (JWT) created with this credentials. It should not exceed
-// grpc_max_auth_token_lifetime or will be cropped to this value.
+/// Builds Service Account JWT Access credentials.
+/// json_key is the JSON key string containing the client's private key.
+/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
+/// (JWT) created with this credentials. It should not exceed
+/// grpc_max_auth_token_lifetime or will be cropped to this value.
std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
const grpc::string& json_key, long token_lifetime_seconds);
-// Builds refresh token credentials.
-// json_refresh_token is the JSON string containing the refresh token along
-// with a client_id and client_secret.
+/// Builds refresh token credentials.
+/// json_refresh_token is the JSON string containing the refresh token along
+/// with a client_id and client_secret.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
std::shared_ptr<Credentials> GoogleRefreshTokenCredentials(
const grpc::string& json_refresh_token);
-// Builds access token credentials.
-// access_token is an oauth2 access token that was fetched using an out of band
-// mechanism.
+/// Builds access token credentials.
+/// access_token is an oauth2 access token that was fetched using an out of band
+/// mechanism.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
std::shared_ptr<Credentials> AccessTokenCredentials(
const grpc::string& access_token);
-// Builds IAM credentials.
+/// Builds IAM credentials.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
std::shared_ptr<Credentials> GoogleIAMCredentials(
const grpc::string& authorization_token,
const grpc::string& authority_selector);
-// Combines two credentials objects into a composite credentials
+/// Combines two credentials objects into a composite credentials
std::shared_ptr<Credentials> CompositeCredentials(
const std::shared_ptr<Credentials>& creds1,
const std::shared_ptr<Credentials>& creds2);
-// Credentials for an unencrypted, unauthenticated channel
+/// Credentials for an unencrypted, unauthenticated channel
std::shared_ptr<Credentials> InsecureCredentials();
} // namespace grpc
diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h
index 2094c7403c..e933825ec3 100644
--- a/include/grpc++/security/server_credentials.h
+++ b/include/grpc++/security/server_credentials.h
@@ -45,7 +45,7 @@ struct grpc_server;
namespace grpc {
class Server;
-// grpc_server_credentials wrapper class.
+// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
class ServerCredentials {
public:
virtual ~ServerCredentials();
@@ -58,11 +58,16 @@ class ServerCredentials {
private:
friend class ::grpc::Server;
+ /// Tries to bind \a server to the given \a addr (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.)
+ ///
+ /// \return bound port number on sucess, 0 on failure.
+ // TODO(dgq): the "port" part seems to be a misnomer.
virtual int AddPortToServer(const grpc::string& addr,
grpc_server* server) = 0;
};
-// Options to create ServerCredentials with SSL
+/// Options to create ServerCredentials with SSL
struct SslServerCredentialsOptions {
SslServerCredentialsOptions() : force_client_auth(false) {}
@@ -75,10 +80,11 @@ struct SslServerCredentialsOptions {
bool force_client_auth;
};
-// Builds SSL ServerCredentials given SSL specific options
+/// Builds SSL ServerCredentials given SSL specific options
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options);
+/// Builds insecure server credentials.
std::shared_ptr<ServerCredentials> InsecureServerCredentials();
} // namespace grpc
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 22d14ee652..18a8017880 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -57,24 +57,30 @@ class RpcServiceMethod;
class ServerAsyncStreamingInterface;
class ThreadPoolInterface;
-// Currently it only supports handling rpcs in a single thread.
+/// Models a gRPC server.
+///
+/// Servers are configured and started via \a grpc::ServerBuilder.
class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
public:
~Server();
- // Shutdown the server, block until all rpc processing finishes.
- // Forcefully terminate pending calls after deadline expires.
+ /// Shutdown the server, blocking until all rpc processing finishes.
+ /// Forcefully terminate pending calls after \a deadline expires.
+ ///
+ /// \param deadline How long to wait until pending rpcs are forcefully
+ /// terminated.
template <class T>
void Shutdown(const T& deadline) {
ShutdownInternal(TimePoint<T>(deadline).raw_time());
}
- // Shutdown the server, waiting for all rpc processing to finish.
+ /// Shutdown the server, waiting for all rpc processing to finish.
void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
- // Block waiting for all work to complete (the server must either
- // be shutting down or some other thread must call Shutdown for this
- // function to ever return)
+ /// Block waiting for all work to complete.
+ ///
+ /// \warning The server must be either shutting down or some other thread must
+ /// call \a Shutdown for this function to ever return.
void Wait();
private:
@@ -86,22 +92,57 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
class AsyncRequest;
class ShutdownRequest;
- // ServerBuilder use only
+ /// Server constructors. To be used by \a ServerBuilder only.
+ ///
+ /// \param thread_pool The threadpool instance to use for call processing.
+ /// \param thread_pool_owned Does the server own the \a thread_pool instance?
+ /// \param max_message_size Maximum message length that the channel can
+ /// receive.
Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
int max_message_size);
- // Register a service. This call does not take ownership of the service.
- // The service must exist for the lifetime of the Server instance.
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the Server instance.
bool RegisterService(const grpc::string* host, RpcService* service);
+
+ /// Register an asynchronous service. This call does not take ownership of the
+ /// service. The service must exist for the lifetime of the Server instance.
bool RegisterAsyncService(const grpc::string* host,
AsynchronousService* service);
+
+ /// Register a generic service. This call does not take ownership of the
+ /// service. The service must exist for the lifetime of the Server instance.
void RegisterAsyncGenericService(AsyncGenericService* service);
- // Add a listening port. Can be called multiple times.
+
+ /// Tries to bind \a server to the given \a addr.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr The address to try to bind to the server (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.).
+ /// \params creds The credentials associated with the server.
+ ///
+ /// \return bound port number on sucess, 0 on failure.
+ ///
+ /// \warning It's an error to call this method on an already started server.
int AddListeningPort(const grpc::string& addr, ServerCredentials* creds);
- // Start the server.
+
+ /// Start the server.
+ ///
+ /// \param cqs Completion queues for handling asynchronous services. The
+ /// caller is required to keep all completion queues live until the server is
+ /// destroyed.
+ /// \param num_cqs How many completion queues does \a cqs hold.
+ ///
+ /// \return true on a successful shutdown.
bool Start(ServerCompletionQueue** cqs, size_t num_cqs);
void HandleQueueClosed();
+
+ /// Process one or more incoming calls.
void RunRpc();
+
+ /// Schedule \a RunRpc to run in the threadpool.
void ScheduleCallback();
void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 8cd2048592..496e7862c5 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -51,57 +51,68 @@ class ServerCredentials;
class SynchronousService;
class ThreadPoolInterface;
+/// A builder class for the creation and startup of \a grpc::Server instances.
class ServerBuilder {
public:
ServerBuilder();
- // Register a service. This call does not take ownership of the service.
- // The service must exist for the lifetime of the Server instance returned by
- // BuildAndStart().
- // Matches requests with any :authority
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the \a Server instance returned
+ /// by \a BuildAndStart().
+ /// Matches requests with any :authority
void RegisterService(SynchronousService* service);
- // Register an asynchronous service.
- // This call does not take ownership of the service or completion queue.
- // The service and completion queuemust exist for the lifetime of the Server
- // instance returned by BuildAndStart().
- // Matches requests with any :authority
+ /// Register an asynchronous service.
+ /// This call does not take ownership of the service or completion queue.
+ /// The service and completion queuemust exist for the lifetime of the \a
+ /// Server instance returned by \a BuildAndStart().
+ /// Matches requests with any :authority
void RegisterAsyncService(AsynchronousService* service);
- // Register a generic service.
- // Matches requests with any :authority
+ /// Register a generic service.
+ /// Matches requests with any :authority
void RegisterAsyncGenericService(AsyncGenericService* service);
- // Register a service. This call does not take ownership of the service.
- // The service must exist for the lifetime of the Server instance returned by
- // BuildAndStart().
- // Only matches requests with :authority \a host
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the \a Server instance returned
+ /// by BuildAndStart().
+ /// Only matches requests with :authority \a host
void RegisterService(const grpc::string& host, SynchronousService* service);
- // Register an asynchronous service.
- // This call does not take ownership of the service or completion queue.
- // The service and completion queuemust exist for the lifetime of the Server
- // instance returned by BuildAndStart().
- // Only matches requests with :authority \a host
+ /// Register an asynchronous service.
+ /// This call does not take ownership of the service or completion queue.
+ /// The service and completion queuemust exist for the lifetime of the \a
+ /// Server instance returned by \a BuildAndStart().
+ /// Only matches requests with :authority equal to \a host
void RegisterAsyncService(const grpc::string& host,
AsynchronousService* service);
- // Set max message size in bytes.
+ /// Set max message size in bytes.
void SetMaxMessageSize(int max_message_size) {
max_message_size_ = max_message_size;
}
- // Add a listening port. Can be called multiple times.
+ /// Tries to bind \a server to the given \a addr.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr The address to try to bind to the server (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.).
+ /// \params creds The credentials associated with the server.
+ /// \param selected_port[out] Upon success, updated to contain the port
+ /// number. \a nullptr otherwise.
+ ///
+ // TODO(dgq): the "port" part seems to be a misnomer.
void AddListeningPort(const grpc::string& addr,
std::shared_ptr<ServerCredentials> creds,
int* selected_port = nullptr);
- // Add a completion queue for handling asynchronous services
- // Caller is required to keep this completion queue live until
- // the server is destroyed.
+ /// Add a completion queue for handling asynchronous services
+ /// Caller is required to keep this completion queue live until
+ /// the server is destroyed.
std::unique_ptr<ServerCompletionQueue> AddCompletionQueue();
- // Return a running server which is ready for processing rpcs.
+ /// Return a running server which is ready for processing calls.
std::unique_ptr<Server> BuildAndStart();
private:
diff --git a/include/grpc++/support/async_stream.h b/include/grpc++/support/async_stream.h
index 4c12fda12f..b4dae30cd5 100644
--- a/include/grpc++/support/async_stream.h
+++ b/include/grpc++/support/async_stream.h
@@ -45,32 +45,48 @@
namespace grpc {
-// Async interfaces
-// Common interface for all client side streaming.
+/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
public:
virtual ~ClientAsyncStreamingInterface() {}
+ /// Request notification of the reading of the initial metadata. Completion
+ /// will be notified by \a tag on the associated completion queue.
+ ///
+ /// \param[in] tag Tag identifying this request.
virtual void ReadInitialMetadata(void* tag) = 0;
+ /// Request notification completion.
+ ///
+ /// \param[out] status To be updated with the operation status.
+ /// \param[in] tag Tag identifying this request.
virtual void Finish(Status* status, void* tag) = 0;
};
-// An interface that yields a sequence of R messages.
+/// An interface that yields a sequence of messages of type \a R.
template <class R>
class AsyncReaderInterface {
public:
virtual ~AsyncReaderInterface() {}
+ /// Read a message of type \a R into \a msg. Completion will be notified by \a
+ /// tag on the associated completion queue.
+ ///
+ /// \param[out] msg Where to eventually store the read message.
+ /// \param[in] tag The tag identifying the operation.
virtual void Read(R* msg, void* tag) = 0;
};
-// An interface that can be fed a sequence of W messages.
+/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class AsyncWriterInterface {
public:
virtual ~AsyncWriterInterface() {}
+ /// Request the writing of \a msg with identifying tag \a tag.
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] tag The tag identifying the operation.
virtual void Write(const W& msg, void* tag) = 0;
};
@@ -81,7 +97,7 @@ class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
template <class R>
class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
public:
- // Create a stream and write the first request out.
+ /// Create a stream and write the first request out.
template <class W>
ClientAsyncReader(Channel* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
@@ -131,10 +147,14 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
};
+/// Common interface for client side asynchronous writing.
template <class W>
class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W> {
public:
+ /// Signal the client is done with the writes.
+ ///
+ /// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
@@ -194,12 +214,15 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
CallOpClientRecvStatus> finish_ops_;
};
-// Client-side interface for bi-directional streaming.
+/// Client-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> {
public:
+ /// Signal the client is done with the writes.
+ ///
+ /// \param[in] tag The tag identifying the operation.
virtual void WritesDone(void* tag) = 0;
};
@@ -373,7 +396,7 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
};
-// Server-side interface for bi-directional streaming.
+/// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W>,
diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h
index 3f8cc25f47..c413703970 100644
--- a/include/grpc++/support/byte_buffer.h
+++ b/include/grpc++/support/byte_buffer.h
@@ -46,21 +46,24 @@
namespace grpc {
+/// A sequence of bytes.
class ByteBuffer GRPC_FINAL {
public:
+ /// Constuct an empty buffer.
ByteBuffer() : buffer_(nullptr) {}
+ /// Construct buffer from \a slices, of which there are \a nslices.
ByteBuffer(const Slice* slices, size_t nslices);
- ~ByteBuffer() {
- if (buffer_) {
- grpc_byte_buffer_destroy(buffer_);
- }
- }
+ ~ByteBuffer();
+ /// Dump (read) the buffer contents into \a slices.
void Dump(std::vector<Slice>* slices) const;
+ /// Remove all data.
void Clear();
+
+ /// Buffer size in bytes.
size_t Length() const;
private:
@@ -78,6 +81,7 @@ class ByteBuffer GRPC_FINAL {
buffer_ = buf;
}
+ // For \a SerializationTraits's usage.
grpc_byte_buffer* buffer() const { return buffer_; }
grpc_byte_buffer* buffer_;
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index cee68467c7..9957712a96 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -46,9 +46,9 @@ namespace testing {
class ChannelArgumentsTest;
} // namespace testing
-// Options for channel creation. The user can use generic setters to pass
-// key value pairs down to c channel creation code. For grpc related options,
-// concrete setters are provided.
+/// Options for channel creation. The user can use generic setters to pass
+/// key value pairs down to c channel creation code. For grpc related options,
+/// concrete setters are provided.
class ChannelArguments {
public:
ChannelArguments() {}
@@ -62,21 +62,26 @@ class ChannelArguments {
void Swap(ChannelArguments& other);
- // grpc specific channel argument setters
- // Set target name override for SSL host name checking.
+ /// Populates this instance with the arguments from \a channel_args. Does not
+ /// take ownership of \a channel_args.
+ ///
+ /// Note that the underlying arguments are shared. Changes made to either \a
+ /// channel_args or this instance would be reflected on both.
+ void SetChannelArgs(grpc_channel_args* channel_args) const;
+
+ // gRPC specific channel argument setters
+ /// Set target name override for SSL host name checking.
void SetSslTargetNameOverride(const grpc::string& name);
// TODO(yangg) add flow control options
-
- // Set the compression algorithm for the channel.
+ /// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
// Generic channel argument setters. Only for advanced use cases.
+ /// Set an integer argument \a value under \a key.
void SetInt(const grpc::string& key, int value);
+ /// Set a textual argument \a value under \a key.
void SetString(const grpc::string& key, const grpc::string& value);
- // Populates given channel_args with args_, does not take ownership.
- void SetChannelArgs(grpc_channel_args* channel_args) const;
-
private:
friend class SecureCredentials;
friend class testing::ChannelArgumentsTest;
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index b2343a7f3d..456379cc5b 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -39,28 +39,42 @@
namespace grpc {
+/// A wrapper around \a grpc_slice.
+///
+/// A slice represents a contiguous reference counted array of bytes.
+/// It is cheap to take references to a slice, and it is cheap to create a
+/// slice pointing to a subset of another slice.
class Slice GRPC_FINAL {
public:
- // construct empty slice
+ /// Construct an empty slice.
Slice();
- // destructor - drops one ref
+ // Destructor - drops one reference.
~Slice();
- // construct slice from grpc slice, adding a ref
+
enum AddRef { ADD_REF };
+ /// Construct a slice from \a slice, adding a reference.
Slice(gpr_slice slice, AddRef);
- // construct slice from grpc slice, stealing a ref
+
enum StealRef { STEAL_REF };
+ /// Construct a slice from \a slice, stealing a reference.
Slice(gpr_slice slice, StealRef);
- // copy constructor - adds a ref
+
+ /// Copy constructor, adds a reference.
Slice(const Slice& other);
- // assignment - ref count is unchanged
+
+ /// Assignment, reference count is unchanged.
Slice& operator=(Slice other) {
std::swap(slice_, other.slice_);
return *this;
}
+ /// Byte size.
size_t size() const { return GPR_SLICE_LENGTH(slice_); }
+
+ /// Raw pointer to the beginning (first element) of the slice.
const gpr_uint8* begin() const { return GPR_SLICE_START_PTR(slice_); }
+
+ /// Raw pointer to the end (one byte \em past the last element) of the slice.
const gpr_uint8* end() const { return GPR_SLICE_END_PTR(slice_); }
private:
diff --git a/include/grpc++/support/status.h b/include/grpc++/support/status.h
index 05750ff600..e59bac92d1 100644
--- a/include/grpc++/support/status.h
+++ b/include/grpc++/support/status.h
@@ -39,19 +39,31 @@
namespace grpc {
+/// Did it work? If it didn't, why?
+///
+/// See \a grpc::StatusCode for details on the available code and their meaning.
class Status {
public:
+ /// Construct an OK instance.
Status() : code_(StatusCode::OK) {}
+
+ /// Construct an instance with associated \a code and \a details (also
+ // referred to as "error_message").
Status(StatusCode code, const grpc::string& details)
: code_(code), details_(details) {}
// Pre-defined special status objects.
+ /// An OK pre-defined instance.
static const Status& OK;
+ /// A CANCELLED pre-defined instance.
static const Status& CANCELLED;
+ /// Return the instance's error code.
StatusCode error_code() const { return code_; }
+ /// Return the instance's error message.
grpc::string error_message() const { return details_; }
+ /// Is the status OK?
bool ok() const { return code_ == StatusCode::OK; }
private:
diff --git a/include/grpc++/support/status_code_enum.h b/include/grpc++/support/status_code_enum.h
index 7cb40452c8..ee05b40b51 100644
--- a/include/grpc++/support/status_code_enum.h
+++ b/include/grpc++/support/status_code_enum.h
@@ -37,120 +37,113 @@
namespace grpc {
enum StatusCode {
- /* Not an error; returned on success */
+ /// Not an error; returned on success.
OK = 0,
- /* The operation was cancelled (typically by the caller). */
+ /// The operation was cancelled (typically by the caller).
CANCELLED = 1,
- /* Unknown error. An example of where this error may be returned is
- if a Status value received from another address space belongs to
- an error-space that is not known in this address space. Also
- errors raised by APIs that do not return enough error information
- may be converted to this error. */
+ /// Unknown error. An example of where this error may be returned is if a
+ /// Status value received from another address space belongs to an error-space
+ /// that is not known in this address space. Also errors raised by APIs that
+ /// do not return enough error information may be converted to this error.
UNKNOWN = 2,
- /* Client specified an invalid argument. Note that this differs
- from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
- that are problematic regardless of the state of the system
- (e.g., a malformed file name). */
+ /// Client specified an invalid argument. Note that this differs from
+ /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
+ /// problematic regardless of the state of the system (e.g., a malformed file
+ /// name).
INVALID_ARGUMENT = 3,
- /* Deadline expired before operation could complete. For operations
- that change the state of the system, this error may be returned
- even if the operation has completed successfully. For example, a
- successful response from a server could have been delayed long
- enough for the deadline to expire. */
+ /// Deadline expired before operation could complete. For operations that
+ /// change the state of the system, this error may be returned even if the
+ /// operation has completed successfully. For example, a successful response
+ /// from a server could have been delayed long enough for the deadline to
+ /// expire.
DEADLINE_EXCEEDED = 4,
- /* Some requested entity (e.g., file or directory) was not found. */
+ /// Some requested entity (e.g., file or directory) was not found.
NOT_FOUND = 5,
- /* Some entity that we attempted to create (e.g., file or directory)
- already exists. */
+ /// Some entity that we attempted to create (e.g., file or directory) already
+ /// exists.
ALREADY_EXISTS = 6,
- /* The caller does not have permission to execute the specified
- operation. PERMISSION_DENIED must not be used for rejections
- caused by exhausting some resource (use RESOURCE_EXHAUSTED
- instead for those errors). PERMISSION_DENIED must not be
- used if the caller can not be identified (use UNAUTHENTICATED
- instead for those errors). */
+ /// The caller does not have permission to execute the specified operation.
+ /// PERMISSION_DENIED must not be used for rejections caused by exhausting
+ /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
+ /// PERMISSION_DENIED must not be used if the caller can not be identified
+ /// (use UNAUTHENTICATED instead for those errors).
PERMISSION_DENIED = 7,
- /* The request does not have valid authentication credentials for the
- operation. */
+ /// The request does not have valid authentication credentials for the
+ /// operation.
UNAUTHENTICATED = 16,
- /* Some resource has been exhausted, perhaps a per-user quota, or
- perhaps the entire file system is out of space. */
+ /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+ /// entire file system is out of space.
RESOURCE_EXHAUSTED = 8,
- /* Operation was rejected because the system is not in a state
- required for the operation's execution. For example, directory
- to be deleted may be non-empty, an rmdir operation is applied to
- a non-directory, etc.
-
- A litmus test that may help a service implementor in deciding
- between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
- (a) Use UNAVAILABLE if the client can retry just the failing call.
- (b) Use ABORTED if the client should retry at a higher-level
- (e.g., restarting a read-modify-write sequence).
- (c) Use FAILED_PRECONDITION if the client should not retry until
- the system state has been explicitly fixed. E.g., if an "rmdir"
- fails because the directory is non-empty, FAILED_PRECONDITION
- should be returned since the client should not retry unless
- they have first fixed up the directory by deleting files from it.
- (d) Use FAILED_PRECONDITION if the client performs conditional
- REST Get/Update/Delete on a resource and the resource on the
- server does not match the condition. E.g., conflicting
- read-modify-write on the same resource. */
+ /// Operation was rejected because the system is not in a state required for
+ /// the operation's execution. For example, directory to be deleted may be
+ /// non-empty, an rmdir operation is applied to a non-directory, etc.
+ ///
+ /// A litmus test that may help a service implementor in deciding
+ /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ /// (a) Use UNAVAILABLE if the client can retry just the failing call.
+ /// (b) Use ABORTED if the client should retry at a higher-level
+ /// (e.g., restarting a read-modify-write sequence).
+ /// (c) Use FAILED_PRECONDITION if the client should not retry until
+ /// the system state has been explicitly fixed. E.g., if an "rmdir"
+ /// fails because the directory is non-empty, FAILED_PRECONDITION
+ /// should be returned since the client should not retry unless
+ /// they have first fixed up the directory by deleting files from it.
+ /// (d) Use FAILED_PRECONDITION if the client performs conditional
+ /// REST Get/Update/Delete on a resource and the resource on the
+ /// server does not match the condition. E.g., conflicting
+ /// read-modify-write on the same resource.
FAILED_PRECONDITION = 9,
- /* The operation was aborted, typically due to a concurrency issue
- like sequencer check failures, transaction aborts, etc.
-
- See litmus test above for deciding between FAILED_PRECONDITION,
- ABORTED, and UNAVAILABLE. */
+ /// The operation was aborted, typically due to a concurrency issue like
+ /// sequencer check failures, transaction aborts, etc.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
ABORTED = 10,
- /* Operation was attempted past the valid range. E.g., seeking or
- reading past end of file.
-
- Unlike INVALID_ARGUMENT, this error indicates a problem that may
- be fixed if the system state changes. For example, a 32-bit file
- system will generate INVALID_ARGUMENT if asked to read at an
- offset that is not in the range [0,2^32-1], but it will generate
- OUT_OF_RANGE if asked to read from an offset past the current
- file size.
-
- There is a fair bit of overlap between FAILED_PRECONDITION and
- OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
- error) when it applies so that callers who are iterating through
- a space can easily look for an OUT_OF_RANGE error to detect when
- they are done. */
+ /// Operation was attempted past the valid range. E.g., seeking or reading
+ /// past end of file.
+ ///
+ /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
+ /// if the system state changes. For example, a 32-bit file system will
+ /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
+ /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
+ /// an offset past the current file size.
+ ///
+ /// There is a fair bit of overlap between FAILED_PRECONDITION and
+ /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
+ /// when it applies so that callers who are iterating through a space can
+ /// easily look for an OUT_OF_RANGE error to detect when they are done.
OUT_OF_RANGE = 11,
- /* Operation is not implemented or not supported/enabled in this service. */
+ /// Operation is not implemented or not supported/enabled in this service.
UNIMPLEMENTED = 12,
- /* Internal errors. Means some invariants expected by underlying
- system has been broken. If you see one of these errors,
- something is very broken. */
+ /// Internal errors. Means some invariants expected by underlying System has
+ /// been broken. If you see one of these errors, Something is very broken.
INTERNAL = 13,
- /* The service is currently unavailable. This is a most likely a
- transient condition and may be corrected by retrying with
- a backoff.
-
- See litmus test above for deciding between FAILED_PRECONDITION,
- ABORTED, and UNAVAILABLE. */
+ /// The service is currently unavailable. This is a most likely a transient
+ /// condition and may be corrected by retrying with a backoff.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
UNAVAILABLE = 14,
- /* Unrecoverable data loss or corruption. */
+ /// Unrecoverable data loss or corruption.
DATA_LOSS = 15,
- /* Force users to include a default branch: */
+ /// Force users to include a default branch:
DO_NOT_USE = -1
};
diff --git a/include/grpc++/support/string_ref.h b/include/grpc++/support/string_ref.h
index 2bc1fecefe..a17e167d2b 100644
--- a/include/grpc++/support/string_ref.h
+++ b/include/grpc++/support/string_ref.h
@@ -41,11 +41,14 @@
namespace grpc {
-// This class is a non owning reference to a string.
-// It should be a strict subset of the upcoming std::string_ref. See:
-// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
-// The constexpr is dropped or replaced with const for legacy compiler
-// compatibility.
+/// This class is a non owning reference to a string.
+///
+/// It should be a strict subset of the upcoming std::string_ref.
+///
+/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+///
+/// The constexpr is dropped or replaced with const for legacy compiler
+/// compatibility.
class string_ref {
public:
// types
diff --git a/include/grpc++/support/sync_stream.h b/include/grpc++/support/sync_stream.h
index b4bb637ff2..514363338d 100644
--- a/include/grpc++/support/sync_stream.h
+++ b/include/grpc++/support/sync_stream.h
@@ -45,60 +45,78 @@
namespace grpc {
-// Common interface for all client side streaming.
+/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
virtual ~ClientStreamingInterface() {}
- // Wait until the stream finishes, and return the final status. When the
- // client side declares it has no more message to send, either implicitly or
- // by calling WritesDone, it needs to make sure there is no more message to
- // be received from the server, either implicitly or by getting a false from
- // a Read().
- // This function will return either:
- // - when all incoming messages have been read and the server has returned
- // status
- // - OR when the server has returned a non-OK status
+ /// Wait until the stream finishes, and return the final status. When the
+ /// client side declares it has no more message to send, either implicitly or
+ /// by calling \a WritesDone(), it needs to make sure there is no more message
+ /// to be received from the server, either implicitly or by getting a false
+ /// from a \a Read().
+ ///
+ /// This function will return either:
+ /// - when all incoming messages have been read and the server has returned
+ /// status.
+ /// - OR when the server has returned a non-OK status.
virtual Status Finish() = 0;
};
-// An interface that yields a sequence of R messages.
+/// An interface that yields a sequence of messages of type \a R.
template <class R>
class ReaderInterface {
public:
virtual ~ReaderInterface() {}
- // Blocking read a message and parse to msg. Returns true on success.
- // The method returns false when there will be no more incoming messages,
- // either because the other side has called WritesDone or the stream has
- // failed (or been cancelled).
+ /// Blocking read a message and parse to \a msg. Returns \a true on success.
+ ///
+ /// \param[out] msg The read message.
+ ///
+ /// \return \a false when there will be no more incoming messages, either
+ /// because the other side has called \a WritesDone() or the stream has failed
+ /// (or been cancelled).
virtual bool Read(R* msg) = 0;
};
-// An interface that can be fed a sequence of W messages.
+/// An interface that can be fed a sequence of messages of type \a W.
template <class W>
class WriterInterface {
public:
virtual ~WriterInterface() {}
- // Blocking write msg to the stream. Returns true on success.
- // Returns false when the stream has been closed.
+ /// Blocking write \a msg to the stream with options.
+ ///
+ /// \param msg The message to be written to the stream.
+ /// \param options Options affecting the write operation.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
virtual bool Write(const W& msg, const WriteOptions& options) = 0;
+ /// Blocking write \a msg to the stream with default options.
+ ///
+ /// \param msg The message to be written to the stream.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
};
+/// Client-side interface for streaming reads of message of type \a R.
template <class R>
class ClientReaderInterface : public ClientStreamingInterface,
public ReaderInterface<R> {
public:
+ /// Blocking wait for initial metadata from server. The received metadata
+ /// can only be accessed after this call returns. Should only be called before
+ /// the first read. Calling this method is optional, and if it is not called
+ /// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
};
template <class R>
class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
public:
- // Blocking create a stream and write the first request out.
+ /// Blocking create a stream and write the first request out.
template <class W>
ClientReader(Channel* channel, const RpcMethod& method,
ClientContext* context, const W& request)
@@ -113,17 +131,13 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
cq_.Pluck(&ops);
}
- // Blocking wait for initial metadata from server. The received metadata
- // can only be accessed after this call returns. Should only be called before
- // the first read. Calling this method is optional, and if it is not called
- // the metadata will be available in ClientContext after the first read.
void WaitForInitialMetadata() {
GPR_ASSERT(!context_->initial_metadata_received_);
CallOpSet<CallOpRecvInitialMetadata> ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
- cq_.Pluck(&ops); // status ignored
+ cq_.Pluck(&ops); /// status ignored
}
bool Read(R* msg) GRPC_OVERRIDE {
@@ -151,17 +165,22 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
Call call_;
};
+/// Client-side interface for streaming writes of message of type \a W.
template <class W>
class ClientWriterInterface : public ClientStreamingInterface,
public WriterInterface<W> {
public:
+ /// Half close writing from the client.
+ /// Block until writes are completed.
+ ///
+ /// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
- // Blocking create a stream.
+ /// Blocking create a stream.
template <class R>
ClientWriter(Channel* channel, const RpcMethod& method,
ClientContext* context, R* response)
@@ -191,7 +210,7 @@ class ClientWriter : public ClientWriterInterface<W> {
return cq_.Pluck(&ops);
}
- // Read the final response and wait for the final status.
+ /// Read the final response and wait for the final status.
Status Finish() GRPC_OVERRIDE {
Status status;
finish_ops_.ClientRecvStatus(context_, &status);
@@ -207,20 +226,28 @@ class ClientWriter : public ClientWriterInterface<W> {
Call call_;
};
-// Client-side interface for bi-directional streaming.
+/// Client-side interface for bi-directional streaming.
template <class W, class R>
class ClientReaderWriterInterface : public ClientStreamingInterface,
public WriterInterface<W>,
public ReaderInterface<R> {
public:
+ /// Blocking wait for initial metadata from server. The received metadata
+ /// can only be accessed after this call returns. Should only be called before
+ /// the first read. Calling this method is optional, and if it is not called
+ /// the metadata will be available in ClientContext after the first read.
virtual void WaitForInitialMetadata() = 0;
+
+ /// Block until writes are completed.
+ ///
+ /// \return Whether the writes were successful.
virtual bool WritesDone() = 0;
};
template <class W, class R>
class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
public:
- // Blocking create a stream.
+ /// Blocking create a stream.
ClientReaderWriter(Channel* channel, const RpcMethod& method,
ClientContext* context)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
@@ -230,10 +257,6 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
cq_.Pluck(&ops);
}
- // Blocking wait for initial metadata from server. The received metadata
- // can only be accessed after this call returns. Should only be called before
- // the first read. Calling this method is optional, and if it is not called
- // the metadata will be available in ClientContext after the first read.
void WaitForInitialMetadata() {
GPR_ASSERT(!context_->initial_metadata_received_);
@@ -344,7 +367,7 @@ class ServerWriter GRPC_FINAL : public WriterInterface<W> {
ServerContext* const ctx_;
};
-// Server-side interface for bi-directional streaming.
+/// Server-side interface for bi-directional streaming.
template <class W, class R>
class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
public ReaderInterface<R> {
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index a75f356312..47f3df6605 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -47,11 +47,9 @@ extern "C" {
/*! \mainpage GRPC Core
*
- * \section intro_sec The GRPC Core library is a low-level library designed
- * to be wrapped by higher level libraries.
- *
- * The top-level API is provided in grpc.h.
- * Security related functionality lives in grpc_security.h.
+ * The GRPC Core library is a low-level library designed to be wrapped by higher
+ * level libraries. The top-level API is provided in grpc.h. Security related
+ * functionality lives in grpc_security.h.
*/
/** Completion Queues enable notification of the completion of asynchronous
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 8de024aaea..74dc09e36e 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -34,7 +34,7 @@
#ifndef GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
#define GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
-/* Internal API for completion channels */
+/* Internal API for completion queues */
#include "src/core/iomgr/pollset.h"
#include <grpc/grpc.h>
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index e46e656beb..755234d7e8 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -45,6 +45,12 @@ ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) {
buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices);
}
+ByteBuffer::~ByteBuffer() {
+ if (buffer_) {
+ grpc_byte_buffer_destroy(buffer_);
+ }
+}
+
void ByteBuffer::Clear() {
if (buffer_) {
grpc_byte_buffer_destroy(buffer_);