aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/grpc++/alarm.h2
-rw-r--r--include/grpc++/channel.h16
-rw-r--r--include/grpc++/generic/async_generic_service.h17
-rw-r--r--include/grpc++/impl/channel_argument_option.h4
-rw-r--r--include/grpc++/impl/codegen/async_stream.h239
-rw-r--r--include/grpc++/impl/codegen/async_unary_call.h73
-rw-r--r--include/grpc++/impl/codegen/byte_buffer.h21
-rw-r--r--include/grpc++/impl/codegen/call.h65
-rw-r--r--include/grpc++/impl/codegen/call_hook.h2
-rw-r--r--include/grpc++/impl/codegen/channel_interface.h45
-rw-r--r--include/grpc++/impl/codegen/client_context.h37
-rw-r--r--include/grpc++/impl/codegen/client_unary_call.h74
-rw-r--r--include/grpc++/impl/codegen/completion_queue.h127
-rw-r--r--include/grpc++/impl/codegen/completion_queue_tag.h2
-rw-r--r--include/grpc++/impl/codegen/config_protobuf.h2
-rw-r--r--include/grpc++/impl/codegen/core_codegen.h4
-rw-r--r--include/grpc++/impl/codegen/core_codegen_interface.h12
-rw-r--r--include/grpc++/impl/codegen/metadata_map.h40
-rw-r--r--include/grpc++/impl/codegen/method_handler_impl.h39
-rw-r--r--include/grpc++/impl/codegen/proto_utils.h133
-rw-r--r--include/grpc++/impl/codegen/rpc_method.h3
-rw-r--r--include/grpc++/impl/codegen/rpc_service_method.h3
-rw-r--r--include/grpc++/impl/codegen/server_context.h27
-rw-r--r--include/grpc++/impl/codegen/server_interface.h42
-rw-r--r--include/grpc++/impl/codegen/service_type.h46
-rw-r--r--include/grpc++/impl/codegen/sync_stream.h327
-rw-r--r--include/grpc++/impl/codegen/time.h6
-rw-r--r--include/grpc++/server.h3
-rw-r--r--include/grpc++/server_builder.h147
-rw-r--r--include/grpc++/support/channel_arguments.h8
-rw-r--r--include/grpc/census.h433
-rw-r--r--include/grpc/compression.h47
-rw-r--r--include/grpc/compression_ruby.h48
-rw-r--r--include/grpc/fork.h (renamed from include/grpc/impl/codegen/exec_ctx_fwd.h)12
-rw-r--r--include/grpc/grpc.h215
-rw-r--r--include/grpc/grpc_cronet.h6
-rw-r--r--include/grpc/grpc_posix.h8
-rw-r--r--include/grpc/grpc_security.h275
-rw-r--r--include/grpc/grpc_security_constants.h7
-rw-r--r--include/grpc/impl/codegen/atm.h10
-rw-r--r--include/grpc/impl/codegen/atm_gcc_atomic.h17
-rw-r--r--include/grpc/impl/codegen/atm_gcc_sync.h11
-rw-r--r--include/grpc/impl/codegen/atm_windows.h45
-rw-r--r--include/grpc/impl/codegen/byte_buffer.h28
-rw-r--r--include/grpc/impl/codegen/byte_buffer_reader.h4
-rw-r--r--include/grpc/impl/codegen/compression_types.h70
-rw-r--r--include/grpc/impl/codegen/connectivity_state.h2
-rw-r--r--include/grpc/impl/codegen/fork.h48
-rw-r--r--include/grpc/impl/codegen/grpc_types.h74
-rw-r--r--include/grpc/impl/codegen/port_platform.h94
-rw-r--r--include/grpc/impl/codegen/slice.h21
-rw-r--r--include/grpc/impl/codegen/sync_generic.h12
-rw-r--r--include/grpc/module.modulemap77
-rw-r--r--include/grpc/slice.h33
-rw-r--r--include/grpc/slice_buffer.h43
-rw-r--r--include/grpc/support/alloc.h25
-rw-r--r--include/grpc/support/avl.h48
-rw-r--r--include/grpc/support/cmdline.h26
-rw-r--r--include/grpc/support/histogram.h64
-rw-r--r--include/grpc/support/host_port.h4
-rw-r--r--include/grpc/support/log.h24
-rw-r--r--include/grpc/support/log_windows.h2
-rw-r--r--include/grpc/support/string_util.h4
-rw-r--r--include/grpc/support/subprocess.h10
-rw-r--r--include/grpc/support/sync.h70
-rw-r--r--include/grpc/support/thd.h15
-rw-r--r--include/grpc/support/tls.h6
-rw-r--r--include/grpc/support/tls_gcc.h45
-rw-r--r--include/grpc/support/tls_msvc.h9
-rw-r--r--include/grpc/support/tls_pthread.h11
70 files changed, 1891 insertions, 1678 deletions
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 2d88d868e5..b43425e224 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -92,7 +92,7 @@ class Alarm : private GrpcLibraryCodegen {
}
private:
- class AlarmEntry : public CompletionQueueTag {
+ class AlarmEntry : public internal::CompletionQueueTag {
public:
AlarmEntry(void* tag) : tag_(tag) {}
void Set(void* tag) { tag_ = tag; }
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index c50091d6ac..e9fb5a5d09 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -32,7 +32,7 @@ struct grpc_channel;
namespace grpc {
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ChannelInterface,
- public CallHook,
+ public internal::CallHook,
public std::enable_shared_from_this<Channel>,
private GrpcLibraryCodegen {
public:
@@ -51,18 +51,16 @@ class Channel final : public ChannelInterface,
private:
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class internal::BlockingUnaryCallImpl;
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel);
Channel(const grpc::string& host, grpc_channel* c_channel);
- Call CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq) override;
- void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) override;
+ internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) override;
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
diff --git a/include/grpc++/generic/async_generic_service.h b/include/grpc++/generic/async_generic_service.h
index cd9a65e3cb..b1ea4f3909 100644
--- a/include/grpc++/generic/async_generic_service.h
+++ b/include/grpc++/generic/async_generic_service.h
@@ -42,6 +42,23 @@ class GenericServerContext final : public ServerContext {
grpc::string host_;
};
+// A generic service at the server side accepts all RPC methods and hosts. It is
+// typically used in proxies. The generic service can be registered to a server
+// which also has other services.
+// Sample usage:
+// ServerBuilder builder;
+// auto cq = builder.AddCompletionQueue();
+// AsyncGenericService generic_service;
+// builder.RegisterAsyncGeneicService(&generic_service);
+// auto server = builder.BuildAndStart();
+//
+// // request a new call
+// GenericServerContext context;
+// GenericAsyncReaderWriter stream;
+// generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
+//
+// When tag is retrieved from cq->Next(), context.method() can be used to look
+// at the method and the RPC can be handled accordingly.
class AsyncGenericService final {
public:
AsyncGenericService() : server_(nullptr) {}
diff --git a/include/grpc++/impl/channel_argument_option.h b/include/grpc++/impl/channel_argument_option.h
index e918f57e92..f157ec1d7e 100644
--- a/include/grpc++/impl/channel_argument_option.h
+++ b/include/grpc++/impl/channel_argument_option.h
@@ -28,9 +28,9 @@
namespace grpc {
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
- const grpc::string &name, const grpc::string &value);
+ const grpc::string& name, const grpc::string& value);
std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
- const grpc::string &name, int value);
+ const grpc::string& name, int value);
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index e60572fc93..4476033463 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -30,6 +30,7 @@ namespace grpc {
class CompletionQueue;
+namespace internal {
/// Common interface for all client side asynchronous streaming.
class ClientAsyncStreamingInterface {
public:
@@ -151,15 +152,16 @@ class AsyncWriterInterface {
}
};
+} // namespace internal
+
template <class R>
-class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
- public AsyncReaderInterface<R> {};
+class ClientAsyncReaderInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {};
-/// Async client-side API for doing server-streaming RPCs,
-/// where the incoming message stream coming from the server has
-/// messages of type \a R.
+namespace internal {
template <class R>
-class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
+class ClientAsyncReaderFactory {
public:
/// Create a stream object.
/// Write the first request out if \a start is set.
@@ -169,16 +171,25 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
- static ClientAsyncReader* Create(ChannelInterface* channel,
- CompletionQueue* cq, const RpcMethod& method,
- ClientContext* context, const W& request,
- bool start, void* tag) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncReader<R>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReader)))
- ClientAsyncReader(call, context, request, start, tag);
+ call.call(), sizeof(ClientAsyncReader<R>)))
+ ClientAsyncReader<R>(call, context, request, start, tag);
}
+};
+} // namespace internal
+/// Async client-side API for doing server-streaming RPCs,
+/// where the incoming message stream coming from the server has
+/// messages of type \a R.
+template <class R>
+class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncReader));
@@ -233,9 +244,10 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
}
private:
+ friend class internal::ClientAsyncReaderFactory<R>;
template <class W>
- ClientAsyncReader(Call call, ClientContext* context, const W& request,
- bool start, void* tag)
+ ClientAsyncReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start, void* tag)
: context_(context), call_(call), started_(start) {
// TODO(ctiller): don't assert
GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
@@ -255,19 +267,27 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
init_ops_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
};
/// Common interface for client side asynchronous writing.
template <class W>
-class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W> {
+class ClientAsyncWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
public:
/// Signal the client is done with the writes (half-close the client stream).
/// Thread-safe with respect to \a AsyncReaderInterface::Read
@@ -276,11 +296,9 @@ class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
virtual void WritesDone(void* tag) = 0;
};
-/// Async API on the client side for doing client-streaming RPCs,
-/// where the outgoing message stream going to the server contains
-/// messages of type \a W.
+namespace internal {
template <class W>
-class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
+class ClientAsyncWriterFactory {
public:
/// Create a stream object.
/// Start the RPC if \a start is set
@@ -294,16 +312,25 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
/// message from the server upon a successful call to the \a Finish
/// method of this instance.
template <class R>
- static ClientAsyncWriter* Create(ChannelInterface* channel,
- CompletionQueue* cq, const RpcMethod& method,
- ClientContext* context, R* response,
- bool start, void* tag) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncWriter<W>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncWriter)))
- ClientAsyncWriter(call, context, response, start, tag);
+ call.call(), sizeof(ClientAsyncWriter<W>)))
+ ClientAsyncWriter<W>(call, context, response, start, tag);
}
+};
+} // namespace internal
+/// Async API on the client side for doing client-streaming RPCs,
+/// where the outgoing message stream going to the server contains
+/// messages of type \a W.
+template <class W>
+class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncWriter));
@@ -376,9 +403,10 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
}
private:
+ friend class internal::ClientAsyncWriterFactory<W>;
template <class R>
- ClientAsyncWriter(Call call, ClientContext* context, R* response, bool start,
- void* tag)
+ ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context,
+ R* response, bool start, void* tag)
: context_(context), call_(call), started_(start) {
finish_ops_.RecvMessage(response);
finish_ops_.AllowNoMessage();
@@ -401,13 +429,17 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
write_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
};
@@ -415,9 +447,10 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
/// where the client-to-server message stream has messages of type \a W,
/// and the server-to-client message stream has messages of type \a R.
template <class W, class R>
-class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W>,
- public AsyncReaderInterface<R> {
+class ClientAsyncReaderWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
public:
/// Signal the client is done with the writes (half-close the client stream).
/// Thread-safe with respect to \a AsyncReaderInterface::Read
@@ -426,13 +459,9 @@ class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
virtual void WritesDone(void* tag) = 0;
};
-/// Async client-side interface for bi-directional streaming,
-/// where the outgoing message stream going to the server
-/// has messages of type \a W, and the incoming message stream coming
-/// from the server has messages of type \a R.
+namespace internal {
template <class W, class R>
-class ClientAsyncReaderWriter final
- : public ClientAsyncReaderWriterInterface<W, R> {
+class ClientAsyncReaderWriterFactory {
public:
/// Create a stream object.
/// Start the RPC request if \a start is set.
@@ -441,18 +470,27 @@ class ClientAsyncReaderWriter final
/// nullptr and the actual call must be initiated by StartCall
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
- static ClientAsyncReaderWriter* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const RpcMethod& method,
- ClientContext* context, bool start,
- void* tag) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncReaderWriter<W, R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReaderWriter)))
- ClientAsyncReaderWriter(call, context, start, tag);
+ call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
+ ClientAsyncReaderWriter<W, R>(call, context, start, tag);
}
+};
+} // namespace internal
+/// Async client-side interface for bi-directional streaming,
+/// where the outgoing message stream going to the server
+/// has messages of type \a W, and the incoming message stream coming
+/// from the server has messages of type \a R.
+template <class W, class R>
+class ClientAsyncReaderWriter final
+ : public ClientAsyncReaderWriterInterface<W, R> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncReaderWriter));
@@ -532,8 +570,9 @@ class ClientAsyncReaderWriter final
}
private:
- ClientAsyncReaderWriter(Call call, ClientContext* context, bool start,
- void* tag)
+ friend class internal::ClientAsyncReaderWriterFactory<W, R>;
+ ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context,
+ bool start, void* tag)
: context_(context), call_(call), started_(start) {
if (start) {
StartCallInternal(tag);
@@ -554,18 +593,26 @@ class ClientAsyncReaderWriter final
}
ClientContext* context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
- CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
write_ops_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
};
template <class W, class R>
-class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
- public AsyncReaderInterface<R> {
+class ServerAsyncReaderInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {
public:
/// Indicate that the stream is to be finished with a certain status code
/// and also send out \a msg response to the client.
@@ -692,20 +739,23 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
finish_ops_;
};
template <class W>
-class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
- public AsyncWriterInterface<W> {
+class ServerAsyncWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
public:
/// Indicate that the stream is to be finished with a certain status code.
/// Request notification for when the server has sent the appropriate
@@ -823,7 +873,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
template <class T>
void EnsureInitialMetadataSent(T* ops) {
@@ -837,20 +887,25 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
}
}
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
write_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
};
/// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R>
-class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
- public AsyncWriterInterface<W>,
- public AsyncReaderInterface<R> {
+class ServerAsyncReaderWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
public:
/// Indicate that the stream is to be finished with a certain status code.
/// Request notification for when the server has sent the appropriate
@@ -980,7 +1035,7 @@ class ServerAsyncReaderWriter final
private:
friend class ::grpc::Server;
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
template <class T>
void EnsureInitialMetadataSent(T* ops) {
@@ -994,14 +1049,18 @@ class ServerAsyncReaderWriter final
}
}
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_ops_;
- CallOpSet<CallOpRecvMessage<R>> read_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
write_ops_;
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index e472f04f56..fb573004cb 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -69,11 +69,9 @@ class ClientAsyncResponseReaderInterface {
virtual void Finish(R* msg, Status* status, void* tag) = 0;
};
-/// Async API for client-side unary RPCs, where the message response
-/// received from the server is of type \a R.
+namespace internal {
template <class R>
-class ClientAsyncResponseReader final
- : public ClientAsyncResponseReaderInterface<R> {
+class ClientAsyncResponseReaderFactory {
public:
/// Start a call and write the request out if \a start is set.
/// \a tag will be notified on \a cq when the call has been started (i.e.
@@ -82,22 +80,36 @@ class ClientAsyncResponseReader final
/// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call.
template <class W>
- static ClientAsyncResponseReader* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const RpcMethod& method,
- ClientContext* context,
- const W& request, bool start) {
- Call call = channel->CreateCall(method, context, cq);
+ static ClientAsyncResponseReader<R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ const W& request, bool start) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncResponseReader)))
- ClientAsyncResponseReader(call, context, request, start);
+ call.call(), sizeof(ClientAsyncResponseReader<R>)))
+ ClientAsyncResponseReader<R>(call, context, request, start);
}
+};
+} // namespace internal
+/// Async API for client-side unary RPCs, where the message response
+/// received from the server is of type \a R.
+template <class R>
+class ClientAsyncResponseReader final
+ : public ClientAsyncResponseReaderInterface<R> {
+ public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
assert(size == sizeof(ClientAsyncResponseReader));
}
+ // This operator should never be called as the memory should be freed as part
+ // of the arena destruction. It only exists to provide a matching operator
+ // delete to the operator new so that some compilers will not complain (see
+ // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
+ // there are no tests catching the compiler warning.
+ static void operator delete(void*, void*) { assert(0); }
+
void StartCall() override {
assert(!started_);
started_ = true;
@@ -137,13 +149,14 @@ class ClientAsyncResponseReader final
}
private:
+ friend class internal::ClientAsyncResponseReaderFactory<R>;
ClientContext* const context_;
- Call call_;
+ ::grpc::internal::Call call_;
bool started_;
template <class W>
- ClientAsyncResponseReader(Call call, ClientContext* context, const W& request,
- bool start)
+ ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start)
: context_(context), call_(call), started_(start) {
// Bind the metadata at time of StartCallInternal but set up the rest here
// TODO(ctiller): don't assert
@@ -162,19 +175,23 @@ class ClientAsyncResponseReader final
static void* operator new(std::size_t size);
static void* operator new(std::size_t size, void* p) { return p; }
- SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::SneakyCallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
init_buf;
- CallOpSet<CallOpRecvInitialMetadata> meta_buf;
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_buf;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_buf;
};
/// Async server-side API for handling unary calls, where the single
/// response message sent to the client is of type \a W.
template <class W>
-class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
+class ServerAsyncResponseWriter final
+ : public internal::ServerAsyncStreamingInterface {
public:
explicit ServerAsyncResponseWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -262,13 +279,15 @@ class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
}
private:
- void BindCall(Call* call) override { call_ = *call; }
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
- Call call_;
+ ::grpc::internal::Call call_;
ServerContext* ctx_;
- CallOpSet<CallOpSendInitialMetadata> meta_buf_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_buf_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
finish_buf_;
};
@@ -285,6 +304,6 @@ class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
public:
void operator()(void* p) {}
};
-}
+} // namespace std
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/byte_buffer.h b/include/grpc++/impl/codegen/byte_buffer.h
index 57d731be18..fe73ce7a83 100644
--- a/include/grpc++/impl/codegen/byte_buffer.h
+++ b/include/grpc++/impl/codegen/byte_buffer.h
@@ -31,18 +31,19 @@
namespace grpc {
+namespace internal {
+class CallOpSendMessage;
template <class R>
class CallOpRecvMessage;
+class CallOpGenericRecvMessage;
class MethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
-namespace CallOpGenericRecvMessageHelper {
template <class R>
class DeserializeFuncType;
-} // namespace CallOpGenericRecvMessageHelper
-
+} // namespace internal
/// A sequence of bytes.
class ByteBuffer final {
public:
@@ -97,17 +98,17 @@ class ByteBuffer final {
private:
friend class SerializationTraits<ByteBuffer, void>;
- friend class CallOpSendMessage;
+ friend class internal::CallOpSendMessage;
template <class R>
- friend class CallOpRecvMessage;
- friend class CallOpGenericRecvMessage;
- friend class MethodHandler;
+ friend class internal::CallOpRecvMessage;
+ friend class internal::CallOpGenericRecvMessage;
+ friend class internal::MethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class internal::ServerStreamingHandler;
template <class R>
- friend class CallOpGenericRecvMessageHelper::DeserializeFuncType;
+ friend class internal::DeserializeFuncType;
grpc_byte_buffer* buffer_;
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index d9988e51fc..c04526c59b 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -43,11 +43,13 @@
namespace grpc {
class ByteBuffer;
-class Call;
-class CallHook;
class CompletionQueue;
extern CoreCodegenInterface* g_core_codegen_interface;
+namespace internal {
+class Call;
+class CallHook;
+
const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
// TODO(yangg) if the map is changed before we send, the pointers will be a
@@ -75,6 +77,7 @@ inline grpc_metadata* FillMetadataArray(
}
return metadata_array;
}
+} // namespace internal
/// Per-message write options.
class WriteOptions {
@@ -163,7 +166,7 @@ class WriteOptions {
/// Clears flag indicating that this is the last message in a stream,
/// disabling coalescing.
- inline WriteOptions& clear_last_messsage() {
+ inline WriteOptions& clear_last_message() {
last_message_ = false;
return *this;
}
@@ -199,6 +202,7 @@ class WriteOptions {
bool last_message_;
};
+namespace internal {
/// 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>
@@ -212,14 +216,12 @@ class CallOpSendInitialMetadata {
public:
CallOpSendInitialMetadata() : send_(false) {
maybe_compression_level_.is_set = false;
- maybe_stream_compression_level_.is_set = false;
}
void SendInitialMetadata(
const std::multimap<grpc::string, grpc::string>& metadata,
uint32_t flags) {
maybe_compression_level_.is_set = false;
- maybe_stream_compression_level_.is_set = false;
send_ = true;
flags_ = flags;
initial_metadata_ =
@@ -231,11 +233,6 @@ class CallOpSendInitialMetadata {
maybe_compression_level_.level = level;
}
- void set_stream_compression_level(grpc_stream_compression_level level) {
- maybe_stream_compression_level_.is_set = true;
- maybe_stream_compression_level_.level = level;
- }
-
protected:
void AddOp(grpc_op* ops, size_t* nops) {
if (!send_) return;
@@ -251,12 +248,6 @@ class CallOpSendInitialMetadata {
op->data.send_initial_metadata.maybe_compression_level.level =
maybe_compression_level_.level;
}
- op->data.send_initial_metadata.maybe_stream_compression_level.is_set =
- maybe_stream_compression_level_.is_set;
- if (maybe_stream_compression_level_.is_set) {
- op->data.send_initial_metadata.maybe_stream_compression_level.level =
- maybe_stream_compression_level_.level;
- }
}
void FinishOp(bool* status) {
if (!send_) return;
@@ -272,10 +263,6 @@ class CallOpSendInitialMetadata {
bool is_set;
grpc_compression_level level;
} maybe_compression_level_;
- struct {
- bool is_set;
- grpc_stream_compression_level level;
- } maybe_stream_compression_level_;
};
class CallOpSendMessage {
@@ -309,16 +296,15 @@ class CallOpSendMessage {
WriteOptions write_options_;
};
-namespace internal {
-template <class T>
-T Example();
-} // namespace internal
-
template <class M>
Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) {
write_options_ = options;
bool own_buf;
- Status result = SerializationTraits<M>::Serialize(
+ // TODO(vjpai): Remove the void below when possible
+ // The void in the template parameter below should not be needed
+ // (since it should be implicit) but is needed due to an observed
+ // difference in behavior between clang and gcc for certain internal users
+ Status result = SerializationTraits<M, void>::Serialize(
message, send_buf_.bbuf_ptr(), &own_buf);
if (!own_buf) {
send_buf_.Duplicate();
@@ -383,7 +369,6 @@ class CallOpRecvMessage {
bool allow_not_getting_message_;
};
-namespace CallOpGenericRecvMessageHelper {
class DeserializeFunc {
public:
virtual Status Deserialize(ByteBuffer* buf) = 0;
@@ -403,7 +388,6 @@ class DeserializeFuncType final : public DeserializeFunc {
private:
R* message_; // Not a managed pointer because management is external to this
};
-} // namespace CallOpGenericRecvMessageHelper
class CallOpGenericRecvMessage {
public:
@@ -414,8 +398,7 @@ class CallOpGenericRecvMessage {
void RecvMessage(R* 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);
+ DeserializeFunc* func = new DeserializeFuncType<R>(message);
deserialize_.reset(func);
}
@@ -455,7 +438,7 @@ class CallOpGenericRecvMessage {
}
private:
- std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
+ std::unique_ptr<DeserializeFunc> deserialize_;
ByteBuffer recv_buf_;
bool allow_not_getting_message_;
};
@@ -558,10 +541,12 @@ class CallOpRecvInitialMetadata {
class CallOpClientRecvStatus {
public:
- CallOpClientRecvStatus() : recv_status_(nullptr) {}
+ CallOpClientRecvStatus()
+ : recv_status_(nullptr), debug_error_string_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
- metadata_map_ = &context->trailing_metadata_;
+ client_context_ = context;
+ metadata_map_ = &client_context_->trailing_metadata_;
recv_status_ = status;
error_message_ = g_core_codegen_interface->grpc_empty_slice();
}
@@ -574,6 +559,7 @@ class CallOpClientRecvStatus {
op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &error_message_;
+ op->data.recv_status_on_client.error_string = &debug_error_string_;
op->flags = 0;
op->reserved = NULL;
}
@@ -591,13 +577,20 @@ class CallOpClientRecvStatus {
grpc::string(GRPC_SLICE_START_PTR(error_message_),
GRPC_SLICE_END_PTR(error_message_)),
binary_error_details);
+ client_context_->set_debug_error_string(
+ debug_error_string_ != nullptr ? debug_error_string_ : "");
g_core_codegen_interface->grpc_slice_unref(error_message_);
+ if (debug_error_string_ != nullptr) {
+ g_core_codegen_interface->gpr_free((void*)debug_error_string_);
+ }
recv_status_ = nullptr;
}
private:
+ ClientContext* client_context_;
MetadataMap* metadata_map_;
Status* recv_status_;
+ const char* debug_error_string_;
grpc_status_code status_code_;
grpc_slice error_message_;
};
@@ -614,7 +607,7 @@ class CallOpSetInterface : public CompletionQueueTag {
virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0;
};
-/// Primary implementaiton of CallOpSetInterface.
+/// Primary implementation 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
@@ -631,7 +624,7 @@ class CallOpSet : public CallOpSetInterface,
public Op5,
public Op6 {
public:
- CallOpSet() : return_tag_(this) {}
+ CallOpSet() : return_tag_(this), call_(nullptr) {}
void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override {
this->Op1::AddOp(ops, nops);
this->Op2::AddOp(ops, nops);
@@ -710,7 +703,7 @@ class Call final {
grpc_call* call_;
int max_receive_message_size_;
};
-
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CALL_H
diff --git a/include/grpc++/impl/codegen/call_hook.h b/include/grpc++/impl/codegen/call_hook.h
index d026cc8b58..44e9de220e 100644
--- a/include/grpc++/impl/codegen/call_hook.h
+++ b/include/grpc++/impl/codegen/call_hook.h
@@ -21,6 +21,7 @@
namespace grpc {
+namespace internal {
class CallOpSetInterface;
class Call;
@@ -31,6 +32,7 @@ class CallHook {
virtual ~CallHook() {}
virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/channel_interface.h b/include/grpc++/impl/codegen/channel_interface.h
index 1b7590bf0c..769f853974 100644
--- a/include/grpc++/impl/codegen/channel_interface.h
+++ b/include/grpc++/impl/codegen/channel_interface.h
@@ -24,10 +24,8 @@
#include <grpc/impl/codegen/connectivity_state.h>
namespace grpc {
-class Call;
+class ChannelInterface;
class ClientContext;
-class RpcMethod;
-class CallOpSetInterface;
class CompletionQueue;
template <class R>
@@ -36,14 +34,22 @@ template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
+
+namespace internal {
+class Call;
+class CallOpSetInterface;
+class RpcMethod;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
template <class R>
-class ClientAsyncReader;
+class ClientAsyncReaderFactory;
template <class W>
-class ClientAsyncWriter;
+class ClientAsyncWriterFactory;
template <class W, class R>
-class ClientAsyncReaderWriter;
+class ClientAsyncReaderWriterFactory;
template <class R>
-class ClientAsyncResponseReader;
+class ClientAsyncResponseReaderFactory;
+} // namespace internal
/// Codegen interface for \a grpc::Channel.
class ChannelInterface {
@@ -88,23 +94,21 @@ class ChannelInterface {
template <class W, class R>
friend class ::grpc::ClientReaderWriter;
template <class R>
- friend class ::grpc::ClientAsyncReader;
+ friend class ::grpc::internal::ClientAsyncReaderFactory;
template <class W>
- friend class ::grpc::ClientAsyncWriter;
+ friend class ::grpc::internal::ClientAsyncWriterFactory;
template <class W, class R>
- friend class ::grpc::ClientAsyncReaderWriter;
+ friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
template <class R>
- friend class ::grpc::ClientAsyncResponseReader;
+ friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
- friend class ::grpc::RpcMethod;
- virtual Call CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq) = 0;
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+ friend class ::grpc::internal::RpcMethod;
+ virtual internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) = 0;
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
virtual void* RegisterMethod(const char* method) = 0;
virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
@@ -112,7 +116,6 @@ class ChannelInterface {
virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) = 0;
};
-
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index 6d7e13bbf2..61d97ce818 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -60,7 +60,16 @@ class Channel;
class ChannelInterface;
class CompletionQueue;
class CallCredentials;
+class ClientContext;
+
+namespace internal {
class RpcMethod;
+class CallOpClientRecvStatus;
+class CallOpRecvInitialMetadata;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
+
template <class R>
class ClientReader;
template <class W>
@@ -339,14 +348,21 @@ class ClientContext {
/// Applications never need to call this method.
grpc_call* c_call() { return call_; }
+ /// EXPERIMENTAL debugging API
+ ///
+ /// if status is not ok() for an RPC, this will return a detailed string
+ /// of the gRPC Core error that led to the failure. It should not be relied
+ /// upon for anything other than gaining more debug data in failure cases.
+ grpc::string debug_error_string() const { return debug_error_string_; }
+
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
ClientContext& operator=(const ClientContext&);
friend class ::grpc::testing::InteropClientContextInspector;
- friend class CallOpClientRecvStatus;
- friend class CallOpRecvInitialMetadata;
+ friend class ::grpc::internal::CallOpClientRecvStatus;
+ friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class Channel;
template <class R>
friend class ::grpc::ClientReader;
@@ -363,11 +379,12 @@ class ClientContext {
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+
+ // Used by friend class CallOpClientRecvStatus
+ void set_debug_error_string(const grpc::string& debug_error_string) {
+ debug_error_string_ = debug_error_string;
+ }
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
@@ -399,14 +416,16 @@ class ClientContext {
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;
- MetadataMap recv_initial_metadata_;
- MetadataMap trailing_metadata_;
+ internal::MetadataMap recv_initial_metadata_;
+ internal::MetadataMap trailing_metadata_;
grpc_call* propagate_from_call_;
PropagationOptions propagation_options_;
grpc_compression_algorithm compression_algorithm_;
bool initial_metadata_corked_;
+
+ grpc::string debug_error_string_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 7c540fade9..543e54b972 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -30,43 +30,61 @@ namespace grpc {
class Channel;
class ClientContext;
class CompletionQueue;
-class RpcMethod;
+namespace internal {
+class RpcMethod;
/// Wrapper that performs a blocking unary call
template <class InputMessage, class OutputMessage>
Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const InputMessage& request,
OutputMessage* result) {
- CompletionQueue cq(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
- Call call(channel->CreateCall(method, context, &cq));
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
- CallOpClientSendClose, CallOpClientRecvStatus>
- ops;
- Status status = ops.SendMessage(request);
- if (!status.ok()) {
- return status;
- }
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- ops.RecvInitialMetadata(context);
- ops.RecvMessage(result);
- ops.ClientSendClose();
- ops.ClientRecvStatus(context, &status);
- call.PerformOps(&ops);
- if (cq.Pluck(&ops)) {
- if (!ops.got_message && status.ok()) {
- return Status(StatusCode::UNIMPLEMENTED,
- "No message returned for unary request");
+ return BlockingUnaryCallImpl<InputMessage, OutputMessage>(
+ channel, method, context, request, result)
+ .status();
+}
+
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl {
+ public:
+ BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
+ ClientContext* context, const InputMessage& request,
+ OutputMessage* result) {
+ CompletionQueue cq(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
+ Call call(channel->CreateCall(method, context, &cq));
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
+ CallOpClientSendClose, CallOpClientRecvStatus>
+ ops;
+ status_ = ops.SendMessage(request);
+ if (!status_.ok()) {
+ return;
+ }
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ ops.RecvInitialMetadata(context);
+ ops.RecvMessage(result);
+ ops.AllowNoMessage();
+ ops.ClientSendClose();
+ ops.ClientRecvStatus(context, &status_);
+ call.PerformOps(&ops);
+ if (cq.Pluck(&ops)) {
+ if (!ops.got_message && status_.ok()) {
+ status_ = Status(StatusCode::UNIMPLEMENTED,
+ "No message returned for unary request");
+ }
+ } else {
+ GPR_CODEGEN_ASSERT(!status_.ok());
}
- } else {
- GPR_CODEGEN_ASSERT(!status.ok());
}
- return status;
-}
+ Status status() { return status_; }
+
+ private:
+ Status status_;
+};
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index ca757e2a9c..b8a7862578 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -56,7 +56,20 @@ class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
-}
+} // namespace internal
+
+class Channel;
+class ChannelInterface;
+class ClientContext;
+class CompletionQueue;
+class Server;
+class ServerBuilder;
+class ServerContext;
+class ServerInterface;
+
+namespace internal {
+class CompletionQueueTag;
+class RpcMethod;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -66,16 +79,11 @@ class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
-
-class Channel;
-class ChannelInterface;
-class ClientContext;
-class CompletionQueueTag;
-class CompletionQueue;
-class RpcMethod;
-class Server;
-class ServerBuilder;
-class ServerContext;
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
@@ -109,6 +117,30 @@ class CompletionQueue : private GrpcLibraryCodegen {
TIMEOUT ///< deadline was reached.
};
+ /// EXPERIMENTAL
+ /// First executes \a F, then reads 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 F[in] Function to execute before calling AsyncNext on this queue.
+ /// \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, typename F>
+ NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
+ CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
+ f();
+ if (cache.Flush(tag, ok)) {
+ return GOT_EVENT;
+ } else {
+ return AsyncNext(tag, ok, deadline);
+ }
+ }
+
/// 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
@@ -133,8 +165,9 @@ class CompletionQueue : private GrpcLibraryCodegen {
///
/// \return true if read a regular event, false if the queue is shutting down.
bool Next(void** tag, bool* ok) {
- return (AsyncNextInternal(tag, ok, g_core_codegen_interface->gpr_inf_future(
- GPR_CLOCK_REALTIME)) != SHUTDOWN);
+ return (AsyncNextInternal(tag, ok,
+ g_core_codegen_interface->gpr_inf_future(
+ GPR_CLOCK_REALTIME)) != SHUTDOWN);
}
/// Request the shutdown of the queue.
@@ -155,21 +188,6 @@ class CompletionQueue : private GrpcLibraryCodegen {
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
- /// Manage state of avalanching operations : completion queue tags that
- /// trigger other completion queue operations. The underlying core completion
- /// queue should not really shutdown until all avalanching operations have
- /// been finalized. Note that we maintain the requirement that an avalanche
- /// registration must take place before CQ shutdown (which must be maintained
- /// elsehwere)
- void InitialAvalanching() {
- gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
- }
- void RegisterAvalanching() {
- gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
- static_cast<gpr_atm>(1));
- }
- void CompleteAvalanching();
-
protected:
/// Private constructor of CompletionQueue only visible to friend classes
CompletionQueue(const grpc_completion_queue_attributes& attributes) {
@@ -196,28 +214,40 @@ class CompletionQueue : private GrpcLibraryCodegen {
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ClientStreamingHandler;
+ friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
- friend class TemplatedBidiStreamingHandler;
- friend class UnknownMethodHandler;
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
+ friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(ChannelInterface* channel,
- const RpcMethod& method,
- ClientContext* context,
- const InputMessage& request,
- OutputMessage* result);
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+
+ /// EXPERIMENTAL
+ /// Creates a Thread Local cache to store the first event
+ /// On this completion queue queued from this thread. Once
+ /// initialized, it must be flushed on the same thread.
+ class CompletionQueueTLSCache {
+ public:
+ CompletionQueueTLSCache(CompletionQueue* cq);
+ ~CompletionQueueTLSCache();
+ bool Flush(void** tag, bool* ok);
+
+ private:
+ CompletionQueue* cq_;
+ bool flushed_;
+ };
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
- bool Pluck(CompletionQueueTag* tag) {
+ bool Pluck(internal::CompletionQueueTag* tag) {
auto deadline =
g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
@@ -238,7 +268,7 @@ class CompletionQueue : private GrpcLibraryCodegen {
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
- void TryPluck(CompletionQueueTag* tag) {
+ void TryPluck(internal::CompletionQueueTag* tag) {
auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
@@ -254,7 +284,7 @@ class CompletionQueue : private GrpcLibraryCodegen {
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
- void TryPluck(CompletionQueueTag* tag, gpr_timespec deadline) {
+ void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) {
auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
@@ -266,6 +296,21 @@ class CompletionQueue : private GrpcLibraryCodegen {
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
+ /// Manage state of avalanching operations : completion queue tags that
+ /// trigger other completion queue operations. The underlying core completion
+ /// queue should not really shutdown until all avalanching operations have
+ /// been finalized. Note that we maintain the requirement that an avalanche
+ /// registration must take place before CQ shutdown (which must be maintained
+ /// elsehwere)
+ void InitialAvalanching() {
+ gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
+ }
+ void RegisterAvalanching() {
+ gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
+ static_cast<gpr_atm>(1));
+ }
+ void CompleteAvalanching();
+
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
diff --git a/include/grpc++/impl/codegen/completion_queue_tag.h b/include/grpc++/impl/codegen/completion_queue_tag.h
index 4d7d3a98dd..cb16bcf9ff 100644
--- a/include/grpc++/impl/codegen/completion_queue_tag.h
+++ b/include/grpc++/impl/codegen/completion_queue_tag.h
@@ -21,6 +21,7 @@
namespace grpc {
+namespace internal {
/// An interface allowing implementors to process and filter event tags.
class CompletionQueueTag {
public:
@@ -31,6 +32,7 @@ class CompletionQueueTag {
/// queue
virtual bool FinalizeResult(void** tag, bool* status) = 0;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h
index c5e5bdf0db..7387fa25c6 100644
--- a/include/grpc++/impl/codegen/config_protobuf.h
+++ b/include/grpc++/impl/codegen/config_protobuf.h
@@ -19,6 +19,8 @@
#ifndef GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
#define GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
+#define GRPC_OPEN_SOURCE_PROTO
+
#ifndef GRPC_CUSTOM_PROTOBUF_INT64
#include <google/protobuf/stubs/common.h>
#define GRPC_CUSTOM_PROTOBUF_INT64 ::google::protobuf::int64
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index c751c1e734..d7c57bebb9 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -50,6 +50,9 @@ class CoreCodegen final : public CoreCodegenInterface {
void* gpr_malloc(size_t size) override;
void gpr_free(void* p) override;
+ void grpc_init() override;
+ void grpc_shutdown() override;
+
void gpr_mu_init(gpr_mu* mu) override;
void gpr_mu_destroy(gpr_mu* mu) override;
void gpr_mu_lock(gpr_mu* mu) override;
@@ -89,6 +92,7 @@ class CoreCodegen final : public CoreCodegenInterface {
grpc_slice grpc_slice_ref(grpc_slice slice) override;
grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override;
grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) override;
+ grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) override;
void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) override;
void grpc_slice_buffer_pop(grpc_slice_buffer* sb) override;
grpc_slice grpc_slice_from_static_buffer(const void* buffer,
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index a4c50dab87..d7ad7a4b57 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -25,10 +25,6 @@
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/sync.h>
-extern "C" {
-struct grpc_byte_buffer;
-}
-
namespace grpc {
/// Interface between the codegen library and the minimal subset of core
@@ -63,6 +59,13 @@ class CoreCodegenInterface {
virtual void* gpr_malloc(size_t size) = 0;
virtual void gpr_free(void* p) = 0;
+ // These are only to be used to fix edge cases involving grpc_init and
+ // grpc_shutdown. Calling grpc_init from the codegen interface before
+ // the real grpc_init is called will cause a crash, so if you use this
+ // function, ensure that it is not the first call to grpc_init.
+ virtual void grpc_init() = 0;
+ virtual void grpc_shutdown() = 0;
+
virtual void gpr_mu_init(gpr_mu* mu) = 0;
virtual void gpr_mu_destroy(gpr_mu* mu) = 0;
virtual void gpr_mu_lock(gpr_mu* mu) = 0;
@@ -103,6 +106,7 @@ class CoreCodegenInterface {
virtual grpc_slice grpc_slice_ref(grpc_slice slice) = 0;
virtual grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) = 0;
virtual grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) = 0;
+ virtual grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) = 0;
virtual void grpc_slice_buffer_add(grpc_slice_buffer* sb,
grpc_slice slice) = 0;
virtual void grpc_slice_buffer_pop(grpc_slice_buffer* sb) = 0;
diff --git a/include/grpc++/impl/codegen/metadata_map.h b/include/grpc++/impl/codegen/metadata_map.h
index b73985967d..8dc7211ba8 100644
--- a/include/grpc++/impl/codegen/metadata_map.h
+++ b/include/grpc++/impl/codegen/metadata_map.h
@@ -1,20 +1,20 @@
/*
-*
-* Copyright 2015 gRPC authors.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-*/
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
#ifndef GRPCXX_IMPL_CODEGEN_METADATA_MAP_H
#define GRPCXX_IMPL_CODEGEN_METADATA_MAP_H
@@ -23,6 +23,7 @@
namespace grpc {
+namespace internal {
class MetadataMap {
public:
MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
@@ -40,16 +41,17 @@ class MetadataMap {
}
}
- std::multimap<grpc::string_ref, grpc::string_ref> *map() { return &map_; }
- const std::multimap<grpc::string_ref, grpc::string_ref> *map() const {
+ std::multimap<grpc::string_ref, grpc::string_ref>* map() { return &map_; }
+ const std::multimap<grpc::string_ref, grpc::string_ref>* map() const {
return &map_;
}
- grpc_metadata_array *arr() { return &arr_; }
+ grpc_metadata_array* arr() { return &arr_; }
private:
grpc_metadata_array arr_;
std::multimap<grpc::string_ref, grpc::string_ref> map_;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index e14cb0e926..daf090f86c 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -26,6 +26,28 @@
namespace grpc {
+namespace internal {
+
+// Invoke the method handler, fill in the status, and
+// return whether or not we finished safely (without an exception).
+// Note that exception handling is 0-cost in most compiler/library
+// implementations (except when an exception is actually thrown),
+// so this process doesn't require additional overhead in the common case.
+// Additionally, we don't need to return if we caught an exception or not;
+// the handling is the same in either case.
+template <class Callable>
+Status CatchingFunctionHandler(Callable&& handler) {
+#if GRPC_ALLOW_EXCEPTIONS
+ try {
+ return handler();
+ } catch (...) {
+ return Status(StatusCode::UNKNOWN, "Unexpected error in RPC handling");
+ }
+#else // GRPC_ALLOW_EXCEPTIONS
+ return handler();
+#endif // GRPC_ALLOW_EXCEPTIONS
+}
+
/// A wrapper class of an application provided rpc method handler.
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler : public MethodHandler {
@@ -42,7 +64,9 @@ class RpcMethodHandler : public MethodHandler {
param.request.bbuf_ptr(), &req);
ResponseType rsp;
if (status.ok()) {
- status = func_(service_, param.server_context, &req, &rsp);
+ status = CatchingFunctionHandler([this, &param, &req, &rsp] {
+ return func_(service_, param.server_context, &req, &rsp);
+ });
}
GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
@@ -85,7 +109,9 @@ class ClientStreamingHandler : public MethodHandler {
void RunHandler(const HandlerParameter& param) final {
ServerReader<RequestType> reader(param.call, param.server_context);
ResponseType rsp;
- Status status = func_(service_, param.server_context, &reader, &rsp);
+ Status status = CatchingFunctionHandler([this, &param, &reader, &rsp] {
+ return func_(service_, param.server_context, &reader, &rsp);
+ });
GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
@@ -129,7 +155,9 @@ class ServerStreamingHandler : public MethodHandler {
if (status.ok()) {
ServerWriter<ResponseType> writer(param.call, param.server_context);
- status = func_(service_, param.server_context, &req, &writer);
+ status = CatchingFunctionHandler([this, &param, &req, &writer] {
+ return func_(service_, param.server_context, &req, &writer);
+ });
}
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
@@ -171,7 +199,9 @@ class TemplatedBidiStreamingHandler : public MethodHandler {
void RunHandler(const HandlerParameter& param) final {
Streamer stream(param.call, param.server_context);
- Status status = func_(param.server_context, &stream);
+ Status status = CatchingFunctionHandler([this, &param, &stream] {
+ return func_(param.server_context, &stream);
+ });
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
@@ -266,6 +296,7 @@ class UnknownMethodHandler : public MethodHandler {
}
};
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index 67e8f71a89..b7636034d4 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -39,11 +39,13 @@ class GrpcBufferWriterPeer;
const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024;
-class GrpcBufferWriter final
- : public ::grpc::protobuf::io::ZeroCopyOutputStream {
+class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
public:
- explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size)
- : block_size_(block_size), byte_count_(0), have_backup_(false) {
+ GrpcBufferWriter(grpc_byte_buffer** bp, int block_size, int total_size)
+ : block_size_(block_size),
+ total_size_(total_size),
+ byte_count_(0),
+ have_backup_(false) {
*bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
slice_buffer_ = &(*bp)->data.raw.slice_buffer;
}
@@ -55,11 +57,20 @@ class GrpcBufferWriter final
}
bool Next(void** data, int* size) override {
+ // Protobuf should not ask for more memory than total_size_.
+ GPR_CODEGEN_ASSERT(byte_count_ < total_size_);
if (have_backup_) {
slice_ = backup_slice_;
have_backup_ = false;
} else {
- slice_ = g_core_codegen_interface->grpc_slice_malloc(block_size_);
+ // When less than a whole block is needed, only allocate that much.
+ // But make sure the allocated slice is not inlined.
+ size_t remain = total_size_ - byte_count_ > block_size_
+ ? block_size_
+ : total_size_ - byte_count_;
+ slice_ = g_core_codegen_interface->grpc_slice_malloc(
+ remain > GRPC_SLICE_INLINED_SIZE ? remain
+ : GRPC_SLICE_INLINED_SIZE + 1);
}
*data = GRPC_SLICE_START_PTR(slice_);
// On win x64, int is only 32bit
@@ -71,7 +82,7 @@ class GrpcBufferWriter final
void BackUp(int count) override {
g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
- if (count == block_size_) {
+ if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
backup_slice_ = slice_;
} else {
backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
@@ -88,9 +99,10 @@ class GrpcBufferWriter final
grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
- private:
+ protected:
friend class GrpcBufferWriterPeer;
const int block_size_;
+ const int total_size_;
int64_t byte_count_;
grpc_slice_buffer* slice_buffer_;
bool have_backup_;
@@ -98,8 +110,7 @@ class GrpcBufferWriter final
grpc_slice slice_;
};
-class GrpcBufferReader final
- : public ::grpc::protobuf::io::ZeroCopyInputStream {
+class GrpcBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
public:
explicit GrpcBufferReader(grpc_byte_buffer* buffer)
: byte_count_(0), backup_count_(0), status_() {
@@ -160,7 +171,7 @@ class GrpcBufferReader final
return byte_count_ - backup_count_;
}
- private:
+ protected:
int64_t byte_count_;
int64_t backup_count_;
grpc_byte_buffer_reader reader_;
@@ -168,57 +179,85 @@ class GrpcBufferReader final
Status status_;
};
+// BufferWriter must be a subclass of io::ZeroCopyOutputStream.
+template <class BufferWriter, class T>
+Status GenericSerialize(const grpc::protobuf::Message& msg,
+ grpc_byte_buffer** bp, bool* own_buffer) {
+ static_assert(
+ std::is_base_of<protobuf::io::ZeroCopyOutputStream, BufferWriter>::value,
+ "BufferWriter must be a subclass of io::ZeroCopyOutputStream");
+ *own_buffer = true;
+ int byte_size = msg.ByteSize();
+ if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) {
+ grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size);
+ GPR_CODEGEN_ASSERT(
+ GRPC_SLICE_END_PTR(slice) ==
+ msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice)));
+ *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
+ g_core_codegen_interface->grpc_slice_unref(slice);
+
+ return g_core_codegen_interface->ok();
+ }
+ BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength, byte_size);
+ return msg.SerializeToZeroCopyStream(&writer)
+ ? g_core_codegen_interface->ok()
+ : Status(StatusCode::INTERNAL, "Failed to serialize message");
+}
+
+// BufferReader must be a subclass of io::ZeroCopyInputStream.
+template <class BufferReader, class T>
+Status GenericDeserialize(grpc_byte_buffer* buffer,
+ grpc::protobuf::Message* msg) {
+ static_assert(
+ std::is_base_of<protobuf::io::ZeroCopyInputStream, BufferReader>::value,
+ "BufferReader must be a subclass of io::ZeroCopyInputStream");
+ if (buffer == nullptr) {
+ return Status(StatusCode::INTERNAL, "No payload");
+ }
+ Status result = g_core_codegen_interface->ok();
+ {
+ BufferReader reader(buffer);
+ if (!reader.status().ok()) {
+ return reader.status();
+ }
+ ::grpc::protobuf::io::CodedInputStream decoder(&reader);
+ decoder.SetTotalBytesLimit(INT_MAX, INT_MAX);
+ if (!msg->ParseFromCodedStream(&decoder)) {
+ result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
+ }
+ if (!decoder.ConsumedEntireMessage()) {
+ result = Status(StatusCode::INTERNAL, "Did not read entire message");
+ }
+ }
+ g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
+ return result;
+}
+
} // namespace internal
+// this is needed so the following class does not conflict with protobuf
+// serializers that utilize internal-only tools.
+#ifdef GRPC_OPEN_SOURCE_PROTO
+// This class provides a protobuf serializer. It translates between protobuf
+// objects and grpc_byte_buffers. More information about SerializationTraits can
+// be found in include/grpc++/impl/codegen/serialization_traits.h.
template <class T>
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
public:
static Status Serialize(const grpc::protobuf::Message& msg,
grpc_byte_buffer** bp, bool* own_buffer) {
- *own_buffer = true;
- int byte_size = msg.ByteSize();
- if (byte_size <= internal::kGrpcBufferWriterMaxBufferLength) {
- grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size);
- GPR_CODEGEN_ASSERT(
- GRPC_SLICE_END_PTR(slice) ==
- msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice)));
- *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
- g_core_codegen_interface->grpc_slice_unref(slice);
- return g_core_codegen_interface->ok();
- } else {
- internal::GrpcBufferWriter writer(
- bp, internal::kGrpcBufferWriterMaxBufferLength);
- return msg.SerializeToZeroCopyStream(&writer)
- ? g_core_codegen_interface->ok()
- : Status(StatusCode::INTERNAL, "Failed to serialize message");
- }
+ return internal::GenericSerialize<internal::GrpcBufferWriter, T>(
+ msg, bp, own_buffer);
}
static Status Deserialize(grpc_byte_buffer* buffer,
grpc::protobuf::Message* msg) {
- if (buffer == nullptr) {
- return Status(StatusCode::INTERNAL, "No payload");
- }
- Status result = g_core_codegen_interface->ok();
- {
- internal::GrpcBufferReader reader(buffer);
- if (!reader.status().ok()) {
- return reader.status();
- }
- ::grpc::protobuf::io::CodedInputStream decoder(&reader);
- decoder.SetTotalBytesLimit(INT_MAX, INT_MAX);
- if (!msg->ParseFromCodedStream(&decoder)) {
- result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
- }
- if (!decoder.ConsumedEntireMessage()) {
- result = Status(StatusCode::INTERNAL, "Did not read entire message");
- }
- }
- g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
- return result;
+ return internal::GenericDeserialize<internal::GrpcBufferReader, T>(buffer,
+ msg);
}
};
+#endif
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/rpc_method.h b/include/grpc++/impl/codegen/rpc_method.h
index ac13ac56c7..54e52364ef 100644
--- a/include/grpc++/impl/codegen/rpc_method.h
+++ b/include/grpc++/impl/codegen/rpc_method.h
@@ -24,7 +24,7 @@
#include <grpc++/impl/codegen/channel_interface.h>
namespace grpc {
-
+namespace internal {
/// Descriptor of an RPC method
class RpcMethod {
public:
@@ -55,6 +55,7 @@ class RpcMethod {
void* const channel_tag_;
};
+} // namespace internal
} // namespace grpc
#endif // GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h
index d356012ad6..5ba11e8559 100644
--- a/include/grpc++/impl/codegen/rpc_service_method.h
+++ b/include/grpc++/impl/codegen/rpc_service_method.h
@@ -32,8 +32,8 @@
namespace grpc {
class ServerContext;
-class StreamContextInterface;
+namespace internal {
/// Base class for running an RPC handler.
class MethodHandler {
public:
@@ -71,6 +71,7 @@ class RpcServiceMethod : public RpcMethod {
void* server_tag_;
std::unique_ptr<MethodHandler> handler_;
};
+} // namespace internal
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index b5e37fd12b..a2d6967bf8 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -55,7 +55,6 @@ class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
-}
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@@ -65,9 +64,11 @@ class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
class UnknownMethodHandler;
-
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
class Call;
-class CallOpBuffer;
+} // namespace internal
+
class CompletionQueue;
class Server;
class ServerInterface;
@@ -247,14 +248,14 @@ class ServerContext {
template <class W, class R>
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
- friend class RpcMethodHandler;
+ friend class ::grpc::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ClientStreamingHandler;
+ friend class ::grpc::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
- friend class ServerStreamingHandler;
+ friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
- friend class TemplatedBidiStreamingHandler;
- friend class UnknownMethodHandler;
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
friend class ::grpc::ClientContext;
/// Prevent copying.
@@ -263,9 +264,9 @@ class ServerContext {
class CompletionOp;
- void BeginCompletionOp(Call* call);
+ void BeginCompletionOp(internal::Call* call);
/// Return the tag queued by BeginCompletionOp()
- CompletionQueueTag* GetCompletionOpTag();
+ internal::CompletionQueueTag* GetCompletionOpTag();
ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
@@ -282,7 +283,7 @@ class ServerContext {
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
- MetadataMap client_metadata_;
+ internal::MetadataMap client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;
@@ -290,7 +291,9 @@ class ServerContext {
grpc_compression_level compression_level_;
grpc_compression_algorithm compression_algorithm_;
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> pending_ops_;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata,
+ internal::CallOpSendMessage>
+ pending_ops_;
bool has_pending_ops_;
};
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index 55937f19d7..3bcf4c87e7 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -30,20 +30,21 @@ namespace grpc {
class AsyncGenericService;
class Channel;
class GenericServerContext;
-class RpcService;
-class ServerAsyncStreamingInterface;
class ServerCompletionQueue;
class ServerContext;
class ServerCredentials;
class Service;
-class ThreadPoolInterface;
extern CoreCodegenInterface* g_core_codegen_interface;
/// Models a gRPC server.
///
/// Servers are configured and started via \a grpc::ServerBuilder.
-class ServerInterface : public CallHook {
+namespace internal {
+class ServerAsyncStreamingInterface;
+} // namespace internal
+
+class ServerInterface : public internal::CallHook {
public:
virtual ~ServerInterface() {}
@@ -78,7 +79,7 @@ class ServerInterface : public CallHook {
virtual void Wait() = 0;
protected:
- friend class Service;
+ friend class ::grpc::Service;
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
@@ -116,12 +117,13 @@ class ServerInterface : public CallHook {
virtual grpc_server* server() = 0;
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
- class BaseAsyncRequest : public CompletionQueueTag {
+ class BaseAsyncRequest : public internal::CompletionQueueTag {
public:
BaseAsyncRequest(ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag,
bool delete_on_finalize);
virtual ~BaseAsyncRequest();
@@ -131,7 +133,7 @@ class ServerInterface : public CallHook {
protected:
ServerInterface* const server_;
ServerContext* const context_;
- ServerAsyncStreamingInterface* const stream_;
+ internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
void* const tag_;
const bool delete_on_finalize_;
@@ -141,7 +143,7 @@ class ServerInterface : public CallHook {
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq, void* tag);
// uses BaseAsyncRequest::FinalizeResult
@@ -155,7 +157,7 @@ class ServerInterface : public CallHook {
public:
NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
: RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
@@ -170,7 +172,7 @@ class ServerInterface : public CallHook {
public:
PayloadAsyncRequest(void* registered_method, ServerInterface* server,
ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
@@ -212,7 +214,7 @@ class ServerInterface : public CallHook {
void* const registered_method_;
ServerInterface* const server_;
ServerContext* const context_;
- ServerAsyncStreamingInterface* const stream_;
+ internal::ServerAsyncStreamingInterface* const stream_;
CompletionQueue* const call_cq_;
ServerCompletionQueue* const notification_cq_;
void* const tag_;
@@ -223,7 +225,7 @@ class ServerInterface : public CallHook {
class GenericAsyncRequest : public BaseAsyncRequest {
public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
bool delete_on_finalize);
@@ -235,8 +237,9 @@ class ServerInterface : public CallHook {
};
template <class Message>
- void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* message) {
@@ -246,8 +249,9 @@ class ServerInterface : public CallHook {
message);
}
- void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
GPR_CODEGEN_ASSERT(method);
@@ -256,7 +260,7 @@ class ServerInterface : public CallHook {
}
void RequestAsyncGenericCall(GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq,
void* tag) {
diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h
index 2dc4ea0ea6..71c3d99d5c 100644
--- a/include/grpc++/impl/codegen/service_type.h
+++ b/include/grpc++/impl/codegen/service_type.h
@@ -28,13 +28,14 @@
namespace grpc {
-class Call;
class CompletionQueue;
class Server;
class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
+namespace internal {
+class Call;
class ServerAsyncStreamingInterface {
public:
virtual ~ServerAsyncStreamingInterface() {}
@@ -48,9 +49,10 @@ class ServerAsyncStreamingInterface {
virtual void SendInitialMetadata(void* tag) = 0;
private:
- friend class ServerInterface;
+ friend class ::grpc::ServerInterface;
virtual void BindCall(Call* call) = 0;
};
+} // namespace internal
/// Desriptor of an RPC service and its various RPC methods
class Service {
@@ -88,40 +90,38 @@ class Service {
protected:
template <class Message>
void RequestAsyncUnary(int index, ServerContext* context, Message* request,
- ServerAsyncStreamingInterface* stream,
+ internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestAsyncClientStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncClientStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
- void RequestAsyncServerStreaming(int index, ServerContext* context,
- Message* request,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncServerStreaming(
+ int index, ServerContext* context, Message* request,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestAsyncBidiStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
+ void RequestAsyncBidiStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
- void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
+ void AddMethod(internal::RpcServiceMethod* method) {
+ methods_.emplace_back(method);
+ }
void MarkMethodAsync(int index) {
GPR_CODEGEN_ASSERT(
@@ -139,7 +139,7 @@ class Service {
methods_[index].reset();
}
- void MarkMethodStreamed(int index, MethodHandler* streamed_method) {
+ void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
"Cannot mark an async or generic method Streamed");
methods_[index]->SetHandler(streamed_method);
@@ -148,14 +148,14 @@ class Service {
// case of BIDI_STREAMING that has 1 read and 1 write, in that order,
// and split server-side streaming is BIDI_STREAMING with 1 read and
// any number of writes, in that order.
- methods_[index]->SetMethodType(::grpc::RpcMethod::BIDI_STREAMING);
+ methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
}
private:
friend class Server;
friend class ServerInterface;
ServerInterface* server_;
- std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
+ std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index c1784f1820..a6dd26fb00 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -30,6 +30,7 @@
namespace grpc {
+namespace internal {
/// Common interface for all synchronous client side streaming.
class ClientStreamingInterface {
public:
@@ -141,10 +142,12 @@ class WriterInterface {
}
};
+} // namespace internal
+
/// Client-side interface for streaming reads of message of type \a R.
template <class R>
-class ClientReaderInterface : public ClientStreamingInterface,
- public ReaderInterface<R> {
+class ClientReaderInterface : public internal::ClientStreamingInterface,
+ public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
@@ -153,35 +156,25 @@ class ClientReaderInterface : public ClientStreamingInterface,
virtual void WaitForInitialMetadata() = 0;
};
+namespace internal {
+template <class R>
+class ClientReaderFactory {
+ public:
+ template <class W>
+ static ClientReader<R>* Create(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request) {
+ return new ClientReader<R>(channel, method, context, request);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
/// where the stream of messages coming from the server has messages
/// of type \a R.
template <class R>
class ClientReader final : public ClientReaderInterface<R> {
public:
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial
- /// metadata used to send to the server when starting the call.
- template <class W>
- ClientReader(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, const W& request)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
- ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
- ops.ClientSendClose();
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
-
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
@@ -192,7 +185,8 @@ class ClientReader final : public ClientReaderInterface<R> {
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); /// status ignored
@@ -209,7 +203,9 @@ class ClientReader final : public ClientReaderInterface<R> {
/// already received (if initial metadata is received, it can be then
/// accessed through the \a ClientContext associated with this call).
bool Read(R* msg) override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -224,7 +220,7 @@ class ClientReader final : public ClientReaderInterface<R> {
/// The \a ClientContext associated with this call is updated with
/// possible metadata received from the server.
Status Finish() override {
- CallOpSet<CallOpClientRecvStatus> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
Status status;
ops.ClientRecvStatus(context_, &status);
call_.PerformOps(&ops);
@@ -233,15 +229,41 @@ class ClientReader final : public ClientReaderInterface<R> {
}
private:
+ friend class internal::ClientReaderFactory<R>;
ClientContext* context_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial
+ /// metadata used to send to the server when starting the call.
+ template <class W>
+ ClientReader(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
+ ops.ClientSendClose();
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
};
/// Client-side interface for streaming writes of message type \a W.
template <class W>
-class ClientWriterInterface : public ClientStreamingInterface,
- public WriterInterface<W> {
+class ClientWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W> {
public:
/// Half close writing from the client. (signal that the stream of messages
/// coming from the client is complete).
@@ -252,37 +274,25 @@ class ClientWriterInterface : public ClientStreamingInterface,
virtual bool WritesDone() = 0;
};
+namespace internal {
+template <class W>
+class ClientWriterFactory {
+ public:
+ template <class R>
+ static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response) {
+ return new ClientWriter<W>(channel, method, context, response);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W.
template <class W>
class ClientWriter : public ClientWriterInterface<W> {
public:
- /// Block to create a stream (i.e. send request headers and other initial
- /// metadata to the server). Note that \a context will be used to fill
- /// in custom initial metadata. \a response will be filled in with the
- /// single expected response message from the server upon a successful
- /// call to the \a Finish method of this instance.
- template <class R>
- ClientWriter(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, R* response)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- finish_ops_.RecvMessage(response);
- finish_ops_.AllowNoMessage();
-
- if (!context_->initial_metadata_corked_) {
- CallOpSet<CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-
/// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
/// semantics.
///
@@ -292,7 +302,8 @@ class ClientWriter : public ClientWriterInterface<W> {
void WaitForInitialMetadata() {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
@@ -304,10 +315,11 @@ class ClientWriter : public ClientWriterInterface<W> {
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call).
- using WriterInterface<W>::Write;
+ using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
@@ -328,7 +340,7 @@ class ClientWriter : public ClientWriterInterface<W> {
}
bool WritesDone() override {
- CallOpSet<CallOpClientSendClose> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
@@ -352,21 +364,51 @@ class ClientWriter : public ClientWriterInterface<W> {
}
private:
+ friend class internal::ClientWriterFactory<W>;
+
+ /// Block to create a stream (i.e. send request headers and other initial
+ /// metadata to the server). Note that \a context will be used to fill
+ /// in custom initial metadata. \a response will be filled in with the
+ /// single expected response message from the server upon a successful
+ /// call to the \a Finish method of this instance.
+ template <class R>
+ ClientWriter(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ finish_ops_.RecvMessage(response);
+ finish_ops_.AllowNoMessage();
+
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
+
ClientContext* context_;
- CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
- CallOpClientRecvStatus>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
finish_ops_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
};
/// Client-side interface for bi-directional streaming with
/// client-to-server stream messages of type \a W and
/// server-to-client stream messages of type \a R.
template <class W, class R>
-class ClientReaderWriterInterface : public ClientStreamingInterface,
- public WriterInterface<W>,
- public ReaderInterface<R> {
+class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {
public:
/// Block to wait for initial metadata from server. The received metadata
/// can only be accessed after this call returns. Should only be called before
@@ -375,7 +417,7 @@ class ClientReaderWriterInterface : public ClientStreamingInterface,
virtual void WaitForInitialMetadata() = 0;
/// Half close writing from the client. (signal that the stream of messages
- /// coming from the client is complete).
+ /// coming from the clinet is complete).
/// Blocks until currently-pending writes are completed.
/// Thread-safe with respect to \a ReaderInterface::Read
///
@@ -383,6 +425,18 @@ class ClientReaderWriterInterface : public ClientStreamingInterface,
virtual bool WritesDone() = 0;
};
+namespace internal {
+template <class W, class R>
+class ClientReaderWriterFactory {
+ public:
+ static ClientReaderWriter<W, R>* Create(
+ ::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context) {
+ return new ClientReaderWriter<W, R>(channel, method, context);
+ }
+};
+} // namespace internal
+
/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
/// where the outgoing message stream coming from the client has messages of
/// type \a W, and the incoming messages stream coming from the server has
@@ -390,25 +444,6 @@ class ClientReaderWriterInterface : public ClientStreamingInterface,
template <class W, class R>
class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
public:
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- if (!context_->initial_metadata_corked_) {
- CallOpSet<CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-
/// Block waiting to read initial metadata from the server.
/// This call is optional, but if it is used, it cannot be used concurrently
/// with or after the \a Finish method.
@@ -418,7 +453,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
void WaitForInitialMetadata() override {
GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
- CallOpSet<CallOpRecvInitialMetadata> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
ops.RecvInitialMetadata(context_);
call_.PerformOps(&ops);
cq_.Pluck(&ops); // status ignored
@@ -434,7 +470,9 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
/// Also receives initial metadata if not already received (updates the \a
/// ClientContext associated with this call in that case).
bool Read(R* msg) override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -448,10 +486,11 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
- using WriterInterface<W>::Write;
+ using ::grpc::internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpClientSendClose>
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
ops;
if (options.is_last_message()) {
@@ -472,7 +511,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
}
bool WritesDone() override {
- CallOpSet<CallOpClientSendClose> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
ops.ClientSendClose();
call_.PerformOps(&ops);
return cq_.Pluck(&ops);
@@ -484,7 +523,9 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
/// - the \a ClientContext associated with this call is updated with
/// possible trailing metadata sent from the server.
Status Finish() override {
- CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> ops;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ ops;
if (!context_->initial_metadata_received_) {
ops.RecvInitialMetadata(context_);
}
@@ -496,15 +537,38 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
}
private:
+ friend class internal::ClientReaderWriterFactory<W, R>;
+
ClientContext* context_;
CompletionQueue cq_;
- Call call_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ ClientReaderWriter(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
};
/// Server-side interface for streaming reads of message of type \a R.
template <class R>
-class ServerReaderInterface : public ServerStreamingInterface,
- public ReaderInterface<R> {};
+class ServerReaderInterface : public internal::ServerStreamingInterface,
+ public internal::ReaderInterface<R> {};
/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
/// where the incoming message stream coming from the client has messages of
@@ -512,15 +576,13 @@ class ServerReaderInterface : public ServerStreamingInterface,
template <class R>
class ServerReader final : public ServerReaderInterface<R> {
public:
- ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata> ops;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
@@ -537,21 +599,27 @@ class ServerReader final : public ServerReaderInterface<R> {
}
bool Read(R* msg) override {
- CallOpSet<CallOpRecvMessage<R>> ops;
+ internal::CallOpSet<internal::CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
private:
- Call* const call_;
+ internal::Call* const call_;
ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ClientStreamingHandler;
+
+ ServerReader(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
};
/// Server-side interface for streaming writes of message of type \a W.
template <class W>
-class ServerWriterInterface : public ServerStreamingInterface,
- public WriterInterface<W> {};
+class ServerWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W> {};
/// Synchronous (blocking) server-side API for doing for doing a
/// server-streaming RPCs, where the outgoing message stream coming from the
@@ -559,8 +627,6 @@ class ServerWriterInterface : public ServerStreamingInterface,
template <class W>
class ServerWriter final : public ServerWriterInterface<W> {
public:
- ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics.
/// Note that initial metadata will be affected by the
@@ -568,7 +634,7 @@ class ServerWriter final : public ServerWriterInterface<W> {
void SendInitialMetadata() override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata> ops;
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
ops.SendInitialMetadata(ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
@@ -584,11 +650,12 @@ class ServerWriter final : public ServerWriterInterface<W> {
/// Side effect:
/// Also sends initial metadata if not already sent (using the
/// \a ClientContext associated with this call to fill in values).
- using WriterInterface<W>::Write;
+ using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
if (options.is_last_message()) {
options.set_buffer_hint();
}
+
if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
return false;
}
@@ -613,15 +680,21 @@ class ServerWriter final : public ServerWriterInterface<W> {
}
private:
- Call* const call_;
+ internal::Call* const call_;
ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ServerStreamingHandler;
+
+ ServerWriter(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
};
/// Server-side interface for bi-directional streaming.
template <class W, class R>
-class ServerReaderWriterInterface : public ServerStreamingInterface,
- public WriterInterface<W>,
- public ReaderInterface<R> {};
+class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {};
/// Actual implementation of bi-directional streaming
namespace internal {
@@ -688,6 +761,7 @@ class ServerReaderWriterBody final {
Call* const call_;
ServerContext* const ctx_;
};
+
} // namespace internal
/// Synchronous (blocking) server-side API for a bidirectional
@@ -697,8 +771,6 @@ class ServerReaderWriterBody final {
template <class W, class R>
class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
public:
- ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {}
-
/// See the \a ServerStreamingInterface.SendInitialMetadata method
/// for semantics. Note that initial metadata will be affected by the
/// \a ServerContext associated with this call.
@@ -715,13 +787,18 @@ class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
/// Side effect:
/// Also sends initial metadata if not already sent (using the \a
/// ServerContext associated with this call).
- using WriterInterface<W>::Write;
+ using internal::WriterInterface<W>::Write;
bool Write(const W& msg, WriteOptions options) override {
return body_.Write(msg, options);
}
private:
internal::ServerReaderWriterBody<W, R> body_;
+
+ friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
+ false>;
+ ServerReaderWriter(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx) {}
};
/// A class to represent a flow-controlled unary call. This is something
@@ -736,9 +813,6 @@ template <class RequestType, class ResponseType>
class ServerUnaryStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
- ServerUnaryStreamer(Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false), write_done_(false) {}
-
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
@@ -775,7 +849,7 @@ class ServerUnaryStreamer final
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
- using WriterInterface<ResponseType>::Write;
+ using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
if (write_done_ || !read_done_) {
return false;
@@ -788,6 +862,11 @@ class ServerUnaryStreamer final
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
bool write_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerUnaryStreamer<RequestType, ResponseType>, true>;
+ ServerUnaryStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false), write_done_(false) {}
};
/// A class to represent a flow-controlled server-side streaming call.
@@ -799,9 +878,6 @@ template <class RequestType, class ResponseType>
class ServerSplitStreamer final
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
- ServerSplitStreamer(Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false) {}
-
/// Block to send initial metadata to client.
/// Implicit input parameter:
/// - the \a ServerContext associated with this call will be used for
@@ -838,7 +914,7 @@ class ServerSplitStreamer final
/// \param options The WriteOptions affecting the write operation.
///
/// \return \a true on success, \a false when the stream has been closed.
- using WriterInterface<ResponseType>::Write;
+ using internal::WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response, WriteOptions options) override {
return read_done_ && body_.Write(response, options);
}
@@ -846,6 +922,11 @@ class ServerSplitStreamer final
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerSplitStreamer<RequestType, ResponseType>, false>;
+ ServerSplitStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false) {}
};
} // namespace grpc
diff --git a/include/grpc++/impl/codegen/time.h b/include/grpc++/impl/codegen/time.h
index 589deb4f03..d464d6ea13 100644
--- a/include/grpc++/impl/codegen/time.h
+++ b/include/grpc++/impl/codegen/time.h
@@ -19,6 +19,8 @@
#ifndef GRPCXX_IMPL_CODEGEN_TIME_H
#define GRPCXX_IMPL_CODEGEN_TIME_H
+#include <chrono>
+
#include <grpc++/impl/codegen/config.h>
#include <grpc/impl/codegen/grpc_types.h>
@@ -59,10 +61,6 @@ class TimePoint<gpr_timespec> {
} // namespace grpc
-#include <chrono>
-
-#include <grpc/impl/codegen/grpc_types.h>
-
namespace grpc {
// from and to should be absolute time.
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 0a3aae8241..01c4a60d21 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -175,7 +175,8 @@ class Server final : public ServerInterface, private GrpcLibraryCodegen {
/// \param num_cqs How many completion queues does \a cqs hold.
void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
- void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) override;
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
void ShutdownInternal(gpr_timespec deadline) override;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index bbf45b3e74..e2bae4b41f 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -40,7 +40,6 @@ namespace grpc {
class AsyncGenericService;
class ResourceQuota;
class CompletionQueue;
-class RpcService;
class Server;
class ServerCompletionQueue;
class ServerCredentials;
@@ -56,13 +55,18 @@ class ServerBuilder {
ServerBuilder();
~ServerBuilder();
- /// Options for synchronous servers.
- enum SyncServerOption {
- NUM_CQS, ///< Number of completion queues.
- MIN_POLLERS, ///< Minimum number of polling threads.
- MAX_POLLERS, ///< Maximum number of polling threads.
- CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds.
- };
+ //////////////////////////////////////////////////////////////////////////////
+ // Primary API's
+
+ /// Return a running server which is ready for processing calls.
+ /// Before calling, one typically needs to ensure that:
+ /// 1. a service is registered - so that the server knows what to serve
+ /// (via RegisterService, or RegisterAsyncGenericService)
+ /// 2. a listening port has been added - so the server knows where to receive
+ /// traffic (via AddListeningPort)
+ /// 3. [for async api only] completion queues have been added via
+ /// AddCompletionQueue
+ std::unique_ptr<Server> BuildAndStart();
/// 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
@@ -70,9 +74,60 @@ class ServerBuilder {
/// Matches requests with any :authority
ServerBuilder& RegisterService(Service* service);
- /// Register a generic service.
- /// Matches requests with any :authority
- ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
+ /// Enlists an endpoint \a addr (port with an optional IP address) to
+ /// bind the \a grpc::Server object to be created to.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr_uri The address to try to bind to the server in URI form. If
+ /// the scheme name is omitted, "dns:///" is assumed. To bind to any address,
+ /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4
+ /// connections. Valid values include dns:///localhost:1234, /
+ /// 192.168.1.1:31416, dns:///[::1]:27182, etc.).
+ /// \param creds The credentials associated with the server.
+ /// \param selected_port[out] If not `nullptr`, gets populated with the port
+ /// number bound to the \a grpc::Server for the corresponding endpoint after
+ /// it is successfully bound, 0 otherwise.
+ ///
+ ServerBuilder& AddListeningPort(const grpc::string& addr_uri,
+ std::shared_ptr<ServerCredentials> creds,
+ int* selected_port = nullptr);
+
+ /// Add a completion queue for handling asynchronous services.
+ ///
+ /// Best performance is typically obtained by using one thread per polling
+ /// completion queue.
+ ///
+ /// Caller is required to shutdown the server prior to shutting down the
+ /// returned completion queue. Caller is also required to drain the
+ /// completion queue after shutting it down. A typical usage scenario:
+ ///
+ /// // While building the server:
+ /// ServerBuilder builder;
+ /// ...
+ /// cq_ = builder.AddCompletionQueue();
+ /// server_ = builder.BuildAndStart();
+ ///
+ /// // While shutting down the server;
+ /// server_->Shutdown();
+ /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()!
+ /// // Drain the cq_ that was created
+ /// void* ignored_tag;
+ /// bool ignored_ok;
+ /// while (cq_->Next(&ignored_tag, &ignored_ok)) { }
+ ///
+ /// \param is_frequently_polled This is an optional parameter to inform gRPC
+ /// library about whether this completion queue would be frequently polled
+ /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is
+ /// 'true' and is the recommended setting. Setting this to 'false' (i.e.
+ /// not polling the completion queue frequently) will have a significantly
+ /// negative performance impact and hence should not be used in production
+ /// use cases.
+ std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(
+ bool is_frequently_polled = true);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Less commonly used RegisterService variants
/// 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
@@ -80,6 +135,15 @@ class ServerBuilder {
/// Only matches requests with :authority \a host
ServerBuilder& RegisterService(const grpc::string& host, Service* service);
+ /// Register a generic service.
+ /// Matches requests with any :authority
+ /// This is mostly useful for writing generic gRPC Proxies where the exact
+ /// serialization format is unknown
+ ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Fine control knobs
+
/// Set max receive message size in bytes.
ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) {
max_receive_message_size_ = max_receive_message_size;
@@ -120,6 +184,14 @@ class ServerBuilder {
ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
+ /// Options for synchronous servers.
+ enum SyncServerOption {
+ NUM_CQS, ///< Number of completion queues.
+ MIN_POLLERS, ///< Minimum number of polling threads.
+ MAX_POLLERS, ///< Maximum number of polling threads.
+ CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds.
+ };
+
/// Only useful if this is a Synchronous server.
ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
@@ -130,59 +202,6 @@ class ServerBuilder {
return SetOption(MakeChannelArgumentOption(arg, value));
}
- /// Enlists an endpoint \a addr (port with an optional IP address) to
- /// bind the \a grpc::Server object to be created to.
- ///
- /// It can be invoked multiple times.
- ///
- /// \param addr_uri The address to try to bind to the server in URI form. If
- /// the scheme name is omitted, "dns:///" is assumed. To bind to any address,
- /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4
- /// connections. Valid values include dns:///localhost:1234, /
- /// 192.168.1.1:31416, dns:///[::1]:27182, etc.).
- /// \params creds The credentials associated with the server.
- /// \param selected_port[out] If not `nullptr`, gets populated with the port
- /// number bound to the \a grpc::Server for the corresponding endpoint after
- /// it is successfully bound, 0 otherwise.
- ///
- // TODO(dgq): the "port" part seems to be a misnomer.
- ServerBuilder& AddListeningPort(const grpc::string& addr_uri,
- std::shared_ptr<ServerCredentials> creds,
- int* selected_port = nullptr);
-
- /// Add a completion queue for handling asynchronous services.
- ///
- /// Caller is required to shutdown the server prior to shutting down the
- /// returned completion queue. Caller is also required to drain the
- /// completion queue after shutting it down. A typical usage scenario:
- ///
- /// // While building the server:
- /// ServerBuilder builder;
- /// ...
- /// cq_ = builder.AddCompletionQueue();
- /// server_ = builder.BuildAndStart();
- ///
- /// // While shutting down the server;
- /// server_->Shutdown();
- /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()!
- /// // Drain the cq_ that was created
- /// void* ignored_tag;
- /// bool ignored_ok;
- /// while (cq_->Next(&ignored_tag, &ignored_ok)) { }
- ///
- /// \param is_frequently_polled This is an optional parameter to inform gRPC
- /// library about whether this completion queue would be frequently polled
- /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is
- /// 'true' and is the recommended setting. Setting this to 'false' (i.e.
- /// not polling the completion queue frequently) will have a significantly
- /// negative performance impact and hence should not be used in production
- /// use cases.
- std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(
- bool is_frequently_polled = true);
-
- /// Return a running server which is ready for processing calls.
- std::unique_ptr<Server> BuildAndStart();
-
/// For internal use only: Register a ServerBuilderPlugin factory function.
static void InternalAddPluginFactory(
std::unique_ptr<ServerBuilderPlugin> (*CreatePlugin)());
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index 7b6befeaf1..c9879d8a28 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -64,6 +64,12 @@ class ChannelArguments {
/// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
+ /// Set the grpclb fallback timeout (in ms) for the channel. If this amount
+ /// of time has passed but we have not gotten any non-empty \a serverlist from
+ /// the balancer, we will fall back to use the backend address(es) returned by
+ /// the resolver.
+ void SetGrpclbFallbackTimeout(int fallback_timeout);
+
/// Set the socket mutator for the channel.
void SetSocketMutator(grpc_socket_mutator* mutator);
@@ -116,7 +122,7 @@ class ChannelArguments {
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
- static void Destroy(grpc_exec_ctx* exec_ctx, void* in) {}
+ static void Destroy(void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;
diff --git a/include/grpc/census.h b/include/grpc/census.h
index de8e7a6617..2258af8898 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -16,10 +16,6 @@
*
*/
-/** RPC-internal Census API's. These are designed to be generic enough that
- * they can (ultimately) be used in many different RPC systems (with differing
- * implementations). */
-
#ifndef GRPC_CENSUS_H
#define GRPC_CENSUS_H
@@ -29,439 +25,12 @@
extern "C" {
#endif
-/** Identify census features that can be enabled via census_initialize(). */
-enum census_features {
- CENSUS_FEATURE_NONE = 0, /** Do not enable census. */
- CENSUS_FEATURE_TRACING = 1, /** Enable census tracing. */
- CENSUS_FEATURE_STATS = 2, /** Enable Census stats collection. */
- CENSUS_FEATURE_CPU = 4, /** Enable Census CPU usage collection. */
- CENSUS_FEATURE_ALL =
- CENSUS_FEATURE_TRACING | CENSUS_FEATURE_STATS | CENSUS_FEATURE_CPU
-};
-
-/** Shutdown and startup census subsystem. The 'features' argument should be
- * the OR (|) of census_features values. If census fails to initialize, then
- * census_initialize() will return -1, otherwise the set of enabled features
- * (which may be smaller than that provided in the `features` argument, see
- * census_supported()) is returned. It is an error to call census_initialize()
- * more than once (without an intervening census_shutdown()). These functions
- * are not thread-safe. */
-CENSUSAPI int census_initialize(int features);
-CENSUSAPI void census_shutdown(void);
-
-/** Return the features supported by the current census implementation (not all
- * features will be available on all platforms). */
-CENSUSAPI int census_supported(void);
-
-/** Return the census features currently enabled. */
-CENSUSAPI int census_enabled(void);
-
/**
A Census Context is a handle used by Census to represent the current tracing
and stats collection information. Contexts should be propagated across RPC's
- (this is the responsibility of the local RPC system). A context is typically
- used as the first argument to most census functions. Conceptually, they
- should be thought of as specific to a single RPC/thread. The user visible
- context representation is that of a collection of key:value string pairs,
- each of which is termed a 'tag'; these form the basis against which Census
- metrics will be recorded. Keys are unique within a context. */
+ (this is the responsibility of the local RPC system). */
typedef struct census_context census_context;
-/** A tag is a key:value pair. Both keys and values are nil-terminated strings,
- containing printable ASCII characters (decimal 32-126). Keys must be at
- least one character in length. Both keys and values can have at most
- CENSUS_MAX_TAG_KB_LEN characters (including the terminating nil). The
- maximum number of tags that can be propagated is
- CENSUS_MAX_PROPAGATED_TAGS. Users should also remember that some systems
- may have limits on, e.g., the number of bytes that can be transmitted as
- metadata, and that larger tags means more memory consumed and time in
- processing. */
-typedef struct {
- const char *key;
- const char *value;
- uint8_t flags;
-} census_tag;
-
-/** Maximum length of a tag's key or value. */
-#define CENSUS_MAX_TAG_KV_LEN 255
-/** Maximum number of propagatable tags. */
-#define CENSUS_MAX_PROPAGATED_TAGS 255
-
-/** Tag flags. */
-#define CENSUS_TAG_PROPAGATE 1 /** Tag should be propagated over RPC */
-#define CENSUS_TAG_STATS 2 /** Tag will be used for statistics aggregation */
-#define CENSUS_TAG_RESERVED 4 /** Reserved for internal use. */
-/** Flag values 4,8,16,32,64,128 are reserved for future/internal use. Clients
- should not use or rely on their values. */
-
-#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
-#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
-
-/** An instance of this structure is kept by every context, and records the
- basic information associated with the creation of that context. */
-typedef struct {
- int n_propagated_tags; /** number of propagated tags */
- int n_local_tags; /** number of non-propagated (local) tags */
- int n_deleted_tags; /** number of tags that were deleted */
- int n_added_tags; /** number of tags that were added */
- int n_modified_tags; /** number of tags that were modified */
- int n_invalid_tags; /** number of tags with bad keys or values (e.g.
- longer than CENSUS_MAX_TAG_KV_LEN) */
- int n_ignored_tags; /** number of tags ignored because of
- CENSUS_MAX_PROPAGATED_TAGS limit. */
-} census_context_status;
-
-/** Create a new context, adding and removing tags from an existing context.
- This will copy all tags from the 'tags' input, so it is recommended
- to add as many tags in a single operation as is practical for the client.
- @param base Base context to build upon. Can be NULL.
- @param tags A set of tags to be added/changed/deleted. Tags with keys that
- are in 'tags', but not 'base', are added to the context. Keys that are in
- both 'tags' and 'base' will have their value/flags modified. Tags with keys
- in both, but with NULL values, will be deleted from the context. Tags with
- invalid (too long or short) keys or values will be ignored.
- If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
- binary or non-binary tags, they will be ignored, as will deletions of
- tags that don't exist.
- @param ntags number of tags in 'tags'
- @param status If not NULL, will return a pointer to a census_context_status
- structure containing information about the new context and status of the
- tags used in its creation.
- @return A new, valid census_context.
-*/
-CENSUSAPI census_context *census_context_create(
- const census_context *base, const census_tag *tags, int ntags,
- census_context_status const **status);
-
-/** Destroy a context. Once this function has been called, the context cannot
- be reused. */
-CENSUSAPI void census_context_destroy(census_context *context);
-
-/** Get a pointer to the original status from the context creation. */
-CENSUSAPI const census_context_status *census_context_get_status(
- const census_context *context);
-
-/** Structure used for iterating over the tags in a context. API clients should
- not use or reference internal fields - neither their contents or
- presence/absence are guaranteed. */
-typedef struct {
- const census_context *context;
- int base;
- int index;
- char *kvm;
-} census_context_iterator;
-
-/** Initialize a census_tag_iterator. Must be called before first use. */
-CENSUSAPI void census_context_initialize_iterator(
- const census_context *context, census_context_iterator *iterator);
-
-/** Get the contents of the "next" tag in the context. If there are no more
- tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1.
- */
-CENSUSAPI int census_context_next_tag(census_context_iterator *iterator,
- census_tag *tag);
-
-/** Get a context tag by key. Returns 0 if the key is not present. */
-CENSUSAPI int census_context_get_tag(const census_context *context,
- const char *key, census_tag *tag);
-
-/** Tag set encode/decode functionality. These functions are intended
- for use by RPC systems only, for purposes of transmitting/receiving contexts.
- */
-
-/** Encode a context into a buffer.
- @param context context to be encoded
- @param buffer buffer into which the context will be encoded.
- @param buf_size number of available bytes in buffer.
- @return The number of buffer bytes consumed for the encoded context, or
- zero if the buffer was of insufficient size. */
-CENSUSAPI size_t census_context_encode(const census_context *context,
- char *buffer, size_t buf_size);
-
-/** Decode context buffer encoded with census_context_encode(). Returns NULL
- if there is an error in parsing either buffer. */
-CENSUSAPI census_context *census_context_decode(const char *buffer,
- size_t size);
-
-/** Distributed traces can have a number of options. */
-enum census_trace_mask_values {
- CENSUS_TRACE_MASK_NONE = 0, /** Default, empty flags */
- CENSUS_TRACE_MASK_IS_SAMPLED = 1 /** RPC tracing enabled for this context. */
-};
-
-/** Get the current trace mask associated with this context. The value returned
- will be the logical OR of census_trace_mask_values values. */
-CENSUSAPI int census_trace_mask(const census_context *context);
-
-/** Set the trace mask associated with a context. */
-CENSUSAPI void census_set_trace_mask(int trace_mask);
-
-/** The concept of "operation" is a fundamental concept for Census. In an RPC
- system, an operation typically represents a single RPC, or a significant
- sub-part thereof (e.g. a single logical "read" RPC to a distributed storage
- system might do several other actions in parallel, from looking up metadata
- indices to making requests of other services - each of these could be a
- sub-operation with the larger RPC operation). Census uses operations for the
- following:
-
- CPU accounting: If enabled, census will measure the thread CPU time
- consumed between operation start and end times.
-
- Active operations: Census will maintain information on all currently
- active operations.
-
- Distributed tracing: Each operation serves as a logical trace span.
-
- Stats collection: Stats are broken down by operation (e.g. latency
- breakdown for each unique RPC path).
-
- The following functions serve to delineate the start and stop points for
- each logical operation. */
-
-/**
- This structure represents a timestamp as used by census to record the time
- at which an operation begins.
-*/
-typedef struct {
- /** Use gpr_timespec for default implementation. High performance
- * implementations should use a cycle-counter based timestamp. */
- gpr_timespec ts;
-} census_timestamp;
-
-/**
- Mark the beginning of an RPC operation. The information required to call the
- functions to record the start of RPC operations (both client and server) may
- not be callable at the true start time of the operation, due to information
- not being available (e.g. the census context data will not be available in a
- server RPC until at least initial metadata has been processed). To ensure
- correct CPU accounting and latency recording, RPC systems can call this
- function to get the timestamp of operation beginning. This can later be used
- as an argument to census_start_{client,server}_rpc_op(). NB: for correct
- CPU accounting, the system must guarantee that the same thread is used
- for all request processing after this function is called.
-
- @return A timestamp representing the operation start time.
-*/
-CENSUSAPI census_timestamp census_start_rpc_op_timestamp(void);
-
-/**
- Represent functions to map RPC name ID to service/method names. Census
- breaks down all RPC stats by service and method names. We leave the
- definition and format of these to the RPC system. For efficiency purposes,
- we encode these as a single 64 bit identifier, and allow the RPC system to
- provide a structure for functions that can convert these to service and
- method strings.
-
- TODO(aveitch): Instead of providing this as an argument to the rpc_start_op()
- functions, maybe it should be set once at census initialization.
-*/
-typedef struct {
- const char *(*get_rpc_service_name)(int64_t id);
- const char *(*get_rpc_method_name)(int64_t id);
-} census_rpc_name_info;
-
-/**
- Start a client rpc operation. This function should be called as early in the
- client RPC path as possible. This function will create a new context. If
- the context argument is non-null, then the new context will inherit all
- its properties, with the following changes:
- - create a new operation ID for the new context, marking it as a child of
- the previous operation.
- - use the new RPC path and peer information for tracing and stats
- collection purposes, rather than those from the original context
-
- If the context argument is NULL, then a new root context is created. This
- is particularly important for tracing purposes (the trace spans generated
- will be unassociated with any other trace spans, except those
- downstream). The trace_mask will be used for tracing operations associated
- with the new context.
-
- In some RPC systems (e.g. where load balancing is used), peer information
- may not be available at the time the operation starts. In this case, use a
- NULL value for peer, and set it later using the
- census_set_rpc_client_peer() function.
-
- @param context The parent context. Can be NULL.
- @param rpc_name_id The rpc name identifier to be associated with this RPC.
- @param rpc_name_info Used to decode rpc_name_id.
- @param peer RPC peer. If not available at the time, NULL can be used,
- and a later census_set_rpc_client_peer() call made.
- @param trace_mask An OR of census_trace_mask_values values. Only used in
- the creation of a new root context (context == NULL).
- @param start_time A timestamp returned from census_start_rpc_op_timestamp().
- Can be NULL. Used to set the true time the operation
- begins.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_client_rpc_op(
- const census_context *context, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- const census_timestamp *start_time);
-
-/**
- Add peer information to a context representing a client RPC operation.
-*/
-CENSUSAPI void census_set_rpc_client_peer(census_context *context,
- const char *peer);
-
-/**
- Start a server RPC operation. Returns a new context to be used in future
- census calls. If buffer is non-NULL, then the buffer contents should
- represent the client context, as generated by census_context_serialize().
- If buffer is NULL, a new root context is created.
-
- @param buffer Buffer containing bytes output from census_context_serialize().
- @param rpc_name_id The rpc name identifier to be associated with this RPC.
- @param rpc_name_info Used to decode rpc_name_id.
- @param peer RPC peer.
- @param trace_mask An OR of census_trace_mask_values values. Only used in
- the creation of a new root context (buffer == NULL).
- @param start_time A timestamp returned from census_start_rpc_op_timestamp().
- Can be NULL. Used to set the true time the operation
- begins.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_server_rpc_op(
- const char *buffer, int64_t rpc_name_id,
- const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
- census_timestamp *start_time);
-
-/**
- Start a new, non-RPC operation. In general, this function works very
- similarly to census_start_client_rpc_op, with the primary difference being
- the replacement of host/path information with the more generic family/name
- tags. If the context argument is non-null, then the new context will
- inherit all its properties, with the following changes:
- - create a new operation ID for the new context, marking it as a child of
- the previous operation.
- - use the family and name information for tracing and stats collection
- purposes, rather than those from the original context
-
- If the context argument is NULL, then a new root context is created. This
- is particularly important for tracing purposes (the trace spans generated
- will be unassociated with any other trace spans, except those
- downstream). The trace_mask will be used for tracing
- operations associated with the new context.
-
- @param context The base context. Can be NULL.
- @param family Family name to associate with the trace
- @param name Name within family to associate with traces/stats
- @param trace_mask An OR of census_trace_mask_values values. Only used if
- context is NULL.
-
- @return A new census context.
- */
-CENSUSAPI census_context *census_start_op(census_context *context,
- const char *family, const char *name,
- int trace_mask);
-
-/**
- End an operation started by any of the census_start_*_op*() calls. The
- context used in this call will no longer be valid once this function
- completes.
-
- @param context Context associated with operation which is ending.
- @param status status associated with the operation. Not interpreted by
- census.
-*/
-CENSUSAPI void census_end_op(census_context *context, int status);
-
-#define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0)
-#define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1)
-
-/** Insert a trace record into the trace stream. The record consists of an
- arbitrary size buffer, the size of which is provided in 'n'.
- @param context Trace context
- @param type User-defined type to associate with trace entry.
- @param buffer Pointer to buffer to use
- @param n Number of bytes in buffer
-*/
-CENSUSAPI void census_trace_print(census_context *context, uint32_t type,
- const char *buffer, size_t n);
-
-/** Trace record. */
-typedef struct {
- census_timestamp timestamp; /** Time of record creation */
- uint64_t trace_id; /** Trace ID associated with record */
- uint64_t op_id; /** Operation ID associated with record */
- uint32_t type; /** Type (as used in census_trace_print() */
- const char *buffer; /** Buffer (from census_trace_print() */
- size_t buf_size; /** Number of bytes inside buffer */
-} census_trace_record;
-
-/** Start a scan of existing trace records. While a scan is ongoing, addition
- of new trace records will be blocked if the underlying trace buffers
- fill up, so trace processing systems should endeavor to complete
- reading as soon as possible.
- @param consume if non-zero, indicates that reading records also "consumes"
- the previously read record - i.e. releases space in the trace log
- while scanning is ongoing.
- @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing)
-*/
-CENSUSAPI int census_trace_scan_start(int consume);
-
-/** Get a trace record. The data pointed to by the trace buffer is guaranteed
- stable until the next census_get_trace_record() call (if the consume
- argument to census_trace_scan_start was non-zero) or census_trace_scan_end()
- is called (otherwise).
- @param trace_record structure that will be filled in with oldest trace record.
- @returns -1 if an error occurred (e.g. no previous call to
- census_trace_scan_start()), 0 if there is no more trace data (and
- trace_record will not be modified) or 1 otherwise.
-*/
-CENSUSAPI int census_get_trace_record(census_trace_record *trace_record);
-
-/** End a scan previously started by census_trace_scan_start() */
-CENSUSAPI void census_trace_scan_end();
-
-/** Core stats collection API's. The following concepts are used:
- * Resource: Users record measurements for a single resource. Examples
- include RPC latency, CPU seconds consumed, and bytes transmitted.
- * Aggregation: An aggregation of a set of measurements. Census supports the
- following aggregation types:
- * Distribution - statistical distribution information, used for
- recording average, standard deviation etc. Can include a histogram.
- * Interval - a count of events that happen in a rolling time window.
- * View: A view is a combination of a Resource, a set of tag keys and an
- Aggregation. When a measurement for a Resource matches the View tags, it is
- recorded (for each unique set of tag values) using the Aggregation type.
- Each resource can have an arbitrary number of views by which it will be
- broken down.
-
- Census uses protos to define each of the above, and output results. This
- ensures unification across the different language and runtime
- implementations. The proto definitions can be found in src/proto/census.
-*/
-
-/** Define a new resource. `resource_pb` should contain an encoded Resource
- protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve
- value on error, or a positive (>= 0) resource id (for use in
- census_delete_resource() and census_record_values()). In order to be valid, a
- resource must have a name, and at least one numerator in its unit type. The
- resource name must be unique, and an error will be returned if it is not. */
-CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb,
- size_t resource_pb_size);
-
-/** Delete a resource created by census_define_resource(). */
-CENSUSAPI void census_delete_resource(int32_t resource_id);
-
-/** Determine the id of a resource, given its name. returns -1 if the resource
- does not exist. */
-CENSUSAPI int32_t census_resource_id(const char *name);
-
-/** A single value to be recorded comprises two parts: an ID for the particular
- * resource and the value to be recorded against it. */
-typedef struct {
- int32_t resource_id;
- double value;
-} census_value;
-
-/** Record new usage values against the given context. */
-CENSUSAPI void census_record_values(census_context *context,
- census_value *values, size_t nvalues);
-
#ifdef __cplusplus
}
#endif
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 13a8dd66ad..a4f6a8faf2 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -30,60 +30,43 @@
extern "C" {
#endif
+/** Return if an algorithm is message compression algorithm. */
+GRPCAPI int grpc_compression_algorithm_is_message(
+ grpc_compression_algorithm algorithm);
+
+/** Return if an algorithm is stream compression algorithm. */
+GRPCAPI int grpc_compression_algorithm_is_stream(
+ grpc_compression_algorithm algorithm);
+
/** Parses the \a slice as a grpc_compression_algorithm instance and updating \a
* algorithm. Returns 1 upon success, 0 otherwise. */
GRPCAPI int grpc_compression_algorithm_parse(
- grpc_slice value, grpc_compression_algorithm *algorithm);
-
-/** Parses the \a slice as a grpc_stream_compression_algorithm instance and
- * updating \a algorithm. Returns 1 upon success, 0 otherwise. */
-int grpc_stream_compression_algorithm_parse(
- grpc_slice name, grpc_stream_compression_algorithm *algorithm);
+ grpc_slice value, grpc_compression_algorithm* algorithm);
/** Updates \a name with the encoding name corresponding to a valid \a
* algorithm. Note that \a name is statically allocated and must *not* be freed.
* Returns 1 upon success, 0 otherwise. */
GRPCAPI int grpc_compression_algorithm_name(
- grpc_compression_algorithm algorithm, const char **name);
-
-/** Updates \a name with the encoding name corresponding to a valid \a
- * algorithm. Note that \a name is statically allocated and must *not* be freed.
- * Returns 1 upon success, 0 otherwise. */
-GRPCAPI int grpc_stream_compression_algorithm_name(
- grpc_stream_compression_algorithm algorithm, const char **name);
+ grpc_compression_algorithm algorithm, const char** name);
/** Returns the compression algorithm corresponding to \a level for the
- * compression algorithms encoded in the \a accepted_encodings bitset.
- *
- * It abort()s for unknown levels. */
+ * compression algorithms encoded in the \a accepted_encodings bitset.*/
GRPCAPI grpc_compression_algorithm grpc_compression_algorithm_for_level(
grpc_compression_level level, uint32_t accepted_encodings);
-/** Returns the stream compression algorithm corresponding to \a level for the
- * compression algorithms encoded in the \a accepted_stream_encodings bitset.
- * It abort()s for unknown levels. */
-GRPCAPI grpc_stream_compression_algorithm
-grpc_stream_compression_algorithm_for_level(grpc_stream_compression_level level,
- uint32_t accepted_stream_encodings);
-
-GRPCAPI void grpc_compression_options_init(grpc_compression_options *opts);
+GRPCAPI void grpc_compression_options_init(grpc_compression_options* opts);
/** Mark \a algorithm as enabled in \a opts. */
GRPCAPI void grpc_compression_options_enable_algorithm(
- grpc_compression_options *opts, grpc_compression_algorithm algorithm);
+ grpc_compression_options* opts, grpc_compression_algorithm algorithm);
/** Mark \a algorithm as disabled in \a opts. */
GRPCAPI void grpc_compression_options_disable_algorithm(
- grpc_compression_options *opts, grpc_compression_algorithm algorithm);
+ grpc_compression_options* opts, grpc_compression_algorithm algorithm);
/** Returns true if \a algorithm is marked as enabled in \a opts. */
GRPCAPI int grpc_compression_options_is_algorithm_enabled(
- const grpc_compression_options *opts, grpc_compression_algorithm algorithm);
-
-/** Returns true if \a algorithm is marked as enabled in \a opts. */
-GRPCAPI int grpc_compression_options_is_stream_compression_algorithm_enabled(
- const grpc_compression_options *opts,
- grpc_stream_compression_algorithm algorithm);
+ const grpc_compression_options* opts, grpc_compression_algorithm algorithm);
#ifdef __cplusplus
}
diff --git a/include/grpc/compression_ruby.h b/include/grpc/compression_ruby.h
new file mode 100644
index 0000000000..b063b2b529
--- /dev/null
+++ b/include/grpc/compression_ruby.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_COMPRESSION_RUBY_H
+#define GRPC_COMPRESSION_RUBY_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/slice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Parses the \a slice as a grpc_compression_algorithm instance and updating \a
+ * algorithm following algorithm names compatible with Ruby. Returns 1 upon
+ * success, 0 otherwise. */
+GRPCAPI int grpc_compression_algorithm_parse_ruby(
+ grpc_slice value, grpc_compression_algorithm* algorithm);
+
+/** Updates \a name with the encoding name corresponding to a valid \a
+ * algorithm. The \a name follows names compatible with Ruby. Note that \a name
+ * is statically allocated and must *not* be freed. Returns 1 upon success, 0
+ * otherwise. */
+GRPCAPI int grpc_compression_algorithm_name_ruby(
+ grpc_compression_algorithm algorithm, const char** name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_COMPRESSION_RUBY_H */
diff --git a/include/grpc/impl/codegen/exec_ctx_fwd.h b/include/grpc/fork.h
index 005ff14e7e..ca45e1139c 100644
--- a/include/grpc/impl/codegen/exec_ctx_fwd.h
+++ b/include/grpc/fork.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,9 @@
*
*/
-#ifndef GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
-#define GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
+#ifndef GRPC_FORK_H
+#define GRPC_FORK_H
-/* forward declaration for exec_ctx.h */
-struct grpc_exec_ctx;
-typedef struct grpc_exec_ctx grpc_exec_ctx;
+#include <grpc/impl/codegen/fork.h>
-#endif /* GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H */
+#endif /* GRPC_FORK_H */
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index fab7d438aa..f083bc591e 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -40,11 +40,11 @@ extern "C" {
* functionality lives in grpc_security.h.
*/
-GRPCAPI void grpc_metadata_array_init(grpc_metadata_array *array);
-GRPCAPI void grpc_metadata_array_destroy(grpc_metadata_array *array);
+GRPCAPI void grpc_metadata_array_init(grpc_metadata_array* array);
+GRPCAPI void grpc_metadata_array_destroy(grpc_metadata_array* array);
-GRPCAPI void grpc_call_details_init(grpc_call_details *details);
-GRPCAPI void grpc_call_details_destroy(grpc_call_details *details);
+GRPCAPI void grpc_call_details_init(grpc_call_details* details);
+GRPCAPI void grpc_call_details_destroy(grpc_call_details* details);
/** Registers a plugin to be initialized and destroyed with the library.
@@ -73,31 +73,31 @@ GRPCAPI void grpc_init(void);
GRPCAPI void grpc_shutdown(void);
/** Return a string representing the current version of grpc */
-GRPCAPI const char *grpc_version_string(void);
+GRPCAPI const char* grpc_version_string(void);
/** Return a string specifying what the 'g' in gRPC stands for */
-GRPCAPI const char *grpc_g_stands_for(void);
+GRPCAPI const char* grpc_g_stands_for(void);
/** Returns the completion queue factory based on the attributes. MAY return a
NULL if no factory can be found */
-GRPCAPI const grpc_completion_queue_factory *
+GRPCAPI const grpc_completion_queue_factory*
grpc_completion_queue_factory_lookup(
- const grpc_completion_queue_attributes *attributes);
+ const grpc_completion_queue_attributes* attributes);
/** Helper function to create a completion queue with grpc_cq_completion_type
of GRPC_CQ_NEXT and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING */
-GRPCAPI grpc_completion_queue *grpc_completion_queue_create_for_next(
- void *reserved);
+GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_next(
+ void* reserved);
/** Helper function to create a completion queue with grpc_cq_completion_type
of GRPC_CQ_PLUCK and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING */
-GRPCAPI grpc_completion_queue *grpc_completion_queue_create_for_pluck(
- void *reserved);
+GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_pluck(
+ void* reserved);
/** Create a completion queue */
-GRPCAPI grpc_completion_queue *grpc_completion_queue_create(
- const grpc_completion_queue_factory *factory,
- const grpc_completion_queue_attributes *attributes, void *reserved);
+GRPCAPI grpc_completion_queue* grpc_completion_queue_create(
+ const grpc_completion_queue_factory* factory,
+ const grpc_completion_queue_attributes* attributes, void* reserved);
/** Blocks until an event is available, the completion queue is being shut down,
or deadline is reached.
@@ -107,9 +107,9 @@ GRPCAPI grpc_completion_queue *grpc_completion_queue_create(
Callers must not call grpc_completion_queue_next and
grpc_completion_queue_pluck simultaneously on the same completion queue. */
-GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
+GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue* cq,
gpr_timespec deadline,
- void *reserved);
+ void* reserved);
/** Blocks until an event with tag 'tag' is available, the completion queue is
being shutdown or deadline is reached.
@@ -122,9 +122,9 @@ GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
Completion queues support a maximum of GRPC_MAX_COMPLETION_QUEUE_PLUCKERS
concurrently executing plucks at any time. */
-GRPCAPI grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq,
- void *tag, gpr_timespec deadline,
- void *reserved);
+GRPCAPI grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq,
+ void* tag, gpr_timespec deadline,
+ void* reserved);
/** Maximum number of outstanding grpc_completion_queue_pluck executions per
completion queue */
@@ -137,14 +137,31 @@ GRPCAPI grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq,
After calling this function applications should ensure that no
NEW work is added to be published on this completion queue. */
-GRPCAPI void grpc_completion_queue_shutdown(grpc_completion_queue *cq);
+GRPCAPI void grpc_completion_queue_shutdown(grpc_completion_queue* cq);
/** Destroy a completion queue. The caller must ensure that the queue is
drained and no threads are executing grpc_completion_queue_next */
-GRPCAPI void grpc_completion_queue_destroy(grpc_completion_queue *cq);
+GRPCAPI void grpc_completion_queue_destroy(grpc_completion_queue* cq);
+
+/*********** EXPERIMENTAL API ************/
+/** Initializes a thread local cache for \a cq.
+ * grpc_flush_cq_tls_cache() MUST be called on the same thread,
+ * with the same cq.
+ */
+GRPCAPI void grpc_completion_queue_thread_local_cache_init(
+ grpc_completion_queue* cq);
+
+/*********** EXPERIMENTAL API ************/
+/** Flushes the thread local cache for \a cq.
+ * Returns 1 if there was contents in the cache. If there was an event
+ * in \a cq tls cache, its tag is placed in tag, and ok is set to the
+ * event success.
+ */
+GRPCAPI int grpc_completion_queue_thread_local_cache_flush(
+ grpc_completion_queue* cq, void** tag, int* ok);
/** Create a completion queue alarm instance */
-GRPCAPI grpc_alarm *grpc_alarm_create(void *reserved);
+GRPCAPI grpc_alarm* grpc_alarm_create(void* reserved);
/** Set a completion queue alarm instance associated to \a cq.
*
@@ -152,25 +169,25 @@ GRPCAPI grpc_alarm *grpc_alarm_create(void *reserved);
* grpc_alarm_cancel), an event with tag \a tag will be added to \a cq. If the
* alarm expired, the event's success bit will be true, false otherwise (ie,
* upon cancellation). */
-GRPCAPI void grpc_alarm_set(grpc_alarm *alarm, grpc_completion_queue *cq,
- gpr_timespec deadline, void *tag, void *reserved);
+GRPCAPI void grpc_alarm_set(grpc_alarm* alarm, grpc_completion_queue* cq,
+ gpr_timespec deadline, void* tag, void* reserved);
/** Cancel a completion queue alarm. Calling this function over an alarm that
* has already fired has no effect. */
-GRPCAPI void grpc_alarm_cancel(grpc_alarm *alarm, void *reserved);
+GRPCAPI void grpc_alarm_cancel(grpc_alarm* alarm, void* reserved);
/** Destroy the given completion queue alarm, cancelling it in the process. */
-GRPCAPI void grpc_alarm_destroy(grpc_alarm *alarm, void *reserved);
+GRPCAPI void grpc_alarm_destroy(grpc_alarm* alarm, void* reserved);
/** Check the connectivity state of a channel. */
GRPCAPI grpc_connectivity_state grpc_channel_check_connectivity_state(
- grpc_channel *channel, int try_to_connect);
+ grpc_channel* channel, int try_to_connect);
/** Number of active "external connectivity state watchers" attached to a
* channel.
* Useful for testing. **/
GRPCAPI int grpc_channel_num_external_connectivity_watchers(
- grpc_channel *channel);
+ grpc_channel* channel);
/** Watch for a change in connectivity state.
Once the channel connectivity state is different from last_observed_state,
@@ -178,11 +195,11 @@ GRPCAPI int grpc_channel_num_external_connectivity_watchers(
If deadline expires BEFORE the state is changed, tag will be enqueued on cq
with success=0. */
GRPCAPI void grpc_channel_watch_connectivity_state(
- grpc_channel *channel, grpc_connectivity_state last_observed_state,
- gpr_timespec deadline, grpc_completion_queue *cq, void *tag);
+ grpc_channel* channel, grpc_connectivity_state last_observed_state,
+ gpr_timespec deadline, grpc_completion_queue* cq, void* tag);
/** Check whether a grpc channel supports connectivity watcher */
-GRPCAPI int grpc_channel_support_connectivity_watcher(grpc_channel *channel);
+GRPCAPI int grpc_channel_support_connectivity_watcher(grpc_channel* channel);
/** Create a call given a grpc_channel, in order to call 'method'. All
completions are sent to 'completion_queue'. 'method' and 'host' need only
@@ -191,31 +208,31 @@ GRPCAPI int grpc_channel_support_connectivity_watcher(grpc_channel *channel);
to propagate properties from the server call to this new client call,
depending on the value of \a propagation_mask (see propagation_bits.h for
possible values). */
-GRPCAPI grpc_call *grpc_channel_create_call(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_completion_queue *completion_queue, grpc_slice method,
- const grpc_slice *host, gpr_timespec deadline, void *reserved);
+GRPCAPI grpc_call* grpc_channel_create_call(
+ grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
+ grpc_completion_queue* completion_queue, grpc_slice method,
+ const grpc_slice* host, gpr_timespec deadline, void* reserved);
/** Ping the channels peer (load balanced channels will select one sub-channel
to ping); if the channel is not connected, posts a failed. */
-GRPCAPI void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
- void *tag, void *reserved);
+GRPCAPI void grpc_channel_ping(grpc_channel* channel, grpc_completion_queue* cq,
+ void* tag, void* reserved);
/** Pre-register a method/host pair on a channel. */
-GRPCAPI void *grpc_channel_register_call(grpc_channel *channel,
- const char *method, const char *host,
- void *reserved);
+GRPCAPI void* grpc_channel_register_call(grpc_channel* channel,
+ const char* method, const char* host,
+ void* reserved);
/** Create a call given a handle returned from grpc_channel_register_call.
\sa grpc_channel_create_call. */
-GRPCAPI grpc_call *grpc_channel_create_registered_call(
- grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
- grpc_completion_queue *completion_queue, void *registered_call_handle,
- gpr_timespec deadline, void *reserved);
+GRPCAPI grpc_call* grpc_channel_create_registered_call(
+ grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
+ grpc_completion_queue* completion_queue, void* registered_call_handle,
+ gpr_timespec deadline, void* reserved);
/** Allocate memory in the grpc_call arena: this memory is automatically
discarded at call completion */
-GRPCAPI void *grpc_call_arena_alloc(grpc_call *call, size_t size);
+GRPCAPI void* grpc_call_arena_alloc(grpc_call* call, size_t size);
/** Start a batch of operations defined in the array ops; when complete, post a
completion of type 'tag' to the completion queue bound to the call.
@@ -234,9 +251,9 @@ GRPCAPI void *grpc_call_arena_alloc(grpc_call *call, size_t size);
needs to be synchronized. As an optimization, you may synchronize batches
containing just send operations independently from batches containing just
receive operations. */
-GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call *call,
- const grpc_op *ops, size_t nops,
- void *tag, void *reserved);
+GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call* call,
+ const grpc_op* ops, size_t nops,
+ void* tag, void* reserved);
/** Returns a newly allocated string representing the endpoint to which this
call is communicating with. The string is in the uri format accepted by
@@ -246,43 +263,43 @@ GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call *call,
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 grpc_auth_context. */
-GRPCAPI char *grpc_call_get_peer(grpc_call *call);
+GRPCAPI char* grpc_call_get_peer(grpc_call* call);
struct census_context;
/** Set census context for a call; Must be called before first call to
grpc_call_start_batch(). */
-GRPCAPI void grpc_census_call_set_context(grpc_call *call,
- struct census_context *context);
+GRPCAPI void grpc_census_call_set_context(grpc_call* call,
+ struct census_context* context);
/** Retrieve the calls current census context. */
-GRPCAPI struct census_context *grpc_census_call_get_context(grpc_call *call);
+GRPCAPI struct census_context* grpc_census_call_get_context(grpc_call* call);
/** Return a newly allocated string representing the target a channel was
created for. */
-GRPCAPI char *grpc_channel_get_target(grpc_channel *channel);
+GRPCAPI char* grpc_channel_get_target(grpc_channel* channel);
/** Request info about the channel.
\a channel_info indicates what information is being requested and
how that information will be returned.
\a channel_info is owned by the caller. */
-GRPCAPI void grpc_channel_get_info(grpc_channel *channel,
- const grpc_channel_info *channel_info);
+GRPCAPI void grpc_channel_get_info(grpc_channel* channel,
+ const grpc_channel_info* channel_info);
/** Create a client channel to 'target'. Additional channel level configuration
MAY be provided by grpc_channel_args, though the expectation is that most
clients will want to simply pass NULL. See grpc_channel_args definition for
more on this. The data in 'args' need only live through the invocation of
this function. */
-GRPCAPI grpc_channel *grpc_insecure_channel_create(
- const char *target, const grpc_channel_args *args, void *reserved);
+GRPCAPI grpc_channel* grpc_insecure_channel_create(
+ const char* target, const grpc_channel_args* args, void* reserved);
/** Create a lame client: this client fails every operation attempted on it. */
-GRPCAPI grpc_channel *grpc_lame_client_channel_create(
- const char *target, grpc_status_code error_code, const char *error_message);
+GRPCAPI grpc_channel* grpc_lame_client_channel_create(
+ const char* target, grpc_status_code error_code, const char* error_message);
/** Close and destroy a grpc channel */
-GRPCAPI void grpc_channel_destroy(grpc_channel *channel);
+GRPCAPI void grpc_channel_destroy(grpc_channel* channel);
/** Error handling for grpc_call
Most grpc_call functions return a grpc_error. If the error is not GRPC_OK
@@ -295,7 +312,7 @@ GRPCAPI void grpc_channel_destroy(grpc_channel *channel);
THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status
are thread-safe, and can be called at any point before grpc_call_unref
is called.*/
-GRPCAPI grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
+GRPCAPI grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved);
/** Called by clients to cancel an RPC on the server.
Can be called multiple times, from any thread.
@@ -307,18 +324,18 @@ GRPCAPI grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved);
It doesn't need to be alive after the call to
grpc_call_cancel_with_status completes.
*/
-GRPCAPI grpc_call_error grpc_call_cancel_with_status(grpc_call *call,
+GRPCAPI grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
grpc_status_code status,
- const char *description,
- void *reserved);
+ const char* description,
+ void* reserved);
/** Ref a call.
- THREAD SAFETY: grpc_call_unref is thread-compatible */
-GRPCAPI void grpc_call_ref(grpc_call *call);
+ THREAD SAFETY: grpc_call_ref is thread-compatible */
+GRPCAPI void grpc_call_ref(grpc_call* call);
/** Unref a call.
THREAD SAFETY: grpc_call_unref is thread-compatible */
-GRPCAPI void grpc_call_unref(grpc_call *call);
+GRPCAPI void grpc_call_unref(grpc_call* call);
/** Request notification of a new call.
Once a call is received, a notification tagged with \a tag_new is added to
@@ -329,10 +346,10 @@ GRPCAPI void grpc_call_unref(grpc_call *call);
Note that \a cq_for_notification must have been registered to the server via
\a grpc_server_register_completion_queue. */
GRPCAPI grpc_call_error grpc_server_request_call(
- grpc_server *server, grpc_call **call, grpc_call_details *details,
- grpc_metadata_array *request_metadata,
- grpc_completion_queue *cq_bound_to_call,
- grpc_completion_queue *cq_for_notification, void *tag_new);
+ grpc_server* server, grpc_call** call, grpc_call_details* details,
+ grpc_metadata_array* request_metadata,
+ grpc_completion_queue* cq_bound_to_call,
+ grpc_completion_queue* cq_for_notification, void* tag_new);
/** How to handle payloads for a registered method */
typedef enum {
@@ -349,8 +366,8 @@ typedef enum {
registered_method (as returned by this function).
Must be called before grpc_server_start.
Returns NULL on failure. */
-GRPCAPI void *grpc_server_register_method(
- grpc_server *server, const char *method, const char *host,
+GRPCAPI void* grpc_server_register_method(
+ grpc_server* server, const char* method, const char* host,
grpc_server_register_method_payload_handling payload_handling,
uint32_t flags);
@@ -358,35 +375,35 @@ GRPCAPI void *grpc_server_register_method(
must have been registered to the server via
grpc_server_register_completion_queue. */
GRPCAPI grpc_call_error grpc_server_request_registered_call(
- grpc_server *server, void *registered_method, grpc_call **call,
- gpr_timespec *deadline, grpc_metadata_array *request_metadata,
- grpc_byte_buffer **optional_payload,
- grpc_completion_queue *cq_bound_to_call,
- grpc_completion_queue *cq_for_notification, void *tag_new);
+ grpc_server* server, void* registered_method, grpc_call** call,
+ gpr_timespec* deadline, grpc_metadata_array* request_metadata,
+ grpc_byte_buffer** optional_payload,
+ grpc_completion_queue* cq_bound_to_call,
+ grpc_completion_queue* cq_for_notification, void* tag_new);
/** Create a server. Additional configuration for each incoming channel can
be specified with args. If no additional configuration is needed, args can
be NULL. See grpc_channel_args for more. The data in 'args' need only live
through the invocation of this function. */
-GRPCAPI grpc_server *grpc_server_create(const grpc_channel_args *args,
- void *reserved);
+GRPCAPI grpc_server* grpc_server_create(const grpc_channel_args* args,
+ void* reserved);
/** Register a completion queue with the server. Must be done for any
notification completion queue that is passed to grpc_server_request_*_call
and to grpc_server_shutdown_and_notify. Must be performed prior to
grpc_server_start. */
-GRPCAPI void grpc_server_register_completion_queue(grpc_server *server,
- grpc_completion_queue *cq,
- void *reserved);
+GRPCAPI void grpc_server_register_completion_queue(grpc_server* server,
+ grpc_completion_queue* cq,
+ void* reserved);
/** Add a HTTP2 over plaintext over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
-GRPCAPI int grpc_server_add_insecure_http2_port(grpc_server *server,
- const char *addr);
+GRPCAPI int grpc_server_add_insecure_http2_port(grpc_server* server,
+ const char* addr);
/** Start a server - tells all listeners to start listening */
-GRPCAPI void grpc_server_start(grpc_server *server);
+GRPCAPI void grpc_server_start(grpc_server* server);
/** Begin shutting down a server.
After completion, no new calls or connections will be admitted.
@@ -395,19 +412,19 @@ GRPCAPI void grpc_server_start(grpc_server *server);
Shutdown is idempotent, and all tags will be notified at once if multiple
grpc_server_shutdown_and_notify calls are made. 'cq' must have been
registered to this server via grpc_server_register_completion_queue. */
-GRPCAPI void grpc_server_shutdown_and_notify(grpc_server *server,
- grpc_completion_queue *cq,
- void *tag);
+GRPCAPI void grpc_server_shutdown_and_notify(grpc_server* server,
+ grpc_completion_queue* cq,
+ void* tag);
/** Cancel all in-progress calls.
Only usable after shutdown. */
-GRPCAPI void grpc_server_cancel_all_calls(grpc_server *server);
+GRPCAPI void grpc_server_cancel_all_calls(grpc_server* server);
/** Destroy a server.
Shutdown must have completed beforehand (i.e. all tags generated by
grpc_server_shutdown_and_notify must have been received, and at least
one call to grpc_server_shutdown_and_notify must have been made). */
-GRPCAPI void grpc_server_destroy(grpc_server *server);
+GRPCAPI void grpc_server_destroy(grpc_server* server);
/** Enable or disable a tracer.
@@ -417,7 +434,7 @@ GRPCAPI void grpc_server_destroy(grpc_server *server);
Use of this function is not strictly thread-safe, but the
thread-safety issues raised by it should not be of concern. */
-GRPCAPI int grpc_tracer_set_enabled(const char *name, int enabled);
+GRPCAPI int grpc_tracer_set_enabled(const char* name, int enabled);
/** Check whether a metadata key is legal (will be accepted by core) */
GRPCAPI int grpc_header_key_is_legal(grpc_slice slice);
@@ -430,24 +447,24 @@ GRPCAPI int grpc_header_nonbin_value_is_legal(grpc_slice slice);
GRPCAPI int grpc_is_binary_header(grpc_slice slice);
/** Convert grpc_call_error values to a string */
-GRPCAPI const char *grpc_call_error_to_string(grpc_call_error error);
+GRPCAPI const char* grpc_call_error_to_string(grpc_call_error error);
/** Create a buffer pool */
-GRPCAPI grpc_resource_quota *grpc_resource_quota_create(const char *trace_name);
+GRPCAPI grpc_resource_quota* grpc_resource_quota_create(const char* trace_name);
/** Add a reference to a buffer pool */
-GRPCAPI void grpc_resource_quota_ref(grpc_resource_quota *resource_quota);
+GRPCAPI void grpc_resource_quota_ref(grpc_resource_quota* resource_quota);
/** Drop a reference to a buffer pool */
-GRPCAPI void grpc_resource_quota_unref(grpc_resource_quota *resource_quota);
+GRPCAPI void grpc_resource_quota_unref(grpc_resource_quota* resource_quota);
/** Update the size of a buffer pool */
-GRPCAPI void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
+GRPCAPI void grpc_resource_quota_resize(grpc_resource_quota* resource_quota,
size_t new_size);
/** Fetch a vtable for a grpc_channel_arg that points to a grpc_resource_quota
*/
-GRPCAPI const grpc_arg_pointer_vtable *grpc_resource_quota_arg_vtable(void);
+GRPCAPI const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void);
#ifdef __cplusplus
}
diff --git a/include/grpc/grpc_cronet.h b/include/grpc/grpc_cronet.h
index 44330c6e11..127d5d038d 100644
--- a/include/grpc/grpc_cronet.h
+++ b/include/grpc/grpc_cronet.h
@@ -25,9 +25,9 @@
extern "C" {
#endif
-GRPCAPI grpc_channel *grpc_cronet_secure_channel_create(
- void *engine, const char *target, const grpc_channel_args *args,
- void *reserved);
+GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
+ void* engine, const char* target, const grpc_channel_args* args,
+ void* reserved);
#ifdef __cplusplus
}
diff --git a/include/grpc/grpc_posix.h b/include/grpc/grpc_posix.h
index c7429eaea0..fa7ebced3f 100644
--- a/include/grpc/grpc_posix.h
+++ b/include/grpc/grpc_posix.h
@@ -37,8 +37,8 @@ extern "C" {
/** Create a client channel to 'target' using file descriptor 'fd'. The 'target'
argument will be used to indicate the name for this channel. See the comment
for grpc_insecure_channel_create for description of 'args' argument. */
-GRPCAPI grpc_channel *grpc_insecure_channel_create_from_fd(
- const char *target, int fd, const grpc_channel_args *args);
+GRPCAPI grpc_channel* grpc_insecure_channel_create_from_fd(
+ const char* target, int fd, const grpc_channel_args* args);
/** Add the connected communication channel based on file descriptor 'fd' to the
'server'. The 'fd' must be an open file descriptor corresponding to a
@@ -48,8 +48,8 @@ GRPCAPI grpc_channel *grpc_insecure_channel_create_from_fd(
The 'reserved' pointer MUST be NULL.
*/
-GRPCAPI void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
- void *reserved, int fd);
+GRPCAPI void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
+ void* reserved, int fd);
/** GRPC Core POSIX library may internally use signals to optimize some work.
The library uses (SIGRTMIN + 6) signal by default. Use this API to instruct
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 2005e25df2..bae07ac309 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -32,51 +32,51 @@ extern "C" {
typedef struct grpc_auth_context grpc_auth_context;
typedef struct grpc_auth_property_iterator {
- const grpc_auth_context *ctx;
+ const grpc_auth_context* ctx;
size_t index;
- const char *name;
+ const char* name;
} grpc_auth_property_iterator;
/** value, if not NULL, is guaranteed to be NULL terminated. */
typedef struct grpc_auth_property {
- char *name;
- char *value;
+ char* name;
+ char* value;
size_t value_length;
} grpc_auth_property;
/** Returns NULL when the iterator is at the end. */
-GRPCAPI const grpc_auth_property *grpc_auth_property_iterator_next(
- grpc_auth_property_iterator *it);
+GRPCAPI const grpc_auth_property* grpc_auth_property_iterator_next(
+ grpc_auth_property_iterator* it);
/** Iterates over the auth context. */
GRPCAPI grpc_auth_property_iterator
-grpc_auth_context_property_iterator(const grpc_auth_context *ctx);
+grpc_auth_context_property_iterator(const grpc_auth_context* ctx);
/** Gets the peer identity. Returns an empty iterator (first _next will return
NULL) if the peer is not authenticated. */
GRPCAPI grpc_auth_property_iterator
-grpc_auth_context_peer_identity(const grpc_auth_context *ctx);
+grpc_auth_context_peer_identity(const grpc_auth_context* ctx);
/** Finds a property in the context. May return an empty iterator (first _next
will return NULL) if no property with this name was found in the context. */
GRPCAPI grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
- const grpc_auth_context *ctx, const char *name);
+ const grpc_auth_context* ctx, const char* name);
/** Gets the name of the property that indicates the peer identity. Will return
NULL if the peer is not authenticated. */
-GRPCAPI const char *grpc_auth_context_peer_identity_property_name(
- const grpc_auth_context *ctx);
+GRPCAPI const char* grpc_auth_context_peer_identity_property_name(
+ const grpc_auth_context* ctx);
/** Returns 1 if the peer is authenticated, 0 otherwise. */
GRPCAPI int grpc_auth_context_peer_is_authenticated(
- const grpc_auth_context *ctx);
+ const grpc_auth_context* ctx);
/** Gets the auth context from the call. Caller needs to call
grpc_auth_context_release on the returned context. */
-GRPCAPI grpc_auth_context *grpc_call_auth_context(grpc_call *call);
+GRPCAPI grpc_auth_context* grpc_call_auth_context(grpc_call* call);
/** Releases the auth context returned from grpc_call_auth_context. */
-GRPCAPI void grpc_auth_context_release(grpc_auth_context *context);
+GRPCAPI void grpc_auth_context_release(grpc_auth_context* context);
/** --
The following auth context methods should only be called by a server metadata
@@ -84,19 +84,19 @@ GRPCAPI void grpc_auth_context_release(grpc_auth_context *context);
-- */
/** Add a property. */
-GRPCAPI void grpc_auth_context_add_property(grpc_auth_context *ctx,
- const char *name, const char *value,
+GRPCAPI void grpc_auth_context_add_property(grpc_auth_context* ctx,
+ const char* name, const char* value,
size_t value_length);
/** Add a C string property. */
-GRPCAPI void grpc_auth_context_add_cstring_property(grpc_auth_context *ctx,
- const char *name,
- const char *value);
+GRPCAPI void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx,
+ const char* name,
+ const char* value);
/** Sets the property name. Returns 1 if successful or 0 in case of failure
(which means that no property with this name exists). */
GRPCAPI int grpc_auth_context_set_peer_identity_property_name(
- grpc_auth_context *ctx, const char *name);
+ grpc_auth_context* ctx, const char* name);
/** --- grpc_channel_credentials object. ---
@@ -107,12 +107,12 @@ typedef struct grpc_channel_credentials grpc_channel_credentials;
/** Releases a channel credentials object.
The creator of the credentials object is responsible for its release. */
-GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds);
+GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials* creds);
/** Creates default credentials to connect to a google gRPC service.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
-GRPCAPI grpc_channel_credentials *grpc_google_default_credentials_create(void);
+GRPCAPI grpc_channel_credentials* grpc_google_default_credentials_create(void);
/** Callback for getting the SSL roots override from the application.
In case of success, *pem_roots_certs must be set to a NULL terminated string
@@ -121,7 +121,7 @@ GRPCAPI grpc_channel_credentials *grpc_google_default_credentials_create(void);
If this function fails and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is
set to a valid path, it will override the roots specified this func */
typedef grpc_ssl_roots_override_result (*grpc_ssl_roots_override_callback)(
- char **pem_root_certs);
+ char** pem_root_certs);
/** Setup a callback to override the default TLS/SSL roots.
This function is not thread-safe and must be called at initialization time
@@ -135,11 +135,11 @@ GRPCAPI void grpc_set_ssl_roots_override_callback(
typedef struct {
/** private_key is the NULL-terminated string containing the PEM encoding of
the client's private key. */
- const char *private_key;
+ const char* private_key;
/** cert_chain is the NULL-terminated string containing the PEM encoding of
the client's certificate chain. */
- const char *cert_chain;
+ const char* cert_chain;
} grpc_ssl_pem_key_cert_pair;
/** Creates an SSL credentials object.
@@ -153,9 +153,9 @@ typedef struct {
- pem_key_cert_pair is a pointer on the object containing client's private
key and certificate chain. This parameter can be NULL if the client does
not have such a key/cert pair. */
-GRPCAPI grpc_channel_credentials *grpc_ssl_credentials_create(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
- void *reserved);
+GRPCAPI grpc_channel_credentials* grpc_ssl_credentials_create(
+ const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ void* reserved);
/** --- grpc_call_credentials object.
@@ -167,35 +167,35 @@ typedef struct grpc_call_credentials grpc_call_credentials;
/** Releases a call credentials object.
The creator of the credentials object is responsible for its release. */
-GRPCAPI void grpc_call_credentials_release(grpc_call_credentials *creds);
+GRPCAPI void grpc_call_credentials_release(grpc_call_credentials* creds);
/** Creates a composite channel credentials object. */
-GRPCAPI grpc_channel_credentials *grpc_composite_channel_credentials_create(
- grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
- void *reserved);
+GRPCAPI grpc_channel_credentials* grpc_composite_channel_credentials_create(
+ grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds,
+ void* reserved);
/** Creates a composite call credentials object. */
-GRPCAPI grpc_call_credentials *grpc_composite_call_credentials_create(
- grpc_call_credentials *creds1, grpc_call_credentials *creds2,
- void *reserved);
+GRPCAPI grpc_call_credentials* grpc_composite_call_credentials_create(
+ grpc_call_credentials* creds1, grpc_call_credentials* creds2,
+ void* reserved);
/** Creates a compute engine credentials object for connecting to Google.
WARNING: Do NOT use this credentials to connect to a non-google service as
this could result in an oauth2 token leak. */
-GRPCAPI grpc_call_credentials *grpc_google_compute_engine_credentials_create(
- void *reserved);
+GRPCAPI grpc_call_credentials* grpc_google_compute_engine_credentials_create(
+ void* reserved);
-GRPCAPI gpr_timespec grpc_max_auth_token_lifetime();
+GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(void);
/** Creates a JWT credentials object. May return NULL if the input is invalid.
- json_key is the JSON key string containing the client's private key.
- token_lifetime is the lifetime 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. */
-GRPCAPI grpc_call_credentials *
-grpc_service_account_jwt_access_credentials_create(const char *json_key,
+GRPCAPI grpc_call_credentials*
+grpc_service_account_jwt_access_credentials_create(const char* json_key,
gpr_timespec token_lifetime,
- void *reserved);
+ void* reserved);
/** Creates an Oauth2 Refresh Token credentials object for connecting to Google.
May return NULL if the input is invalid.
@@ -203,18 +203,18 @@ grpc_service_account_jwt_access_credentials_create(const char *json_key,
this could result in an oauth2 token leak.
- json_refresh_token is the JSON string containing the refresh token itself
along with a client_id and client_secret. */
-GRPCAPI grpc_call_credentials *grpc_google_refresh_token_credentials_create(
- const char *json_refresh_token, void *reserved);
+GRPCAPI grpc_call_credentials* grpc_google_refresh_token_credentials_create(
+ const char* json_refresh_token, void* reserved);
/** Creates an Oauth2 Access Token credentials with an access token that was
aquired by an out of band mechanism. */
-GRPCAPI grpc_call_credentials *grpc_access_token_credentials_create(
- const char *access_token, void *reserved);
+GRPCAPI grpc_call_credentials* grpc_access_token_credentials_create(
+ const char* access_token, void* reserved);
/** Creates an IAM credentials object for connecting to Google. */
-GRPCAPI grpc_call_credentials *grpc_google_iam_credentials_create(
- const char *authorization_token, const char *authority_selector,
- void *reserved);
+GRPCAPI grpc_call_credentials* grpc_google_iam_credentials_create(
+ const char* authorization_token, const char* authority_selector,
+ void* reserved);
/** Callback function to be called by the metadata credentials plugin
implementation when the metadata is ready.
@@ -228,61 +228,82 @@ GRPCAPI grpc_call_credentials *grpc_google_iam_credentials_create(
- error_details contains details about the error if any. In case of success
it should be NULL and will be otherwise ignored. */
typedef void (*grpc_credentials_plugin_metadata_cb)(
- void *user_data, const grpc_metadata *creds_md, size_t num_creds_md,
- grpc_status_code status, const char *error_details);
+ void* user_data, const grpc_metadata* creds_md, size_t num_creds_md,
+ grpc_status_code status, const char* error_details);
/** Context that can be used by metadata credentials plugin in order to create
auth related metadata. */
typedef struct {
/** The fully qualifed service url. */
- const char *service_url;
+ const char* service_url;
/** The method name of the RPC being called (not fully qualified).
The fully qualified method name can be built from the service_url:
full_qualified_method_name = ctx->service_url + '/' + ctx->method_name. */
- const char *method_name;
+ const char* method_name;
/** The auth_context of the channel which gives the server's identity. */
- const grpc_auth_context *channel_auth_context;
+ const grpc_auth_context* channel_auth_context;
/** Reserved for future use. */
- void *reserved;
+ void* reserved;
} grpc_auth_metadata_context;
+/** Maximum number of metadata entries returnable by a credentials plugin via
+ a synchronous return. */
+#define GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX 4
+
/** grpc_metadata_credentials plugin is an API user provided structure used to
create grpc_credentials objects that can be set on a channel (composed) or
a call. See grpc_credentials_metadata_create_from_plugin below.
The grpc client stack will call the get_metadata method of the plugin for
every call in scope for the credentials created from it. */
typedef struct {
- /** The implementation of this method has to be non-blocking.
- - context is the information that can be used by the plugin to create auth
- metadata.
- - cb is the callback that needs to be called when the metadata is ready.
- - user_data needs to be passed as the first parameter of the callback. */
- void (*get_metadata)(void *state, grpc_auth_metadata_context context,
- grpc_credentials_plugin_metadata_cb cb, void *user_data);
+ /** The implementation of this method has to be non-blocking, but can
+ be performed synchronously or asynchronously.
+
+ If processing occurs synchronously, returns non-zero and populates
+ creds_md, num_creds_md, status, and error_details. In this case,
+ the caller takes ownership of the entries in creds_md and of
+ error_details. Note that if the plugin needs to return more than
+ GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX entries in creds_md, it must
+ return asynchronously.
+
+ If processing occurs asynchronously, returns zero and invokes \a cb
+ when processing is completed. \a user_data will be passed as the
+ first parameter of the callback. NOTE: \a cb MUST be invoked in a
+ different thread, not from the thread in which \a get_metadata() is
+ invoked.
+
+ \a context is the information that can be used by the plugin to create
+ auth metadata. */
+ int (*get_metadata)(
+ void* state, grpc_auth_metadata_context context,
+ grpc_credentials_plugin_metadata_cb cb, void* user_data,
+ grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
+ size_t* num_creds_md, grpc_status_code* status,
+ const char** error_details);
/** Destroys the plugin state. */
- void (*destroy)(void *state);
+ void (*destroy)(void* state);
/** State that will be set as the first parameter of the methods above. */
- void *state;
+ void* state;
/** Type of credentials that this plugin is implementing. */
- const char *type;
+ const char* type;
} grpc_metadata_credentials_plugin;
/** Creates a credentials object from a plugin. */
-GRPCAPI grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
- grpc_metadata_credentials_plugin plugin, void *reserved);
+GRPCAPI grpc_call_credentials* grpc_metadata_credentials_create_from_plugin(
+ grpc_metadata_credentials_plugin plugin, void* reserved);
/** --- Secure channel creation. --- */
/** Creates a secure channel using the passed-in credentials. */
-GRPCAPI grpc_channel *grpc_secure_channel_create(
- grpc_channel_credentials *creds, const char *target,
- const grpc_channel_args *args, void *reserved);
+GRPCAPI grpc_channel* grpc_secure_channel_create(
+ grpc_channel_credentials* creds, const char* target,
+ const grpc_channel_args* args, void* reserved);
/** --- grpc_server_credentials object. ---
@@ -293,7 +314,44 @@ typedef struct grpc_server_credentials grpc_server_credentials;
/** Releases a server_credentials object.
The creator of the server_credentials object is responsible for its release.
*/
-GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds);
+GRPCAPI void grpc_server_credentials_release(grpc_server_credentials* creds);
+
+/** Server certificate config object holds the server's public certificates and
+ associated private keys, as well as any CA certificates needed for client
+ certificate validation (if applicable). Create using
+ grpc_ssl_server_certificate_config_create(). */
+typedef struct grpc_ssl_server_certificate_config
+ grpc_ssl_server_certificate_config;
+
+/** Creates a grpc_ssl_server_certificate_config object.
+ - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
+ the client root certificates. This parameter may be NULL if the server does
+ not want the client to be authenticated with SSL.
+ - pem_key_cert_pairs is an array private key / certificate chains of the
+ server. This parameter cannot be NULL.
+ - num_key_cert_pairs indicates the number of items in the private_key_files
+ and cert_chain_files parameters. It must be at least 1.
+ - It is the caller's responsibility to free this object via
+ grpc_ssl_server_certificate_config_destroy(). */
+GRPCAPI grpc_ssl_server_certificate_config*
+grpc_ssl_server_certificate_config_create(
+ const char* pem_root_certs,
+ const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
+ size_t num_key_cert_pairs);
+
+/** Destroys a grpc_ssl_server_certificate_config object. */
+GRPCAPI void grpc_ssl_server_certificate_config_destroy(
+ grpc_ssl_server_certificate_config* config);
+
+/** Callback to retrieve updated SSL server certificates, private keys, and
+ trusted CAs (for client authentication).
+ - user_data parameter, if not NULL, contains opaque data to be used by the
+ callback.
+ - Use grpc_ssl_server_certificate_config_create to create the config.
+ - The caller assumes ownership of the config. */
+typedef grpc_ssl_certificate_config_reload_status (
+ *grpc_ssl_server_certificate_config_callback)(
+ void* user_data, grpc_ssl_server_certificate_config** config);
/** Deprecated in favor of grpc_ssl_server_credentials_create_ex.
Creates an SSL server_credentials object.
@@ -307,34 +365,69 @@ GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds);
- force_client_auth, if set to non-zero will force the client to authenticate
with an SSL cert. Note that this option is ignored if pem_root_certs is
NULL. */
-GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs, int force_client_auth, void *reserved);
+GRPCAPI grpc_server_credentials* grpc_ssl_server_credentials_create(
+ const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
+ size_t num_key_cert_pairs, int force_client_auth, void* reserved);
-/** Same as grpc_ssl_server_credentials_create method except uses
+/** Deprecated in favor of grpc_ssl_server_credentials_create_with_options.
+ Same as grpc_ssl_server_credentials_create method except uses
grpc_ssl_client_certificate_request_type enum to support more ways to
authenticate client cerificates.*/
-GRPCAPI grpc_server_credentials *grpc_ssl_server_credentials_create_ex(
- const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+GRPCAPI grpc_server_credentials* grpc_ssl_server_credentials_create_ex(
+ const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
size_t num_key_cert_pairs,
grpc_ssl_client_certificate_request_type client_certificate_request,
- void *reserved);
+ void* reserved);
+
+typedef struct grpc_ssl_server_credentials_options
+ grpc_ssl_server_credentials_options;
+
+/** Creates an options object using a certificate config. Use this method when
+ the certificates and keys of the SSL server will not change during the
+ server's lifetime.
+ - Takes ownership of the certificate_config parameter. */
+GRPCAPI grpc_ssl_server_credentials_options*
+grpc_ssl_server_credentials_create_options_using_config(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config* certificate_config);
+
+/** Creates an options object using a certificate config fetcher. Use this
+ method to reload the certificates and keys of the SSL server without
+ interrupting the operation of the server. Initial certificate config will be
+ fetched during server initialization.
+ - user_data parameter, if not NULL, contains opaque data which will be passed
+ to the fetcher (see definition of
+ grpc_ssl_server_certificate_config_callback). */
+GRPCAPI grpc_ssl_server_credentials_options*
+grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config_callback cb, void* user_data);
+
+/** Destroys a grpc_ssl_server_credentials_options object. */
+GRPCAPI void grpc_ssl_server_credentials_options_destroy(
+ grpc_ssl_server_credentials_options* options);
+
+/** Creates an SSL server_credentials object using the provided options struct.
+ - Takes ownership of the options parameter. */
+GRPCAPI grpc_server_credentials*
+grpc_ssl_server_credentials_create_with_options(
+ grpc_ssl_server_credentials_options* options);
/** --- Server-side secure ports. --- */
/** Add a HTTP2 over an encrypted link over tcp listener.
Returns bound port number on success, 0 on failure.
REQUIRES: server not started */
-GRPCAPI int grpc_server_add_secure_http2_port(grpc_server *server,
- const char *addr,
- grpc_server_credentials *creds);
+GRPCAPI int grpc_server_add_secure_http2_port(grpc_server* server,
+ const char* addr,
+ grpc_server_credentials* creds);
/** --- Call specific credentials. --- */
/** Sets a credentials to a call. Can only be called on the client side before
grpc_call_start_batch. */
-GRPCAPI grpc_call_error grpc_call_set_credentials(grpc_call *call,
- grpc_call_credentials *creds);
+GRPCAPI grpc_call_error grpc_call_set_credentials(grpc_call* call,
+ grpc_call_credentials* creds);
/** --- Auth Metadata Processing --- */
@@ -348,9 +441,9 @@ GRPCAPI grpc_call_error grpc_call_set_credentials(grpc_call *call,
GRPC_STATUS PERMISSION_DENIED in case of an authorization failure.
- error_details gives details about the error. May be NULL. */
typedef void (*grpc_process_auth_metadata_done_cb)(
- void *user_data, const grpc_metadata *consumed_md, size_t num_consumed_md,
- const grpc_metadata *response_md, size_t num_response_md,
- grpc_status_code status, const char *error_details);
+ void* user_data, const grpc_metadata* consumed_md, size_t num_consumed_md,
+ const grpc_metadata* response_md, size_t num_response_md,
+ grpc_status_code status, const char* error_details);
/** Pluggable server-side metadata processor object. */
typedef struct {
@@ -358,15 +451,15 @@ typedef struct {
channel peer and it is the job of the process function to augment it with
properties derived from the passed-in metadata.
The lifetime of these objects is guaranteed until cb is invoked. */
- void (*process)(void *state, grpc_auth_context *context,
- const grpc_metadata *md, size_t num_md,
- grpc_process_auth_metadata_done_cb cb, void *user_data);
- void (*destroy)(void *state);
- void *state;
+ void (*process)(void* state, grpc_auth_context* context,
+ const grpc_metadata* md, size_t num_md,
+ grpc_process_auth_metadata_done_cb cb, void* user_data);
+ void (*destroy)(void* state);
+ void* state;
} grpc_auth_metadata_processor;
GRPCAPI void grpc_server_credentials_set_auth_metadata_processor(
- grpc_server_credentials *creds, grpc_auth_metadata_processor processor);
+ grpc_server_credentials* creds, grpc_auth_metadata_processor processor);
#ifdef __cplusplus
}
diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h
index fde300dfb1..60e167eb88 100644
--- a/include/grpc/grpc_security_constants.h
+++ b/include/grpc/grpc_security_constants.h
@@ -48,6 +48,13 @@ typedef enum {
GRPC_SSL_ROOTS_OVERRIDE_FAIL
} grpc_ssl_roots_override_result;
+/** Callback results for dynamically loading a SSL certificate config. */
+typedef enum {
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED,
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW,
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL
+} grpc_ssl_certificate_config_reload_status;
+
typedef enum {
/** Server does not request client certificate. A client can present a self
signed or signed certificates if it wishes to do so and they would be
diff --git a/include/grpc/impl/codegen/atm.h b/include/grpc/impl/codegen/atm.h
index 764bee5272..00d83f0604 100644
--- a/include/grpc/impl/codegen/atm.h
+++ b/include/grpc/impl/codegen/atm.h
@@ -79,9 +79,17 @@
#error could not determine platform for atm
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** Adds \a delta to \a *value, clamping the result to the range specified
by \a min and \a max. Returns the new value. */
-gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm *value, gpr_atm delta,
+gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm* value, gpr_atm delta,
gpr_atm min, gpr_atm max);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_IMPL_CODEGEN_ATM_H */
diff --git a/include/grpc/impl/codegen/atm_gcc_atomic.h b/include/grpc/impl/codegen/atm_gcc_atomic.h
index 1793ec22b8..5879708548 100644
--- a/include/grpc/impl/codegen/atm_gcc_atomic.h
+++ b/include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -23,8 +23,13 @@
__atomic_* interface. */
#include <grpc/impl/codegen/port_platform.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
+#define GPR_ATM_MIN INTPTR_MIN
#ifdef GPR_LOW_LEVEL_COUNTERS
extern gpr_atm gpr_counter_atm_cas;
@@ -56,22 +61,22 @@ extern gpr_atm gpr_counter_atm_add;
GPR_ATM_INC_ADD_THEN( \
__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL))
-static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
return GPR_ATM_INC_CAS_THEN(__atomic_compare_exchange_n(
p, &o, n, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED));
}
-static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
return GPR_ATM_INC_CAS_THEN(__atomic_compare_exchange_n(
p, &o, n, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED));
}
-static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
return GPR_ATM_INC_CAS_THEN(__atomic_compare_exchange_n(
p, &o, n, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED));
}
-static __inline int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
return GPR_ATM_INC_CAS_THEN(__atomic_compare_exchange_n(
p, &o, n, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED));
}
@@ -79,4 +84,8 @@ static __inline int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
#define gpr_atm_full_xchg(p, n) \
GPR_ATM_INC_CAS_THEN(__atomic_exchange_n((p), (n), __ATOMIC_ACQ_REL))
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h
index 27ae0f63d5..c0010a3469 100644
--- a/include/grpc/impl/codegen/atm_gcc_sync.h
+++ b/include/grpc/impl/codegen/atm_gcc_sync.h
@@ -25,6 +25,7 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
+#define GPR_ATM_MIN INTPTR_MIN
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
@@ -37,24 +38,24 @@ typedef intptr_t gpr_atm;
#define gpr_atm_full_barrier() (__sync_synchronize())
-static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
+static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_LS_BARRIER_();
return value;
}
-static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
+static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_COMPILE_BARRIER_();
return value;
}
-static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
+static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_LS_BARRIER_();
*p = value;
}
-static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
+static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_COMPILE_BARRIER_();
*p = value;
}
@@ -71,7 +72,7 @@ static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_full_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
-static __inline gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n) {
+static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
gpr_atm cur;
do {
cur = gpr_atm_acq_load(p);
diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h
index dfcaa4cc37..f6b27e5df7 100644
--- a/include/grpc/impl/codegen/atm_windows.h
+++ b/include/grpc/impl/codegen/atm_windows.h
@@ -24,73 +24,74 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
+#define GPR_ATM_MIN INTPTR_MIN
#define gpr_atm_full_barrier MemoryBarrier
-static __inline gpr_atm gpr_atm_acq_load(const gpr_atm *p) {
+static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm result = *p;
gpr_atm_full_barrier();
return result;
}
-static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm *p) {
+static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
/* TODO(dklempner): Can we implement something better here? */
return gpr_atm_acq_load(p);
}
-static __inline void gpr_atm_rel_store(gpr_atm *p, gpr_atm value) {
+static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
gpr_atm_full_barrier();
*p = value;
}
-static __inline void gpr_atm_no_barrier_store(gpr_atm *p, gpr_atm value) {
+static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
/* TODO(ctiller): Can we implement something better here? */
gpr_atm_rel_store(p, value);
}
-static __inline int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
/** InterlockedCompareExchangePointerNoFence() not available on vista or
windows7 */
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
- (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+ (volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
- return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
+ return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
-static __inline int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
- (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+ (volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
- return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG *)p,
+ return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
-static __inline int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeRelease64(
- (volatile LONGLONG *)p, (LONGLONG)n, (LONGLONG)o);
+ (volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
- return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG *)p,
+ return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
-static __inline int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n) {
+static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
- return o == (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
+ return o == (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)n, (LONGLONG)o);
#else
- return o == (gpr_atm)InterlockedCompareExchange((volatile LONG *)p, (LONG)n,
+ return o == (gpr_atm)InterlockedCompareExchange((volatile LONG*)p, (LONG)n,
(LONG)o);
#endif
}
-static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
+static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm* p,
gpr_atm delta) {
/** Use the CAS operation to get pointer-sized fetch and add */
gpr_atm old;
@@ -100,26 +101,26 @@ static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p,
return old;
}
-static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta) {
+static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm* p, gpr_atm delta) {
/** Use a CAS operation to get pointer-sized fetch and add */
gpr_atm old;
#ifdef GPR_ARCH_64
do {
old = *p;
- } while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG *)p,
+ } while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)old + delta,
(LONGLONG)old));
#else
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange(
- (volatile LONG *)p, (LONG)old + delta, (LONG)old));
+ (volatile LONG*)p, (LONG)old + delta, (LONG)old));
#endif
return old;
}
-static __inline gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n) {
- return (gpr_atm)InterlockedExchangePointer((PVOID *)p, (PVOID)n);
+static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
+ return (gpr_atm)InterlockedExchangePointer((PVOID*)p, (PVOID)n);
}
#endif /* GRPC_IMPL_CODEGEN_ATM_WINDOWS_H */
diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h
index fc33305713..f8dfbd1d7d 100644
--- a/include/grpc/impl/codegen/byte_buffer.h
+++ b/include/grpc/impl/codegen/byte_buffer.h
@@ -29,7 +29,7 @@ extern "C" {
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices,
+GRPCAPI grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slices,
size_t nslices);
/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
@@ -38,20 +38,20 @@ GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(grpc_slice *slices,
*
* Increases the reference count for all \a slices processed. The user is
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
- grpc_slice *slices, size_t nslices, grpc_compression_algorithm compression);
+GRPCAPI grpc_byte_buffer* grpc_raw_compressed_byte_buffer_create(
+ grpc_slice* slices, size_t nslices, grpc_compression_algorithm compression);
/** Copies input byte buffer \a bb.
*
* Increases the reference count of all the source slices. The user is
* responsible for calling grpc_byte_buffer_destroy over the returned copy. */
-GRPCAPI grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
+GRPCAPI grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb);
/** Returns the size of the given byte buffer, in bytes. */
-GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
+GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer* bb);
/** Destroys \a byte_buffer deallocating all its memory. */
-GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
+GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer* byte_buffer);
/** Reader for byte buffers. Iterates over slices in the byte buffer */
struct grpc_byte_buffer_reader;
@@ -59,25 +59,25 @@ typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
/** Initialize \a reader to read over \a buffer.
* Returns 1 upon success, 0 otherwise. */
-GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
- grpc_byte_buffer *buffer);
+GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer);
/** Cleanup and destroy \a reader */
-GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
+GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader);
/** Updates \a slice with the next piece of data from from \a reader and returns
* 1. Returns 0 at the end of the stream. Caller is responsible for calling
* grpc_slice_unref on the result. */
-GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
- grpc_slice *slice);
+GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ grpc_slice* slice);
/** Merge all data from \a reader into single slice */
GRPCAPI grpc_slice
-grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
+grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader);
/** Returns a RAW byte buffer instance from the output of \a reader. */
-GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
- grpc_byte_buffer_reader *reader);
+GRPCAPI grpc_byte_buffer* grpc_raw_byte_buffer_from_reader(
+ grpc_byte_buffer_reader* reader);
#ifdef __cplusplus
}
diff --git a/include/grpc/impl/codegen/byte_buffer_reader.h b/include/grpc/impl/codegen/byte_buffer_reader.h
index dc0f15496f..e06e19558a 100644
--- a/include/grpc/impl/codegen/byte_buffer_reader.h
+++ b/include/grpc/impl/codegen/byte_buffer_reader.h
@@ -26,8 +26,8 @@ extern "C" {
struct grpc_byte_buffer;
struct grpc_byte_buffer_reader {
- struct grpc_byte_buffer *buffer_in;
- struct grpc_byte_buffer *buffer_out;
+ struct grpc_byte_buffer* buffer_in;
+ struct grpc_byte_buffer* buffer_out;
/** Different current objects correspond to different types of byte buffers */
union grpc_byte_buffer_reader_current {
/** Index into a slice buffer's array of slices */
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 4419e2a447..ddc667fcdb 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -29,11 +29,6 @@ extern "C" {
* algorithm */
#define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
"grpc-internal-encoding-request"
-/** To be used as initial metadata key for the request of a concrete stream
- * compression
- * algorithm */
-#define GRPC_STREAM_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
- "grpc-internal-stream-encoding-request"
/** To be used in channel arguments.
*
@@ -43,17 +38,9 @@ extern "C" {
* Its value is an int from the \a grpc_compression_algorithm enum. */
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
"grpc.default_compression_algorithm"
-/** Default stream compression algorithm for the channel.
- * Its value is an int from the \a grpc_stream_compression_algorithm enum. */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
- "grpc.default_stream_compression_algorithm"
/** Default compression level for the channel.
* Its value is an int from the \a grpc_compression_level enum. */
#define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level"
-/** Default stream compression level for the channel.
- * Its value is an int from the \a grpc_stream_compression_level enum. */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_LEVEL \
- "grpc.default_stream_compression_level"
/** Compression algorithms supported by the channel.
* Its value is a bitset (an int). Bits correspond to algorithms in \a
* grpc_compression_algorithm. For example, its LSB corresponds to
@@ -63,33 +50,18 @@ extern "C" {
* be ignored). */
#define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \
"grpc.compression_enabled_algorithms_bitset"
-/** Stream compression algorithms supported by the channel.
- * Its value is a bitset (an int). Bits correspond to algorithms in \a
- * grpc_stream_compression_algorithm. For example, its LSB corresponds to
- * GRPC_STREAM_COMPRESS_NONE, the next bit to GRPC_STREAM_COMPRESS_DEFLATE, etc.
- * Unset bits disable support for the algorithm. By default all algorithms are
- * supported. It's not possible to disable GRPC_STREAM_COMPRESS_NONE (the
- * attempt will be ignored). */
-#define GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \
- "grpc.stream_compression_enabled_algorithms_bitset"
/** \} */
/** The various compression algorithms supported by gRPC */
typedef enum {
GRPC_COMPRESS_NONE = 0,
- GRPC_COMPRESS_DEFLATE,
- GRPC_COMPRESS_GZIP,
+ GRPC_COMPRESS_MESSAGE_DEFLATE,
+ GRPC_COMPRESS_MESSAGE_GZIP,
+ GRPC_COMPRESS_STREAM_GZIP,
/* TODO(ctiller): snappy */
GRPC_COMPRESS_ALGORITHMS_COUNT
} grpc_compression_algorithm;
-/** Stream compresssion algorithms supported by gRPC */
-typedef enum {
- GRPC_STREAM_COMPRESS_NONE = 0,
- GRPC_STREAM_COMPRESS_GZIP,
- GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT
-} grpc_stream_compression_algorithm;
-
/** Compression levels allow a party with knowledge of its peer's accepted
* encodings to request compression in an abstract way. The level-algorithm
* mapping is performed internally and depends on the peer's supported
@@ -102,41 +74,22 @@ typedef enum {
GRPC_COMPRESS_LEVEL_COUNT
} grpc_compression_level;
-/** Compression levels for stream compression algorithms */
-typedef enum {
- GRPC_STREAM_COMPRESS_LEVEL_NONE = 0,
- GRPC_STREAM_COMPRESS_LEVEL_LOW,
- GRPC_STREAM_COMPRESS_LEVEL_MED,
- GRPC_STREAM_COMPRESS_LEVEL_HIGH,
- GRPC_STREAM_COMPRESS_LEVEL_COUNT
-} grpc_stream_compression_level;
-
typedef struct grpc_compression_options {
/** All algs are enabled by default. This option corresponds to the channel
* argument key behind \a GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET
*/
uint32_t enabled_algorithms_bitset;
- uint32_t enabled_stream_compression_algorithms_bitset;
- /** The default message-wise compression level. It'll be used in the absence
- * of * call specific settings. This option corresponds to the channel
+ /** The default compression level. It'll be used in the absence of call
+ * specific settings. This option corresponds to the channel
* argument key behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL. If present,
- * takes precedence over \a default_algorithm and \a
- * default_stream_compression_algorithm.
+ * takes precedence over \a default_algorithm.
* TODO(dgq): currently only available for server channels. */
struct grpc_compression_options_default_level {
int is_set;
grpc_compression_level level;
} default_level;
- /** The default stream compression level. It'll be used in the absence of call
- * specefic settings. If present, takes precedence over \a default_level,
- * \a default_algorithm and \a default_stream_compression_algorithm. */
- struct grpc_stream_compression_options_default_level {
- int is_set;
- grpc_stream_compression_level level;
- } default_stream_compression_level;
-
/** The default message compression algorithm. It'll be used in the absence of
* call specific settings. This option corresponds to the channel argument key
* behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM. */
@@ -144,17 +97,6 @@ typedef struct grpc_compression_options {
int is_set;
grpc_compression_algorithm algorithm;
} default_algorithm;
-
- /** The default stream compression algorithm. It'll be used in the absence of
- * call specific settings. If present, takes precedence over \a
- * default_algorithm. This option corresponds to the channel
- * argument key behind \a GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM.
- */
- struct grpc_stream_compression_options_default_algorithm {
- int is_set;
- grpc_stream_compression_algorithm algorithm;
- } default_stream_compression_algorithm;
-
} grpc_compression_options;
#ifdef __cplusplus
diff --git a/include/grpc/impl/codegen/connectivity_state.h b/include/grpc/impl/codegen/connectivity_state.h
index 545b4fdbcc..b70dbef356 100644
--- a/include/grpc/impl/codegen/connectivity_state.h
+++ b/include/grpc/impl/codegen/connectivity_state.h
@@ -25,8 +25,6 @@ extern "C" {
/** Connectivity state of a channel. */
typedef enum {
- /** channel has just been initialized */
- GRPC_CHANNEL_INIT = -1,
/** channel is idle */
GRPC_CHANNEL_IDLE,
/** channel is connecting */
diff --git a/include/grpc/impl/codegen/fork.h b/include/grpc/impl/codegen/fork.h
new file mode 100644
index 0000000000..baec7a2f10
--- /dev/null
+++ b/include/grpc/impl/codegen/fork.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_FORK_H
+#define GRPC_IMPL_CODEGEN_FORK_H
+
+/**
+ * gRPC applications should call this before calling fork(). There should be no
+ * active gRPC function calls between calling grpc_prefork() and
+ * grpc_postfork_parent()/grpc_postfork_child().
+ *
+ *
+ * Typical use:
+ * grpc_prefork();
+ * int pid = fork();
+ * if (pid) {
+ * grpc_postfork_parent();
+ * // Parent process..
+ * } else {
+ * grpc_postfork_child();
+ * // Child process...
+ * }
+ */
+
+void grpc_prefork();
+
+void grpc_postfork_parent();
+
+void grpc_postfork_child();
+
+void grpc_fork_handlers_auto_register();
+
+#endif /* GRPC_IMPL_CODEGEN_FORK_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 90f03f49a3..e5aa29b88a 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -22,7 +22,6 @@
#include <grpc/impl/codegen/port_platform.h>
#include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <grpc/impl/codegen/gpr_types.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/status.h>
@@ -39,11 +38,11 @@ typedef enum {
} grpc_byte_buffer_type;
typedef struct grpc_byte_buffer {
- void *reserved;
+ void* reserved;
grpc_byte_buffer_type type;
union grpc_byte_buffer_data {
struct /* internal */ {
- void *reserved[8];
+ void* reserved[8];
} reserved;
struct grpc_compressed_buffer {
grpc_compression_algorithm compression;
@@ -84,9 +83,9 @@ typedef enum {
} grpc_arg_type;
typedef struct grpc_arg_pointer_vtable {
- void *(*copy)(void *p);
- void (*destroy)(grpc_exec_ctx *exec_ctx, void *p);
- int (*cmp)(void *p, void *q);
+ void* (*copy)(void* p);
+ void (*destroy)(void* p);
+ int (*cmp)(void* p, void* q);
} grpc_arg_pointer_vtable;
/** A single argument... each argument has a key and a value
@@ -103,13 +102,13 @@ typedef struct grpc_arg_pointer_vtable {
their keys so that it's possible to change them in the future. */
typedef struct {
grpc_arg_type type;
- char *key;
+ char* key;
union grpc_arg_value {
- char *string;
+ char* string;
int integer;
struct grpc_arg_pointer {
- void *p;
- const grpc_arg_pointer_vtable *vtable;
+ void* p;
+ const grpc_arg_pointer_vtable* vtable;
} pointer;
} value;
} grpc_arg;
@@ -127,7 +126,7 @@ typedef struct {
details. */
typedef struct {
size_t num_args;
- grpc_arg *args;
+ grpc_arg* args;
} grpc_channel_args;
/** \defgroup grpc_arg_keys
@@ -240,6 +239,9 @@ typedef struct {
/** The time between the first and second connection attempts, in ms */
#define GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS \
"grpc.initial_reconnect_backoff_ms"
+/** The timeout used on servers for finishing handshaking on an incoming
+ connection. Defaults to 120 seconds. */
+#define GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS "grpc.server_handshake_timeout_ms"
/** This *should* be used for testing only.
The caller of the secure_channel_create functions may override the target
name used for SSL host name checking using this channel argument which is of
@@ -288,7 +290,11 @@ typedef struct {
"grpc.experimental.tcp_max_read_chunk_size"
/* Timeout in milliseconds to use for calls to the grpclb load balancer.
If 0 or unset, the balancer calls will have no deadline. */
-#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_timeout_ms"
+#define GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS "grpc.grpclb_call_timeout_ms"
+/* Timeout in milliseconds to wait for the serverlist from the grpclb load
+ balancer before using fallback backend addresses from the resolver.
+ If 0, fallback will never be used. */
+#define GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS "grpc.grpclb_fallback_timeout_ms"
/** If non-zero, grpc server's cronet compression workaround will be enabled */
#define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \
"grpc.workaround.cronet_compression"
@@ -396,7 +402,7 @@ typedef struct grpc_metadata {
There is no need to initialize them, and they will be set to garbage
during calls to grpc. */
struct /* internal */ {
- void *obfuscated[4];
+ void* obfuscated[4];
} internal_data;
} grpc_metadata;
@@ -424,13 +430,13 @@ typedef struct grpc_event {
int success;
/** The tag passed to grpc_call_start_batch etc to start this operation.
Only GRPC_OP_COMPLETE has a tag. */
- void *tag;
+ void* tag;
} grpc_event;
typedef struct {
size_t count;
size_t capacity;
- grpc_metadata *metadata;
+ grpc_metadata* metadata;
} grpc_metadata_array;
typedef struct {
@@ -438,7 +444,7 @@ typedef struct {
grpc_slice host;
gpr_timespec deadline;
uint32_t flags;
- void *reserved;
+ void* reserved;
} grpc_call_details;
typedef enum {
@@ -494,25 +500,21 @@ typedef struct grpc_op {
/** Write flags bitset for grpc_begin_messages */
uint32_t flags;
/** Reserved for future usage */
- void *reserved;
+ void* reserved;
union grpc_op_data {
/** Reserved for future usage */
struct /* internal */ {
- void *reserved[8];
+ void* reserved[8];
} reserved;
struct grpc_op_send_initial_metadata {
size_t count;
- grpc_metadata *metadata;
+ grpc_metadata* metadata;
/** If \a is_set, \a compression_level will be used for the call.
* Otherwise, \a compression_level won't be considered */
struct grpc_op_send_initial_metadata_maybe_compression_level {
uint8_t is_set;
grpc_compression_level level;
} maybe_compression_level;
- struct grpc_op_send_initial_metadata_maybe_stream_compression_level {
- uint8_t is_set;
- grpc_stream_compression_level level;
- } maybe_stream_compression_level;
} send_initial_metadata;
struct grpc_op_send_message {
/** This op takes ownership of the slices in send_message. After
@@ -520,16 +522,16 @@ typedef struct grpc_op {
* and likely empty. The original owner should still call
* grpc_byte_buffer_destroy() on this object however.
*/
- struct grpc_byte_buffer *send_message;
+ struct grpc_byte_buffer* send_message;
} send_message;
struct grpc_op_send_status_from_server {
size_t trailing_metadata_count;
- grpc_metadata *trailing_metadata;
+ grpc_metadata* trailing_metadata;
grpc_status_code status;
/** optional: set to NULL if no details need sending, non-NULL if they do
* pointer will not be retained past the start_batch call
*/
- grpc_slice *status_details;
+ grpc_slice* status_details;
} send_status_from_server;
/** ownership of the array is with the caller, but ownership of the elements
stays with the call object (ie key, value members are owned by the call
@@ -537,13 +539,13 @@ typedef struct grpc_op {
After the operation completes, call grpc_metadata_array_destroy on this
value, or reuse it in a future op. */
struct grpc_op_recv_initial_metadata {
- grpc_metadata_array *recv_initial_metadata;
+ grpc_metadata_array* recv_initial_metadata;
} recv_initial_metadata;
/** ownership of the byte buffer is moved to the caller; the caller must
call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
*/
struct grpc_op_recv_message {
- struct grpc_byte_buffer **recv_message;
+ struct grpc_byte_buffer** recv_message;
} recv_message;
struct grpc_op_recv_status_on_client {
/** ownership of the array is with the caller, but ownership of the
@@ -551,14 +553,18 @@ typedef struct grpc_op {
by the call object, trailing_metadata->array is owned by the caller).
After the operation completes, call grpc_metadata_array_destroy on
this value, or reuse it in a future op. */
- grpc_metadata_array *trailing_metadata;
- grpc_status_code *status;
- grpc_slice *status_details;
+ grpc_metadata_array* trailing_metadata;
+ grpc_status_code* status;
+ grpc_slice* status_details;
+ /** If this is not nullptr, it will be populated with the full fidelity
+ * error string for debugging purposes. The application is responsible
+ * for freeing the data by using gpr_free(). */
+ const char** error_string;
} recv_status_on_client;
struct grpc_op_recv_close_on_server {
/** out argument, set to 1 if the call failed in any way (seen as a
cancellation on the server), or 0 if the call succeeded */
- int *cancelled;
+ int* cancelled;
} recv_close_on_server;
} data;
} grpc_op;
@@ -567,10 +573,10 @@ typedef struct grpc_op {
typedef struct {
/** If non-NULL, will be set to point to a string indicating the LB
* policy name. Caller takes ownership. */
- char **lb_policy_name;
+ char** lb_policy_name;
/** If non-NULL, will be set to point to a string containing the
* service config used by the channel in JSON form. */
- char **service_config_json;
+ char** service_config_json;
} grpc_channel_info;
typedef struct grpc_resource_quota grpc_resource_quota;
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 1904c636f7..819d17ce2a 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -173,6 +173,7 @@
#endif /* _LP64 */
#ifdef __GLIBC__
#define GPR_POSIX_CRASH_HANDLER 1
+#define GPR_LINUX_PTHREAD_NAME 1
#else /* musl libc */
#define GPR_MUSL_LIBC_COMPAT 1
#endif
@@ -183,7 +184,6 @@
#define _BSD_SOURCE
#endif
#if TARGET_OS_IPHONE
-#define GPR_FORBID_UNREACHABLE_CODE 1
#define GPR_PLATFORM_STRING "ios"
#define GPR_CPU_IPHONE 1
#define GPR_PTHREAD_TLS 1
@@ -195,11 +195,25 @@
#define GPR_PTHREAD_TLS 1
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */
#define GPR_CPU_POSIX 1
+/* TODO(vjpai): there is a reported issue in bazel build for Mac where __thread
+ in a header is currently not working (bazelbuild/bazel#4341). Remove
+ the following conditional and use GPR_GCC_TLS when that is fixed */
+#ifndef GRPC_BAZEL_BUILD
#define GPR_GCC_TLS 1
+#else /* GRPC_BAZEL_BUILD */
+#define GPR_PTHREAD_TLS 1
+#endif /* GRPC_BAZEL_BUILD */
+#define GPR_APPLE_PTHREAD_NAME 1
#endif
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */
#define GPR_CPU_POSIX 1
+/* TODO(vjpai): Remove the following conditional and use only GPR_GCC_TLS
+ when bazelbuild/bazel#4341 is fixed */
+#ifndef GRPC_BAZEL_BUILD
#define GPR_GCC_TLS 1
+#else /* GRPC_BAZEL_BUILD */
+#define GPR_PTHREAD_TLS 1
+#endif /* GRPC_BAZEL_BUILD */
#endif
#define GPR_POSIX_CRASH_HANDLER 1
#endif
@@ -242,6 +256,29 @@
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
+#elif defined(__OpenBSD__)
+#define GPR_PLATFORM_STRING "openbsd"
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#define GPR_OPENBSD 1
+#define GPR_CPU_POSIX 1
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#define GPR_POSIX_LOG 1
+#define GPR_POSIX_ENV 1
+#define GPR_POSIX_TMPFILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
+#ifdef _LP64
+#define GPR_ARCH_64 1
+#else /* _LP64 */
+#define GPR_ARCH_32 1
+#endif /* _LP64 */
#elif defined(__native_client__)
#define GPR_PLATFORM_STRING "nacl"
#ifndef _BSD_SOURCE
@@ -275,6 +312,30 @@
#endif
#endif /* GPR_NO_AUTODETECT_PLATFORM */
+/*
+ * There are platforms for which TLS should not be used even though the
+ * compiler makes it seem like it's supported (Android NDK < r12b for example).
+ * This is primarily because of linker problems and toolchain misconfiguration:
+ * TLS isn't supported until NDK r12b per
+ * https://developer.android.com/ndk/downloads/revision_history.html
+ * TLS also does not work with Android NDK if GCC is being used as the compiler
+ * instead of Clang.
+ * Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in
+ * <android/ndk-version.h>. For NDK < r16, users should define these macros,
+ * e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. */
+#if defined(__ANDROID__) && defined(GPR_GCC_TLS)
+#if __has_include(<android/ndk-version.h>)
+#include <android/ndk-version.h>
+#endif /* __has_include(<android/ndk-version.h>) */
+#if (defined(__clang__) && defined(__NDK_MAJOR__) && defined(__NDK_MINOR__) && \
+ ((__NDK_MAJOR__ < 12) || \
+ ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))) || \
+ (defined(__GNUC__) && !defined(__clang__))
+#undef GPR_GCC_TLS
+#define GPR_PTHREAD_TLS 1
+#endif
+#endif /*defined(__ANDROID__) && defined(GPR_GCC_TLS) */
+
#if defined(__has_include)
#if __has_include(<atomic>)
#define GRPC_HAS_CXX11_ATOMIC
@@ -292,10 +353,6 @@
#endif
#ifdef _MSC_VER
-#ifdef _PYTHON_MSVC
-// The Python 3.5 Windows runtime is missing InetNtop
-#define GPR_WIN_INET_NTOP
-#endif // _PYTHON_MSVC
#if _MSC_VER < 1700
typedef __int8 int8_t;
typedef __int16 int16_t;
@@ -377,6 +434,14 @@ typedef unsigned __int64 uint64_t;
#endif
#endif
+#ifndef GRPC_UNUSED
+#if defined(__GNUC__) && !defined(__MINGW32__)
+#define GRPC_UNUSED __attribute__((unused))
+#else
+#define GRPC_UNUSED
+#endif
+#endif
+
#ifndef GPR_PRINT_FORMAT_CHECK
#ifdef __GNUC__
#define GPR_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS) \
@@ -420,4 +485,23 @@ typedef unsigned __int64 uint64_t;
#endif /* GPR_ATTRIBUTE_NO_TSAN (2) */
#endif /* GPR_ATTRIBUTE_NO_TSAN (1) */
+/* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */
+#ifndef GRPC_ALLOW_EXCEPTIONS
+/* If not already set, set to 1 on Windows (style guide standard) but to
+ * 0 on non-Windows platforms unless the compiler defines __EXCEPTIONS */
+#ifdef GPR_WINDOWS
+#define GRPC_ALLOW_EXCEPTIONS 1
+#else /* GPR_WINDOWS */
+#ifdef __EXCEPTIONS
+#define GRPC_ALLOW_EXCEPTIONS 1
+#else /* __EXCEPTIONS */
+#define GRPC_ALLOW_EXCEPTIONS 0
+#endif /* __EXCEPTIONS */
+#endif /* __GPR_WINDOWS */
+#endif /* GRPC_ALLOW_EXCEPTIONS */
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
#endif /* GRPC_IMPL_CODEGEN_PORT_PLATFORM_H */
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index 128fa8e121..a3cd1f1bbe 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -23,7 +23,6 @@
#include <stddef.h>
-#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <grpc/impl/codegen/gpr_slice.h>
typedef struct grpc_slice grpc_slice;
@@ -42,8 +41,8 @@ typedef struct grpc_slice grpc_slice;
constraints (is the callee allowed to modify the slice?) */
typedef struct grpc_slice_refcount_vtable {
- void (*ref)(void *);
- void (*unref)(grpc_exec_ctx *exec_ctx, void *);
+ void (*ref)(void*);
+ void (*unref)(void*);
int (*eq)(grpc_slice a, grpc_slice b);
uint32_t (*hash)(grpc_slice slice);
} grpc_slice_refcount_vtable;
@@ -54,20 +53,20 @@ typedef struct grpc_slice_refcount_vtable {
Typically client code should not touch this, and use grpc_slice_malloc,
grpc_slice_new, or grpc_slice_new_with_len instead. */
typedef struct grpc_slice_refcount {
- const grpc_slice_refcount_vtable *vtable;
+ const grpc_slice_refcount_vtable* vtable;
/** If a subset of this slice is taken, use this pointer for the refcount.
Typically points back to the refcount itself, however iterning
implementations can use this to avoid a verification step on each hash
or equality check */
- struct grpc_slice_refcount *sub_refcount;
+ struct grpc_slice_refcount* sub_refcount;
} grpc_slice_refcount;
/* Inlined half of grpc_slice is allowed to expand the size of the overall type
by this many bytes */
-#define GRPC_SLICE_INLINE_EXTRA_SIZE sizeof(void *)
+#define GRPC_SLICE_INLINE_EXTRA_SIZE sizeof(void*)
#define GRPC_SLICE_INLINED_SIZE \
- (sizeof(size_t) + sizeof(uint8_t *) - 1 + GRPC_SLICE_INLINE_EXTRA_SIZE)
+ (sizeof(size_t) + sizeof(uint8_t*) - 1 + GRPC_SLICE_INLINE_EXTRA_SIZE)
/** A grpc_slice s, if initialized, represents the byte range
s.bytes[0..s.length-1].
@@ -79,10 +78,10 @@ typedef struct grpc_slice_refcount {
If the slice does not have a refcount, it represents an inlined small piece
of data that is copied by value. */
struct grpc_slice {
- struct grpc_slice_refcount *refcount;
+ struct grpc_slice_refcount* refcount;
union grpc_slice_data {
struct grpc_slice_refcounted {
- uint8_t *bytes;
+ uint8_t* bytes;
size_t length;
} refcounted;
struct grpc_slice_inlined {
@@ -99,10 +98,10 @@ struct grpc_slice {
typedef struct {
/** This is for internal use only. External users (i.e any code outside grpc
* core) MUST NOT use this field */
- grpc_slice *base_slices;
+ grpc_slice* base_slices;
/** slices in the array (Points to the first valid grpc_slice in the array) */
- grpc_slice *slices;
+ grpc_slice* slices;
/** the number of slices in the array */
size_t count;
/** the number of slices allocated in the array. External users (i.e any code
diff --git a/include/grpc/impl/codegen/sync_generic.h b/include/grpc/impl/codegen/sync_generic.h
index e1eea54298..83f905e120 100644
--- a/include/grpc/impl/codegen/sync_generic.h
+++ b/include/grpc/impl/codegen/sync_generic.h
@@ -23,16 +23,22 @@
#include <grpc/impl/codegen/atm.h>
/* gpr_event */
-typedef struct { gpr_atm state; } gpr_event;
+typedef struct {
+ gpr_atm state;
+} gpr_event;
#define GPR_EVENT_INIT \
{ 0 }
/* gpr_refcount */
-typedef struct { gpr_atm count; } gpr_refcount;
+typedef struct {
+ gpr_atm count;
+} gpr_refcount;
/* gpr_stats_counter */
-typedef struct { gpr_atm value; } gpr_stats_counter;
+typedef struct {
+ gpr_atm value;
+} gpr_stats_counter;
#define GPR_STATS_INIT \
{ 0 }
diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap
index 51bfef2cc9..d23072f556 100644
--- a/include/grpc/module.modulemap
+++ b/include/grpc/module.modulemap
@@ -1,12 +1,83 @@
+
framework module grpc {
umbrella header "grpc.h"
- header "byte_buffer_reader.h"
- header "grpc_security.h"
- header "grpc_security_constants.h"
header "support/alloc.h"
+ header "support/atm.h"
+ header "support/avl.h"
+ header "support/cmdline.h"
+ header "support/cpu.h"
+ header "support/host_port.h"
+ header "support/log.h"
+ header "support/log_windows.h"
header "support/port_platform.h"
header "support/string_util.h"
+ header "support/subprocess.h"
+ header "support/sync.h"
+ header "support/sync_generic.h"
+ header "support/thd.h"
+ header "support/time.h"
+ header "support/tls.h"
+ header "support/useful.h"
+ header "impl/codegen/atm.h"
+ header "impl/codegen/fork.h"
+ header "impl/codegen/gpr_slice.h"
+ header "impl/codegen/gpr_types.h"
+ header "impl/codegen/port_platform.h"
+ header "impl/codegen/sync.h"
+ header "impl/codegen/sync_generic.h"
+ header "impl/codegen/byte_buffer.h"
+ header "impl/codegen/byte_buffer_reader.h"
+ header "impl/codegen/compression_types.h"
+ header "impl/codegen/connectivity_state.h"
+ header "impl/codegen/grpc_types.h"
+ header "impl/codegen/propagation_bits.h"
+ header "impl/codegen/slice.h"
+ header "impl/codegen/status.h"
+ header "impl/codegen/atm.h"
+ header "impl/codegen/fork.h"
+ header "impl/codegen/gpr_slice.h"
+ header "impl/codegen/gpr_types.h"
+ header "impl/codegen/port_platform.h"
+ header "impl/codegen/sync.h"
+ header "impl/codegen/sync_generic.h"
+ header "grpc_security.h"
+ header "byte_buffer.h"
+ header "byte_buffer_reader.h"
+ header "compression.h"
+ header "compression_ruby.h"
+ header "fork.h"
+ header "grpc.h"
+ header "grpc_posix.h"
+ header "grpc_security_constants.h"
+ header "load_reporting.h"
+ header "slice.h"
+ header "slice_buffer.h"
+ header "status.h"
+ header "support/workaround_list.h"
+ header "census.h"
+
+ textual header "support/atm_gcc_atomic.h"
+ textual header "support/atm_gcc_sync.h"
+ textual header "support/atm_windows.h"
+ textual header "support/sync_custom.h"
+ textual header "support/sync_posix.h"
+ textual header "support/sync_windows.h"
+ textual header "support/tls_gcc.h"
+ textual header "support/tls_msvc.h"
+ textual header "support/tls_pthread.h"
+ textual header "impl/codegen/atm_gcc_atomic.h"
+ textual header "impl/codegen/atm_gcc_sync.h"
+ textual header "impl/codegen/atm_windows.h"
+ textual header "impl/codegen/sync_custom.h"
+ textual header "impl/codegen/sync_posix.h"
+ textual header "impl/codegen/sync_windows.h"
+ textual header "impl/codegen/atm_gcc_atomic.h"
+ textual header "impl/codegen/atm_gcc_sync.h"
+ textual header "impl/codegen/atm_windows.h"
+ textual header "impl/codegen/sync_custom.h"
+ textual header "impl/codegen/sync_posix.h"
+ textual header "impl/codegen/sync_windows.h"
export *
module * { export * }
diff --git a/include/grpc/slice.h b/include/grpc/slice.h
index 3f3cff1408..10b6a624b3 100644
--- a/include/grpc/slice.h
+++ b/include/grpc/slice.h
@@ -44,20 +44,20 @@ GPRAPI grpc_slice grpc_slice_copy(grpc_slice s);
/** 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 pointer
passed in at destruction. */
-GPRAPI grpc_slice grpc_slice_new(void *p, size_t len, void (*destroy)(void *));
+GPRAPI grpc_slice grpc_slice_new(void* p, size_t len, void (*destroy)(void*));
/** Equivalent to grpc_slice_new, but with a separate pointer that is
passed to the destroy function. This function can be useful when
the data is part of a larger structure that must be destroyed when
the data is no longer needed. */
-GPRAPI grpc_slice grpc_slice_new_with_user_data(void *p, size_t len,
- void (*destroy)(void *),
- void *user_data);
+GPRAPI grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
+ void (*destroy)(void*),
+ void* user_data);
/** Equivalent to grpc_slice_new, but with a two argument destroy function that
also takes the slice length. */
-GPRAPI grpc_slice grpc_slice_new_with_len(void *p, size_t len,
- void (*destroy)(void *, size_t));
+GPRAPI grpc_slice grpc_slice_new_with_len(void* p, size_t len,
+ void (*destroy)(void*, size_t));
/** Equivalent to grpc_slice_new(malloc(len), len, free), but saves one malloc()
call.
@@ -79,19 +79,19 @@ GPRAPI grpc_slice grpc_slice_intern(grpc_slice slice);
size_t len = strlen(source);
grpc_slice slice = grpc_slice_malloc(len);
memcpy(slice->data, source, len); */
-GPRAPI grpc_slice grpc_slice_from_copied_string(const char *source);
+GPRAPI grpc_slice grpc_slice_from_copied_string(const char* source);
/** Create a slice by copying a buffer.
Equivalent to:
grpc_slice slice = grpc_slice_malloc(len);
memcpy(slice->data, source, len); */
-GPRAPI grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len);
+GPRAPI grpc_slice grpc_slice_from_copied_buffer(const char* source, size_t len);
/** Create a slice pointing to constant memory */
-GPRAPI grpc_slice grpc_slice_from_static_string(const char *source);
+GPRAPI grpc_slice grpc_slice_from_static_string(const char* source);
/** Create a slice pointing to constant memory */
-GPRAPI grpc_slice grpc_slice_from_static_buffer(const void *source, size_t len);
+GPRAPI grpc_slice grpc_slice_from_static_buffer(const void* source, size_t len);
/** Return a result slice derived from s, which shares a ref count with \a s,
where result.data==s.data+begin, and result.length==end-begin. The ref count
@@ -106,7 +106,7 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end);
/** Splits s into two: modifies s to be s[0:split], and returns a new slice,
sharing a refcount with s, that contains s[split:s.length].
Requires s intialized, split <= s.length */
-GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice *s, size_t split);
+GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split);
typedef enum {
GRPC_SLICE_REF_TAIL = 1,
@@ -117,13 +117,13 @@ typedef enum {
/** The same as grpc_slice_split_tail, but with an option to skip altering
* refcounts (grpc_slice_split_tail_maybe_ref(..., true) is equivalent to
* grpc_slice_split_tail(...)) */
-GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice *s, size_t split,
+GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* s, size_t split,
grpc_slice_ref_whom ref_whom);
/** Splits s into two: modifies s to be s[split:s.length], and returns a new
slice, sharing a refcount with s, that contains s[0:split].
Requires s intialized, split <= s.length */
-GPRAPI grpc_slice grpc_slice_split_head(grpc_slice *s, size_t split);
+GPRAPI grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split);
GPRAPI grpc_slice grpc_empty_slice(void);
@@ -136,11 +136,10 @@ GPRAPI int grpc_slice_eq(grpc_slice a, grpc_slice b);
The order is arbitrary, and is not guaranteed to be stable across different
versions of the API. */
GPRAPI int grpc_slice_cmp(grpc_slice a, grpc_slice b);
-GPRAPI int grpc_slice_str_cmp(grpc_slice a, const char *b);
-GPRAPI int grpc_slice_buf_cmp(grpc_slice a, const void *b, size_t blen);
+GPRAPI int grpc_slice_str_cmp(grpc_slice a, const char* b);
/** return non-zero if the first blen bytes of a are equal to b */
-GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void *b, size_t blen);
+GPRAPI int grpc_slice_buf_start_eq(grpc_slice a, const void* b, size_t blen);
/** return the index of the last instance of \a c in \a s, or -1 if not found */
GPRAPI int grpc_slice_rchr(grpc_slice s, char c);
@@ -162,7 +161,7 @@ GPRAPI grpc_slice grpc_slice_dup(grpc_slice a);
/** Return a copy of slice as a C string. Offers no protection against embedded
NULL's. Returned string must be freed with gpr_free. */
-GPRAPI char *grpc_slice_to_c_string(grpc_slice s);
+GPRAPI char* grpc_slice_to_c_string(grpc_slice s);
#ifdef __cplusplus
}
diff --git a/include/grpc/slice_buffer.h b/include/grpc/slice_buffer.h
index de4b86f777..30833d02db 100644
--- a/include/grpc/slice_buffer.h
+++ b/include/grpc/slice_buffer.h
@@ -26,13 +26,13 @@ extern "C" {
#endif
/** initialize a slice buffer */
-GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer *sb);
+GPRAPI void grpc_slice_buffer_init(grpc_slice_buffer* sb);
/** destroy a slice buffer - unrefs any held elements */
-GPRAPI void grpc_slice_buffer_destroy(grpc_slice_buffer *sb);
+GPRAPI void grpc_slice_buffer_destroy(grpc_slice_buffer* sb);
/** Add an element to a slice buffer - takes ownership of the slice.
This function is allowed to concatenate the passed in slice to the end of
some other slice if desired by the slice buffer. */
-GPRAPI void grpc_slice_buffer_add(grpc_slice_buffer *sb, grpc_slice slice);
+GPRAPI void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice);
/** add an element to a slice buffer - takes ownership of the slice and returns
the index of the slice.
Guarantees that the slice will not be concatenated at the end of another
@@ -40,40 +40,39 @@ GPRAPI void grpc_slice_buffer_add(grpc_slice_buffer *sb, grpc_slice slice);
slice at the returned index in sb->slices)
The implementation MAY decide to concatenate data at the end of a small
slice added in this fashion. */
-GPRAPI size_t grpc_slice_buffer_add_indexed(grpc_slice_buffer *sb,
+GPRAPI size_t grpc_slice_buffer_add_indexed(grpc_slice_buffer* sb,
grpc_slice slice);
-GPRAPI void grpc_slice_buffer_addn(grpc_slice_buffer *sb, grpc_slice *slices,
+GPRAPI void grpc_slice_buffer_addn(grpc_slice_buffer* sb, grpc_slice* slices,
size_t n);
/** add a very small (less than 8 bytes) amount of data to the end of a slice
buffer: returns a pointer into which to add the data */
-GPRAPI uint8_t *grpc_slice_buffer_tiny_add(grpc_slice_buffer *sb, size_t len);
+GPRAPI uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t len);
/** pop the last buffer, but don't unref it */
-GPRAPI void grpc_slice_buffer_pop(grpc_slice_buffer *sb);
+GPRAPI void grpc_slice_buffer_pop(grpc_slice_buffer* sb);
/** clear a slice buffer, unref all elements */
-GPRAPI void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer *sb);
+GPRAPI void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb);
/** swap the contents of two slice buffers */
-GPRAPI void grpc_slice_buffer_swap(grpc_slice_buffer *a, grpc_slice_buffer *b);
+GPRAPI void grpc_slice_buffer_swap(grpc_slice_buffer* a, grpc_slice_buffer* b);
/** move all of the elements of src into dst */
-GPRAPI void grpc_slice_buffer_move_into(grpc_slice_buffer *src,
- grpc_slice_buffer *dst);
+GPRAPI void grpc_slice_buffer_move_into(grpc_slice_buffer* src,
+ grpc_slice_buffer* dst);
/** remove n bytes from the end of a slice buffer */
-GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer *src, size_t n,
- grpc_slice_buffer *garbage);
+GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer* src, size_t n,
+ grpc_slice_buffer* garbage);
/** move the first n bytes of src into dst */
-GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer *src, size_t n,
- grpc_slice_buffer *dst);
+GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer* src, size_t n,
+ grpc_slice_buffer* dst);
/** move the first n bytes of src into dst without adding references */
-GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer *src,
+GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer* src,
size_t n,
- grpc_slice_buffer *dst);
+ grpc_slice_buffer* dst);
/** move the first n bytes of src into dst (copying them) */
-GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx *exec_ctx,
- grpc_slice_buffer *src,
- size_t n, void *dst);
+GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_slice_buffer* src,
+ size_t n, void* dst);
/** take the first slice in the slice buffer */
-GPRAPI grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer *src);
+GPRAPI grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* src);
/** undo the above with (a possibly different) \a slice */
-GPRAPI void grpc_slice_buffer_undo_take_first(grpc_slice_buffer *src,
+GPRAPI void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* src,
grpc_slice slice);
#ifdef __cplusplus
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 4b59e137f2..577d4f0069 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -28,10 +28,10 @@ extern "C" {
#endif
typedef struct gpr_allocation_functions {
- void *(*malloc_fn)(size_t size);
- void *(*zalloc_fn)(size_t size); /** if NULL, uses malloc_fn then memset */
- void *(*realloc_fn)(void *ptr, size_t size);
- void (*free_fn)(void *ptr);
+ void* (*malloc_fn)(size_t size);
+ void* (*zalloc_fn)(size_t size); /** if NULL, uses malloc_fn then memset */
+ void* (*realloc_fn)(void* ptr, size_t size);
+ void (*free_fn)(void* ptr);
} gpr_allocation_functions;
/** malloc.
@@ -39,17 +39,18 @@ typedef struct gpr_allocation_functions {
* The pointer returned is suitably aligned for any kind of variable it could
* contain.
*/
-GPRAPI void *gpr_malloc(size_t size);
+GPRAPI void* gpr_malloc(size_t size);
/** like malloc, but zero all bytes before returning them */
-GPRAPI void *gpr_zalloc(size_t size);
+GPRAPI void* gpr_zalloc(size_t size);
/** free */
-GPRAPI void gpr_free(void *ptr);
+GPRAPI void gpr_free(void* ptr);
/** realloc, never returns NULL */
-GPRAPI void *gpr_realloc(void *p, size_t size);
-/** aligned malloc, never returns NULL, will align to 1 << alignment_log */
-GPRAPI void *gpr_malloc_aligned(size_t size, size_t alignment_log);
+GPRAPI void* gpr_realloc(void* p, size_t size);
+/** aligned malloc, never returns NULL, will align to alignment, which
+ * must be a power of 2. */
+GPRAPI void* gpr_malloc_aligned(size_t size, size_t alignment);
/** free memory allocated by gpr_malloc_aligned */
-GPRAPI void gpr_free_aligned(void *ptr);
+GPRAPI void gpr_free_aligned(void* ptr);
/** Request the family of allocation functions in \a functions be used. NOTE
* that this request will be honored in a *best effort* basis and that no
@@ -58,7 +59,7 @@ GPRAPI void gpr_free_aligned(void *ptr);
GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
/** Return the family of allocation functions currently in effect. */
-GPRAPI gpr_allocation_functions gpr_get_allocation_functions();
+GPRAPI gpr_allocation_functions gpr_get_allocation_functions(void);
#ifdef __cplusplus
}
diff --git a/include/grpc/support/avl.h b/include/grpc/support/avl.h
index d53ff5d904..b5a8c0ffa1 100644
--- a/include/grpc/support/avl.h
+++ b/include/grpc/support/avl.h
@@ -21,13 +21,17 @@
#include <grpc/support/sync.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/** internal node of an AVL tree */
typedef struct gpr_avl_node {
gpr_refcount refs;
- void *key;
- void *value;
- struct gpr_avl_node *left;
- struct gpr_avl_node *right;
+ void* key;
+ void* value;
+ struct gpr_avl_node* left;
+ struct gpr_avl_node* right;
long height;
} gpr_avl_node;
@@ -38,57 +42,61 @@ typedef struct gpr_avl_node {
*/
typedef struct gpr_avl_vtable {
/** destroy a key */
- void (*destroy_key)(void *key, void *user_data);
+ void (*destroy_key)(void* key, void* user_data);
/** copy a key, returning new value */
- void *(*copy_key)(void *key, void *user_data);
+ void* (*copy_key)(void* key, void* user_data);
/** compare key1, key2; return <0 if key1 < key2,
>0 if key1 > key2, 0 if key1 == key2 */
- long (*compare_keys)(void *key1, void *key2, void *user_data);
+ long (*compare_keys)(void* key1, void* key2, void* user_data);
/** destroy a value */
- void (*destroy_value)(void *value, void *user_data);
+ void (*destroy_value)(void* value, void* user_data);
/** copy a value */
- void *(*copy_value)(void *value, void *user_data);
+ void* (*copy_value)(void* value, void* user_data);
} gpr_avl_vtable;
/** "pointer" to an AVL tree - this is a reference
counted object - use gpr_avl_ref to add a reference,
gpr_avl_unref when done with a reference */
typedef struct gpr_avl {
- const gpr_avl_vtable *vtable;
- gpr_avl_node *root;
+ const gpr_avl_vtable* vtable;
+ gpr_avl_node* root;
} gpr_avl;
/** Create an immutable AVL tree. */
-GPRAPI gpr_avl gpr_avl_create(const gpr_avl_vtable *vtable);
+GPRAPI gpr_avl gpr_avl_create(const gpr_avl_vtable* vtable);
/** Add a reference to an existing tree - returns
the tree as a convenience. The optional user_data will be passed to vtable
functions. */
-GPRAPI gpr_avl gpr_avl_ref(gpr_avl avl, void *user_data);
+GPRAPI gpr_avl gpr_avl_ref(gpr_avl avl, void* user_data);
/** Remove a reference to a tree - destroying it if there
are no references left. The optional user_data will be passed to vtable
functions. */
-GPRAPI void gpr_avl_unref(gpr_avl avl, void *user_data);
+GPRAPI void gpr_avl_unref(gpr_avl avl, void* user_data);
/** Return a new tree with (key, value) added to avl.
implicitly unrefs avl to allow easy chaining.
if key exists in avl, the new tree's key entry updated
(i.e. a duplicate is not created). The optional user_data will be passed to
vtable functions. */
-GPRAPI gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value,
- void *user_data);
+GPRAPI gpr_avl gpr_avl_add(gpr_avl avl, void* key, void* value,
+ void* user_data);
/** Return a new tree with key deleted
implicitly unrefs avl to allow easy chaining. The optional user_data will be
passed to vtable functions. */
-GPRAPI gpr_avl gpr_avl_remove(gpr_avl avl, void *key, void *user_data);
+GPRAPI gpr_avl gpr_avl_remove(gpr_avl avl, void* key, void* user_data);
/** Lookup key, and return the associated value.
Does not mutate avl.
Returns NULL if key is not found. The optional user_data will be passed to
vtable functions.*/
-GPRAPI void *gpr_avl_get(gpr_avl avl, void *key, void *user_data);
+GPRAPI void* gpr_avl_get(gpr_avl avl, void* key, void* user_data);
/** Return 1 if avl contains key, 0 otherwise; if it has the key, sets *value to
its value. THe optional user_data will be passed to vtable functions. */
-GPRAPI int gpr_avl_maybe_get(gpr_avl avl, void *key, void **value,
- void *user_data);
+GPRAPI int gpr_avl_maybe_get(gpr_avl avl, void* key, void** value,
+ void* user_data);
/** Return 1 if avl is empty, 0 otherwise */
GPRAPI int gpr_avl_is_empty(gpr_avl avl);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* GRPC_SUPPORT_AVL_H */
diff --git a/include/grpc/support/cmdline.h b/include/grpc/support/cmdline.h
index 9f46491b38..c34a109fbd 100644
--- a/include/grpc/support/cmdline.h
+++ b/include/grpc/support/cmdline.h
@@ -55,31 +55,31 @@ typedef struct gpr_cmdline gpr_cmdline;
/** Construct a command line parser: takes a short description of the tool
doing the parsing */
-GPRAPI gpr_cmdline *gpr_cmdline_create(const char *description);
+GPRAPI gpr_cmdline* gpr_cmdline_create(const char* description);
/** Add an integer parameter, with a name (used on the command line) and some
helpful text (used in the command usage) */
-GPRAPI void gpr_cmdline_add_int(gpr_cmdline *cl, const char *name,
- const char *help, int *value);
+GPRAPI void gpr_cmdline_add_int(gpr_cmdline* cl, const char* name,
+ const char* help, int* value);
/** The same, for a boolean flag */
-GPRAPI void gpr_cmdline_add_flag(gpr_cmdline *cl, const char *name,
- const char *help, int *value);
+GPRAPI void gpr_cmdline_add_flag(gpr_cmdline* cl, const char* name,
+ const char* help, int* value);
/** And for a string */
-GPRAPI void gpr_cmdline_add_string(gpr_cmdline *cl, const char *name,
- const char *help, char **value);
+GPRAPI void gpr_cmdline_add_string(gpr_cmdline* cl, const char* name,
+ const char* help, const char** value);
/** Set a callback for non-named arguments */
GPRAPI void gpr_cmdline_on_extra_arg(
- gpr_cmdline *cl, const char *name, const char *help,
- void (*on_extra_arg)(void *user_data, const char *arg), void *user_data);
+ gpr_cmdline* cl, const char* name, const char* help,
+ void (*on_extra_arg)(void* user_data, const char* arg), void* user_data);
/** Enable surviving failure: default behavior is to exit the process */
-GPRAPI void gpr_cmdline_set_survive_failure(gpr_cmdline *cl);
+GPRAPI void gpr_cmdline_set_survive_failure(gpr_cmdline* cl);
/** Parse the command line; returns 1 on success, on failure either dies
(by default) or returns 0 if gpr_cmdline_set_survive_failure() has been
called */
-GPRAPI int gpr_cmdline_parse(gpr_cmdline *cl, int argc, char **argv);
+GPRAPI int gpr_cmdline_parse(gpr_cmdline* cl, int argc, char** argv);
/** Destroy the parser */
-GPRAPI void gpr_cmdline_destroy(gpr_cmdline *cl);
+GPRAPI void gpr_cmdline_destroy(gpr_cmdline* cl);
/** Get a string describing usage */
-GPRAPI char *gpr_cmdline_usage_string(gpr_cmdline *cl, const char *argv0);
+GPRAPI char* gpr_cmdline_usage_string(gpr_cmdline* cl, const char* argv0);
#ifdef __cplusplus
}
diff --git a/include/grpc/support/histogram.h b/include/grpc/support/histogram.h
deleted file mode 100644
index 8489daa27e..0000000000
--- a/include/grpc/support/histogram.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_SUPPORT_HISTOGRAM_H
-#define GRPC_SUPPORT_HISTOGRAM_H
-
-#include <grpc/support/port_platform.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct gpr_histogram gpr_histogram;
-
-GPRAPI gpr_histogram *gpr_histogram_create(double resolution,
- double max_bucket_start);
-GPRAPI void gpr_histogram_destroy(gpr_histogram *h);
-GPRAPI void gpr_histogram_add(gpr_histogram *h, double x);
-
-/** The following merges the second histogram into the first. It only works
- if they have the same buckets and resolution. Returns 0 on failure, 1
- on success */
-GPRAPI int gpr_histogram_merge(gpr_histogram *dst, const gpr_histogram *src);
-
-GPRAPI double gpr_histogram_percentile(gpr_histogram *histogram,
- double percentile);
-GPRAPI double gpr_histogram_mean(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_stddev(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_variance(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_maximum(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_minimum(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_count(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_sum(gpr_histogram *histogram);
-GPRAPI double gpr_histogram_sum_of_squares(gpr_histogram *histogram);
-
-GPRAPI const uint32_t *gpr_histogram_get_contents(gpr_histogram *histogram,
- size_t *count);
-GPRAPI void gpr_histogram_merge_contents(gpr_histogram *histogram,
- const uint32_t *data,
- size_t data_count, double min_seen,
- double max_seen, double sum,
- double sum_of_squares, double count);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_SUPPORT_HISTOGRAM_H */
diff --git a/include/grpc/support/host_port.h b/include/grpc/support/host_port.h
index 41592dfe26..9805811bfb 100644
--- a/include/grpc/support/host_port.h
+++ b/include/grpc/support/host_port.h
@@ -35,14 +35,14 @@ extern "C" {
destroyed using gpr_free().
In the unlikely event of an error, returns -1 and sets *out to NULL. */
-GPRAPI int gpr_join_host_port(char **out, const char *host, int port);
+GPRAPI int gpr_join_host_port(char** out, const char* host, int port);
/** Given a name in the form "host:port" or "[ho:st]:port", split into hostname
and port number, into newly allocated strings, which must later be
destroyed using gpr_free().
Return 1 on success, 0 on failure. Guarantees *host and *port == NULL on
failure. */
-GPRAPI int gpr_split_host_port(const char *name, char **host, char **port);
+GPRAPI int gpr_split_host_port(const char* name, char** host, char** port);
#ifdef __cplusplus
}
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index a22fb6a6e2..a8371cbd48 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -50,7 +50,7 @@ typedef enum gpr_log_severity {
#define GPR_LOG_VERBOSITY_UNSET -1
/** Returns a string representation of the log severity */
-GPRAPI const char *gpr_log_severity_string(gpr_log_severity severity);
+GPRAPI const char* gpr_log_severity_string(gpr_log_severity severity);
/** Macros to build log contexts at various severity levels */
#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
@@ -59,28 +59,30 @@ GPRAPI const char *gpr_log_severity_string(gpr_log_severity severity);
/** Log a message. It's advised to use GPR_xxx above to generate the context
* for each message */
-GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity,
- const char *format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
+GPRAPI void gpr_log(const char* file, int line, gpr_log_severity severity,
+ const char* format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
-GPRAPI void gpr_log_message(const char *file, int line,
- gpr_log_severity severity, const char *message);
+GPRAPI void gpr_log_message(const char* file, int line,
+ gpr_log_severity severity, const char* message);
/** Set global log verbosity */
GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
-GPRAPI void gpr_log_verbosity_init();
+GPRAPI void gpr_log_verbosity_init(void);
/** Log overrides: applications can use this API to intercept logging calls
and use their own implementations */
-typedef struct {
- const char *file;
+struct gpr_log_func_args {
+ const char* file;
int line;
gpr_log_severity severity;
- const char *message;
-} gpr_log_func_args;
+ const char* message;
+};
-typedef void (*gpr_log_func)(gpr_log_func_args *args);
+typedef struct gpr_log_func_args gpr_log_func_args;
+
+typedef void (*gpr_log_func)(gpr_log_func_args* args);
GPRAPI void gpr_set_log_function(gpr_log_func func);
/** abort() the process if x is zero, having written a line to the log.
diff --git a/include/grpc/support/log_windows.h b/include/grpc/support/log_windows.h
index b530fd50d6..e833f9d9df 100644
--- a/include/grpc/support/log_windows.h
+++ b/include/grpc/support/log_windows.h
@@ -29,7 +29,7 @@ extern "C" {
* formatted error message, corresponding to the error messageid.
* Use in conjunction with GetLastError() et al.
*/
-GPRAPI char *gpr_format_message(int messageid);
+GPRAPI char* gpr_format_message(int messageid);
#ifdef __cplusplus
}
diff --git a/include/grpc/support/string_util.h b/include/grpc/support/string_util.h
index c4fc159d05..2c7460fa15 100644
--- a/include/grpc/support/string_util.h
+++ b/include/grpc/support/string_util.h
@@ -29,7 +29,7 @@ extern "C" {
/** Returns a copy of src that can be passed to gpr_free().
If allocation fails or if src is NULL, returns NULL. */
-GPRAPI char *gpr_strdup(const char *src);
+GPRAPI char* gpr_strdup(const char* src);
/** printf to a newly-allocated string. The set of supported formats may vary
between platforms.
@@ -39,7 +39,7 @@ GPRAPI char *gpr_strdup(const char *src);
On error, returns -1 and sets *strp to NULL. If the format string is bad,
the result is undefined. */
-GPRAPI int gpr_asprintf(char **strp, const char *format, ...)
+GPRAPI int gpr_asprintf(char** strp, const char* format, ...)
GPR_PRINT_FORMAT_CHECK(2, 3);
#ifdef __cplusplus
diff --git a/include/grpc/support/subprocess.h b/include/grpc/support/subprocess.h
index c06e629637..175f7b50eb 100644
--- a/include/grpc/support/subprocess.h
+++ b/include/grpc/support/subprocess.h
@@ -28,14 +28,14 @@ extern "C" {
typedef struct gpr_subprocess gpr_subprocess;
/** .exe on windows, empty on unices */
-GPRAPI const char *gpr_subprocess_binary_extension();
+GPRAPI const char* gpr_subprocess_binary_extension();
-GPRAPI gpr_subprocess *gpr_subprocess_create(int argc, const char **argv);
+GPRAPI gpr_subprocess* gpr_subprocess_create(int argc, const char** argv);
/** if subprocess has not been joined, kill it */
-GPRAPI void gpr_subprocess_destroy(gpr_subprocess *p);
+GPRAPI void gpr_subprocess_destroy(gpr_subprocess* p);
/** returns exit status; can be called at most once */
-GPRAPI int gpr_subprocess_join(gpr_subprocess *p);
-GPRAPI void gpr_subprocess_interrupt(gpr_subprocess *p);
+GPRAPI int gpr_subprocess_join(gpr_subprocess* p);
+GPRAPI void gpr_subprocess_interrupt(gpr_subprocess* p);
#ifdef __cplusplus
} // extern "C"
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index fe8a59a5d6..75192673a6 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -34,26 +34,26 @@ extern "C" {
gpr_mu are uninitialized when first declared. */
/** Initialize *mu. Requires: *mu uninitialized. */
-GPRAPI void gpr_mu_init(gpr_mu *mu);
+GPRAPI void gpr_mu_init(gpr_mu* mu);
/** Cause *mu no longer to be initialized, freeing any memory in use. Requires:
- *mu initialized; no other concurrent operation on *mu. */
-GPRAPI void gpr_mu_destroy(gpr_mu *mu);
+ *mu initialized; no other concurrent operation on *mu. */
+GPRAPI void gpr_mu_destroy(gpr_mu* mu);
/** Wait until no thread has a lock on *mu, cause the calling thread to own an
exclusive lock on *mu, then return. May block indefinitely or crash if the
calling thread has a lock on *mu. Requires: *mu initialized. */
-GPRAPI void gpr_mu_lock(gpr_mu *mu);
+GPRAPI void gpr_mu_lock(gpr_mu* mu);
/** Release an exclusive lock on *mu held by the calling thread. Requires: *mu
initialized; the calling thread holds an exclusive lock on *mu. */
-GPRAPI void gpr_mu_unlock(gpr_mu *mu);
+GPRAPI void gpr_mu_unlock(gpr_mu* mu);
/** Without blocking, attempt to acquire an exclusive lock on *mu for the
calling thread, then return non-zero iff success. Fail, if any thread holds
the lock; succeeds with high probability if no thread holds the lock.
Requires: *mu initialized. */
-GPRAPI int gpr_mu_trylock(gpr_mu *mu);
+GPRAPI int gpr_mu_trylock(gpr_mu* mu);
/** --- Condition variable interface ---
@@ -62,11 +62,11 @@ GPRAPI int gpr_mu_trylock(gpr_mu *mu);
uninitialized when first declared. */
/** Initialize *cv. Requires: *cv uninitialized. */
-GPRAPI void gpr_cv_init(gpr_cv *cv);
+GPRAPI void gpr_cv_init(gpr_cv* cv);
/** Cause *cv no longer to be initialized, freeing any memory in use. Requires:
- *cv initialized; no other concurrent operation on *cv.*/
-GPRAPI void gpr_cv_destroy(gpr_cv *cv);
+ *cv initialized; no other concurrent operation on *cv.*/
+GPRAPI void gpr_cv_destroy(gpr_cv* cv);
/** Atomically release *mu and wait on *cv. When the calling thread is woken
from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
@@ -75,16 +75,16 @@ GPRAPI void gpr_cv_destroy(gpr_cv *cv);
an absolute deadline, or a GPR_TIMESPAN. May return even when not
woken explicitly. Requires: *mu and *cv initialized; the calling thread
holds an exclusive lock on *mu. */
-GPRAPI int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
+GPRAPI int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline);
/** If any threads are waiting on *cv, wake at least one.
Clients may treat this as an optimization of gpr_cv_broadcast()
for use in the case where waking more than one waiter is not useful.
Requires: *cv initialized. */
-GPRAPI void gpr_cv_signal(gpr_cv *cv);
+GPRAPI void gpr_cv_signal(gpr_cv* cv);
/** Wake all threads waiting on *cv. Requires: *cv initialized. */
-GPRAPI void gpr_cv_broadcast(gpr_cv *cv);
+GPRAPI void gpr_cv_broadcast(gpr_cv* cv);
/** --- One-time initialization ---
@@ -97,7 +97,7 @@ GPRAPI void gpr_cv_broadcast(gpr_cv *cv);
If multiple threads call gpr_once() on the same gpr_once instance, one of
them will call (*init_routine)(), and the others will block until that call
finishes.*/
-GPRAPI void gpr_once_init(gpr_once *once, void (*init_routine)(void));
+GPRAPI void gpr_once_init(gpr_once* once, void (*init_routine)(void));
/** --- One-time event notification ---
@@ -107,51 +107,51 @@ GPRAPI void gpr_once_init(gpr_once *once, void (*init_routine)(void));
It requires no destruction. */
/** Initialize *ev. */
-GPRAPI void gpr_event_init(gpr_event *ev);
+GPRAPI void gpr_event_init(gpr_event* ev);
/** Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
Requires: *ev initialized; value != NULL; no prior or concurrent calls to
gpr_event_set(ev, ...) since initialization. */
-GPRAPI void gpr_event_set(gpr_event *ev, void *value);
+GPRAPI void gpr_event_set(gpr_event* ev, void* value);
/** Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
completed. If the result is non-NULL, all operations that occurred prior to
the gpr_event_set(ev, ...) set will be visible after this call returns.
Requires: *ev initialized. This operation is faster than acquiring a mutex
on most platforms. */
-GPRAPI void *gpr_event_get(gpr_event *ev);
+GPRAPI void* gpr_event_get(gpr_event* ev);
/** Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
exceeded, then return gpr_event_get(ev). Requires: *ev initialized. Use
abs_deadline==gpr_inf_future for no deadline. When the event has been
signalled before the call, this operation is faster than acquiring a mutex
on most platforms. */
-GPRAPI void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
+GPRAPI void* gpr_event_wait(gpr_event* ev, gpr_timespec abs_deadline);
/** --- Reference counting ---
These calls act on the type gpr_refcount. It requires no destruction. */
/** Initialize *r to value n. */
-GPRAPI void gpr_ref_init(gpr_refcount *r, int n);
+GPRAPI void gpr_ref_init(gpr_refcount* r, int n);
/** Increment the reference count *r. Requires *r initialized. */
-GPRAPI void gpr_ref(gpr_refcount *r);
+GPRAPI void gpr_ref(gpr_refcount* r);
/** Increment the reference count *r. Requires *r initialized.
Crashes if refcount is zero */
-GPRAPI void gpr_ref_non_zero(gpr_refcount *r);
+GPRAPI void gpr_ref_non_zero(gpr_refcount* r);
/** Increment the reference count *r by n. Requires *r initialized, n > 0. */
-GPRAPI void gpr_refn(gpr_refcount *r, int n);
+GPRAPI void gpr_refn(gpr_refcount* r, int n);
/** Decrement the reference count *r and return non-zero iff it has reached
zero. . Requires *r initialized. */
-GPRAPI int gpr_unref(gpr_refcount *r);
+GPRAPI int gpr_unref(gpr_refcount* r);
/** Return non-zero iff the reference count of *r is one, and thus is owned
by exactly one object. */
-GPRAPI int gpr_ref_is_unique(gpr_refcount *r);
+GPRAPI int gpr_ref_is_unique(gpr_refcount* r);
/** --- Stats counters ---
@@ -162,13 +162,13 @@ GPRAPI int gpr_ref_is_unique(gpr_refcount *r);
synchronize other events. */
/** Initialize *c to the value n. */
-GPRAPI void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
+GPRAPI void gpr_stats_init(gpr_stats_counter* c, intptr_t n);
/** *c += inc. Requires: *c initialized. */
-GPRAPI void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
+GPRAPI void gpr_stats_inc(gpr_stats_counter* c, intptr_t inc);
/** Return *c. Requires: *c initialized. */
-GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter *c);
+GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter* c);
/** ==================Example use of interface===================
A producer-consumer queue of up to N integers,
@@ -274,7 +274,23 @@ GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter *c);
#endif /* 0 */
#ifdef __cplusplus
-}
+} // extern "C"
+
+namespace grpc_core {
+
+class mu_guard {
+ public:
+ mu_guard(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); }
+ ~mu_guard() { gpr_mu_unlock(mu_); }
+
+ mu_guard(const mu_guard&) = delete;
+ mu_guard& operator=(const mu_guard&) = delete;
+
+ private:
+ gpr_mu* const mu_;
+};
+
+} // namespace grpc_core
#endif
#endif /* GRPC_SUPPORT_SYNC_H */
diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h
index 25bd8f1238..e9444e88c9 100644
--- a/include/grpc/support/thd.h
+++ b/include/grpc/support/thd.h
@@ -42,25 +42,28 @@ typedef struct {
/** Create a new thread running (*thd_body)(arg) and place its thread identifier
in *t, and return true. If there are insufficient resources, return false.
+ thd_name is the name of the thread for identification purposes on platforms
+ that support thread naming.
If options==NULL, default options are used.
The thread is immediately runnable, and exits when (*thd_body)() returns. */
-GPRAPI int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg,
- const gpr_thd_options *options);
+GPRAPI int gpr_thd_new(gpr_thd_id* t, const char* thd_name,
+ void (*thd_body)(void* arg), void* arg,
+ const gpr_thd_options* options);
/** Return a gpr_thd_options struct with all fields set to defaults. */
GPRAPI gpr_thd_options gpr_thd_options_default(void);
/** Set the thread to become detached on startup - this is the default. */
-GPRAPI void gpr_thd_options_set_detached(gpr_thd_options *options);
+GPRAPI void gpr_thd_options_set_detached(gpr_thd_options* options);
/** Set the thread to become joinable - mutually exclusive with detached. */
-GPRAPI void gpr_thd_options_set_joinable(gpr_thd_options *options);
+GPRAPI void gpr_thd_options_set_joinable(gpr_thd_options* options);
/** Returns non-zero if the option detached is set. */
-GPRAPI int gpr_thd_options_is_detached(const gpr_thd_options *options);
+GPRAPI int gpr_thd_options_is_detached(const gpr_thd_options* options);
/** Returns non-zero if the option joinable is set. */
-GPRAPI int gpr_thd_options_is_joinable(const gpr_thd_options *options);
+GPRAPI int gpr_thd_options_is_joinable(const gpr_thd_options* options);
/** Returns the identifier of the current thread. */
GPRAPI gpr_thd_id gpr_thd_currentid(void);
diff --git a/include/grpc/support/tls.h b/include/grpc/support/tls.h
index 8519a8350b..4c9e79b6cf 100644
--- a/include/grpc/support/tls.h
+++ b/include/grpc/support/tls.h
@@ -32,6 +32,12 @@
GPR_TLS_DECL(foo);
Thread locals always have static scope.
+ Declaring a thread local class variable 'foo':
+ GPR_TLS_CLASS_DECL(foo);
+
+ Defining the thread local class variable:
+ GPR_TLS_CLASS_DEF(foo);
+
Initializing a thread local (must be done at library initialization
time):
gpr_tls_init(&foo);
diff --git a/include/grpc/support/tls_gcc.h b/include/grpc/support/tls_gcc.h
index e6d8c01447..b44f0f1c8c 100644
--- a/include/grpc/support/tls_gcc.h
+++ b/include/grpc/support/tls_gcc.h
@@ -26,44 +26,6 @@
/** Thread local storage based on gcc compiler primitives.
#include tls.h to use this - and see that file for documentation */
-#ifndef NDEBUG
-
-struct gpr_gcc_thread_local {
- intptr_t value;
- bool *inited;
-};
-
-#define GPR_TLS_DECL(name) \
- static bool name##_inited = false; \
- static __thread struct gpr_gcc_thread_local name = {0, &(name##_inited)}
-
-#define gpr_tls_init(tls) \
- do { \
- GPR_ASSERT(*((tls)->inited) == false); \
- *((tls)->inited) = true; \
- } while (0)
-
-/** It is allowed to call gpr_tls_init after gpr_tls_destroy is called. */
-#define gpr_tls_destroy(tls) \
- do { \
- GPR_ASSERT(*((tls)->inited)); \
- *((tls)->inited) = false; \
- } while (0)
-
-#define gpr_tls_set(tls, new_value) \
- do { \
- GPR_ASSERT(*((tls)->inited)); \
- (tls)->value = (new_value); \
- } while (0)
-
-#define gpr_tls_get(tls) \
- ({ \
- GPR_ASSERT(*((tls)->inited)); \
- (tls)->value; \
- })
-
-#else /* NDEBUG */
-
struct gpr_gcc_thread_local {
intptr_t value;
};
@@ -71,6 +33,11 @@ struct gpr_gcc_thread_local {
#define GPR_TLS_DECL(name) \
static __thread struct gpr_gcc_thread_local name = {0}
+#define GPR_TLS_CLASS_DECL(name) \
+ static __thread struct gpr_gcc_thread_local name
+
+#define GPR_TLS_CLASS_DEF(name) __thread struct gpr_gcc_thread_local name = {0}
+
#define gpr_tls_init(tls) \
do { \
} while (0)
@@ -80,6 +47,4 @@ struct gpr_gcc_thread_local {
#define gpr_tls_set(tls, new_value) (((tls)->value) = (new_value))
#define gpr_tls_get(tls) ((tls)->value)
-#endif /* NDEBUG */
-
#endif /* GRPC_SUPPORT_TLS_GCC_H */
diff --git a/include/grpc/support/tls_msvc.h b/include/grpc/support/tls_msvc.h
index e5f2205fc1..68a411f5d4 100644
--- a/include/grpc/support/tls_msvc.h
+++ b/include/grpc/support/tls_msvc.h
@@ -26,9 +26,18 @@ struct gpr_msvc_thread_local {
intptr_t value;
};
+/** Use GPR_TLS_DECL to declare tls static variables outside a class */
#define GPR_TLS_DECL(name) \
static __declspec(thread) struct gpr_msvc_thread_local name = {0}
+/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
+ * GPR_TLS_CLASS_DEF needs to be called to define this member. */
+#define GPR_TLS_CLASS_DECL(name) \
+ static __declspec(thread) struct gpr_msvc_thread_local name
+
+#define GPR_TLS_CLASS_DEF(name) \
+ __declspec(thread) struct gpr_msvc_thread_local name = {0}
+
#define gpr_tls_init(tls) \
do { \
} while (0)
diff --git a/include/grpc/support/tls_pthread.h b/include/grpc/support/tls_pthread.h
index a68b45569a..249c8b16f8 100644
--- a/include/grpc/support/tls_pthread.h
+++ b/include/grpc/support/tls_pthread.h
@@ -29,15 +29,24 @@ struct gpr_pthread_thread_local {
pthread_key_t key;
};
+/** Use GPR_TLS_DECL to declare tls static variables outside a class */
#define GPR_TLS_DECL(name) static struct gpr_pthread_thread_local name = {0}
+/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
+ * GPR_TLS_CLASS_DEF needs to be called to define this member. */
+#define GPR_TLS_CLASS_DECL(name) static struct gpr_pthread_thread_local name
+
+/** Use GPR_TLS_CLASS_DEF to declare tls static variable members of a class.
+ * GPR_TLS_CLASS_DEF needs to be called to define this member. */
+#define GPR_TLS_CLASS_DEF(name) struct gpr_pthread_thread_local name = {0}
+
#define gpr_tls_init(tls) GPR_ASSERT(0 == pthread_key_create(&(tls)->key, NULL))
#define gpr_tls_destroy(tls) pthread_key_delete((tls)->key)
#define gpr_tls_get(tls) ((intptr_t)pthread_getspecific((tls)->key))
#ifdef __cplusplus
extern "C" {
#endif
-intptr_t gpr_tls_set(struct gpr_pthread_thread_local *tls, intptr_t value);
+intptr_t gpr_tls_set(struct gpr_pthread_thread_local* tls, intptr_t value);
#ifdef __cplusplus
}
#endif