diff --git a/README.md b/README.md index f894def470605d3234a4b8ef7a1831fa94c443d3..033e09b91b7e8ee9bbcfc336688479d68840c936 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ [gRPC - An RPC library and framework](http://github.com/grpc/grpc) =================================== +[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + Copyright 2015-2016 Google Inc. #Documentation diff --git a/binding.gyp b/binding.gyp index 3659bfcf13e0f604d609d33313908d86b054d579..82e36c421d5edd61b9c1d20dce7fef37ae663b78 100644 --- a/binding.gyp +++ b/binding.gyp @@ -55,7 +55,8 @@ 'UNICODE', '_UNICODE', 'NOMINMAX', - 'OPENSSL_NO_ASM' + 'OPENSSL_NO_ASM', + 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], "msvs_settings": { 'VCCLCompilerTool': { @@ -78,7 +79,8 @@ # supports ALPN. The target is "[major].[minor].[patch]". We split by # periods and take the first field to get the major version. 'defines': [ - 'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)' + 'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)', + 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], 'include_dirs': [ '<(node_root_dir)/deps/openssl/openssl/include', diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h index aff9c291c26d397e9b14c62186f7ca5b4eb43bf9..e9ccb5150396929bf7fa427fada3dab1f03c2e53 100644 --- a/include/grpc++/create_channel.h +++ b/include/grpc++/create_channel.h @@ -36,6 +36,7 @@ #include <memory> +#include <grpc++/channel.h> #include <grpc++/security/credentials.h> #include <grpc++/support/channel_arguments.h> #include <grpc++/support/config.h> diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h index 33d25e837c677f70a1d4b22365ec3e4aa36066c0..9ae48bd23d6a4d23510f2b01e0dd0090a3df88ab 100644 --- a/include/grpc++/impl/codegen/sync_stream.h +++ b/include/grpc++/impl/codegen/sync_stream.h @@ -193,6 +193,15 @@ class ClientWriter : public ClientWriterInterface<W> { cq_.Pluck(&ops); } + void WaitForInitialMetadata() { + GPR_ASSERT(!context_->initial_metadata_received_); + + CallOpSet<CallOpRecvInitialMetadata> ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); // status ignored + } + using WriterInterface<W>::Write; bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE { CallOpSet<CallOpSendMessage> ops; @@ -213,6 +222,9 @@ class ClientWriter : public ClientWriterInterface<W> { /// Read the final response and wait for the final status. Status Finish() GRPC_OVERRIDE { Status status; + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } finish_ops_.ClientRecvStatus(context_, &status); call_.PerformOps(&finish_ops_); GPR_ASSERT(cq_.Pluck(&finish_ops_)); @@ -221,7 +233,8 @@ class ClientWriter : public ClientWriterInterface<W> { private: ClientContext* context_; - CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_; + CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage, + CallOpClientRecvStatus> finish_ops_; CompletionQueue cq_; Call call_; }; @@ -292,7 +305,10 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> { } Status Finish() GRPC_OVERRIDE { - CallOpSet<CallOpClientRecvStatus> ops; + CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } Status status; ops.ClientRecvStatus(context_, &status); call_.PerformOps(&ops); diff --git a/include/grpc/census.h b/include/grpc/census.h index 6313b196f224238f0fcbb9283116950f40f79d49..dfa3bd7e0df70d530f7607a3060865ef46806b42 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -59,15 +59,15 @@ enum census_features { * census_initialize() will return a non-zero value. It is an error to call * census_initialize() more than once (without an intervening * census_shutdown()). */ -CENSUS_API int census_initialize(int features); -CENSUS_API void census_shutdown(void); +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). */ -CENSUS_API int census_supported(void); +CENSUSAPI int census_supported(void); /** Return the census features currently enabled. */ -CENSUS_API int census_enabled(void); +CENSUSAPI int census_enabled(void); /** A Census Context is a handle used by Census to represent the current tracing @@ -145,16 +145,16 @@ typedef struct { tags used in its creation. @return A new, valid census_context. */ -CENSUS_API census_context *census_context_create( +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. */ -CENSUS_API void census_context_destroy(census_context *context); +CENSUSAPI void census_context_destroy(census_context *context); /* Get a pointer to the original status from the context creation. */ -CENSUS_API const census_context_status *census_context_get_status( +CENSUSAPI const census_context_status *census_context_get_status( const census_context *context); /* Structure used for iterating over the tegs in a context. API clients should @@ -168,18 +168,18 @@ typedef struct { } census_context_iterator; /* Initialize a census_tag_iterator. Must be called before first use. */ -CENSUS_API void census_context_initialize_iterator( +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. */ -CENSUS_API int census_context_next_tag(census_context_iterator *iterator, - census_tag *tag); +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. */ -CENSUS_API int census_context_get_tag(const census_context *context, - const char *key, census_tag *tag); +CENSUSAPI int census_context_get_tag(const census_context *context, + const char *key, census_tag *tag); /* Tag set encode/decode functionality. These functionas are intended for use by RPC systems only, for purposes of transmitting/receiving contexts. @@ -201,17 +201,16 @@ CENSUS_API int census_context_get_tag(const census_context *context, [buffer, buffer + *print_buf_size) and binary tags into [returned-ptr, returned-ptr + *bin_buf_size) (and the returned pointer should be buffer + *print_buf_size) */ -CENSUS_API char *census_context_encode(const census_context *context, - char *buffer, size_t buf_size, - size_t *print_buf_size, - size_t *bin_buf_size); +CENSUSAPI char *census_context_encode(const census_context *context, + char *buffer, size_t buf_size, + size_t *print_buf_size, + size_t *bin_buf_size); /* Decode context buffers encoded with census_context_encode(). Returns NULL if there is an error in parsing either buffer. */ -CENSUS_API census_context *census_context_decode(const char *buffer, - size_t size, - const char *bin_buffer, - size_t bin_size); +CENSUSAPI census_context *census_context_decode(const char *buffer, size_t size, + const char *bin_buffer, + size_t bin_size); /* Distributed traces can have a number of options. */ enum census_trace_mask_values { @@ -221,10 +220,10 @@ enum census_trace_mask_values { /** Get the current trace mask associated with this context. The value returned will be the logical or of census_trace_mask_values values. */ -CENSUS_API int census_trace_mask(const census_context *context); +CENSUSAPI int census_trace_mask(const census_context *context); /** Set the trace mask associated with a context. */ -CENSUS_API void census_set_trace_mask(int trace_mask); +CENSUSAPI void census_set_trace_mask(int trace_mask); /* The concept of "operation" is a fundamental concept for Census. In an RPC system, and operation typcially represents a single RPC, or a significant @@ -272,7 +271,7 @@ typedef struct { @return A timestamp representing the operation start time. */ -CENSUS_API census_timestamp census_start_rpc_op_timestamp(void); +CENSUSAPI census_timestamp census_start_rpc_op_timestamp(void); /** Represent functions to map RPC name ID to service/method names. Census @@ -324,7 +323,7 @@ typedef struct { @return A new census context. */ -CENSUS_API census_context *census_start_client_rpc_op( +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); @@ -332,8 +331,8 @@ CENSUS_API census_context *census_start_client_rpc_op( /** Add peer information to a context representing a client RPC operation. */ -CENSUS_API void census_set_rpc_client_peer(census_context *context, - const char *peer); +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 @@ -353,7 +352,7 @@ CENSUS_API void census_set_rpc_client_peer(census_context *context, @return A new census context. */ -CENSUS_API census_context *census_start_server_rpc_op( +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); @@ -383,9 +382,9 @@ CENSUS_API census_context *census_start_server_rpc_op( @return A new census context. */ -CENSUS_API census_context *census_start_op(census_context *context, - const char *family, const char *name, - int trace_mask); +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 @@ -396,7 +395,7 @@ CENSUS_API census_context *census_start_op(census_context *context, @param status status associated with the operation. Not interpreted by census. */ -CENSUS_API void census_end_op(census_context *context, int status); +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) @@ -408,8 +407,8 @@ CENSUS_API void census_end_op(census_context *context, int status); @param buffer Pointer to buffer to use @param n Number of bytes in buffer */ -CENSUS_API void census_trace_print(census_context *context, uint32_t type, - const char *buffer, size_t n); +CENSUSAPI void census_trace_print(census_context *context, uint32_t type, + const char *buffer, size_t n); /** Trace record. */ typedef struct { @@ -430,7 +429,7 @@ typedef struct { while scanning is ongoing. @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing) */ -CENSUS_API int census_trace_scan_start(int consume); +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 @@ -441,10 +440,10 @@ CENSUS_API int census_trace_scan_start(int consume); census_trace_scan_start()), 0 if there is no more trace data (and trace_record will not be modified) or 1 otherwise. */ -CENSUS_API int census_get_trace_record(census_trace_record *trace_record); +CENSUSAPI int census_get_trace_record(census_trace_record *trace_record); /** End a scan previously started by census_trace_scan_start() */ -CENSUS_API void census_trace_scan_end(); +CENSUSAPI void census_trace_scan_end(); /* Core stats collection API's. The following concepts are used: * Aggregation: A collection of values. Census supports the following @@ -475,8 +474,8 @@ typedef struct { } census_value; /* Record new usage values against the given context. */ -CENSUS_API void census_record_values(census_context *context, - census_value *values, size_t nvalues); +CENSUSAPI void census_record_values(census_context *context, + census_value *values, size_t nvalues); /** Type representing a particular aggregation */ typedef struct census_aggregation_ops census_aggregation_ops; @@ -508,24 +507,24 @@ typedef struct census_view census_view; /* TODO(aveitch): consider if context is the right argument type to pass in tags. */ -CENSUS_API census_view *census_view_create( +CENSUSAPI census_view *census_view_create( uint32_t metric_id, const census_context *tags, const census_aggregation *aggregations, size_t naggregations); /** Destroy a previously created view. */ -CENSUS_API void census_view_delete(census_view *view); +CENSUSAPI void census_view_delete(census_view *view); /** Metric ID associated with a view */ -CENSUS_API size_t census_view_metric(const census_view *view); +CENSUSAPI size_t census_view_metric(const census_view *view); /** Number of aggregations associated with view. */ -CENSUS_API size_t census_view_naggregations(const census_view *view); +CENSUSAPI size_t census_view_naggregations(const census_view *view); /** Get tags associated with view. */ -CENSUS_API const census_context *census_view_tags(const census_view *view); +CENSUSAPI const census_context *census_view_tags(const census_view *view); /** Get aggregation descriptors associated with a view. */ -CENSUS_API const census_aggregation *census_view_aggregrations( +CENSUSAPI const census_aggregation *census_view_aggregrations( const census_view *view); /** Holds all the aggregation data for a particular view instantiation. Forms @@ -545,11 +544,10 @@ typedef struct { @param view View from which to get data. @return Full set of data for all aggregations for the view. */ -CENSUS_API const census_view_data *census_view_get_data( - const census_view *view); +CENSUSAPI const census_view_data *census_view_get_data(const census_view *view); /** Reset all view data to zero for the specified view */ -CENSUS_API void census_view_reset(census_view *view); +CENSUSAPI void census_view_reset(census_view *view); #ifdef __cplusplus } diff --git a/include/grpc/compression.h b/include/grpc/compression.h index a2b65b0e8af1ef0f7ea408b8ed1f220b05ec44c4..acc168a6eefcd0695e29657fd5b24c8c492ecb46 100644 --- a/include/grpc/compression.h +++ b/include/grpc/compression.h @@ -46,33 +46,33 @@ extern "C" { /** Parses the first \a name_length bytes of \a name as a * grpc_compression_algorithm instance, updating \a algorithm. Returns 1 upon * success, 0 otherwise. */ -GRPC_API int grpc_compression_algorithm_parse( +GRPCAPI int grpc_compression_algorithm_parse( const char *name, size_t name_length, grpc_compression_algorithm *algorithm); /** Updates \a name with the encoding name corresponding to a valid \a * algorithm. Returns 1 upon success, 0 otherwise. */ -GRPC_API int grpc_compression_algorithm_name( +GRPCAPI int grpc_compression_algorithm_name( grpc_compression_algorithm algorithm, char **name); /** Returns the compression algorithm corresponding to \a level. * * It abort()s for unknown levels . */ -GRPC_API grpc_compression_algorithm +GRPCAPI grpc_compression_algorithm grpc_compression_algorithm_for_level(grpc_compression_level level); -GRPC_API 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. */ -GRPC_API void grpc_compression_options_enable_algorithm( +GRPCAPI void grpc_compression_options_enable_algorithm( grpc_compression_options *opts, grpc_compression_algorithm algorithm); /** Mark \a algorithm as disabled in \a opts. */ -GRPC_API void grpc_compression_options_disable_algorithm( +GRPCAPI void grpc_compression_options_disable_algorithm( grpc_compression_options *opts, grpc_compression_algorithm algorithm); /** Returns true if \a algorithm is marked as enabled in \a opts. */ -GRPC_API int grpc_compression_options_is_algorithm_enabled( +GRPCAPI int grpc_compression_options_is_algorithm_enabled( const grpc_compression_options *opts, grpc_compression_algorithm algorithm); #ifdef __cplusplus diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index ac4c536be315d9fa778848b56d26950fcab048ab..5113645daf95396341aa306b10b6fa187536880f 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -55,11 +55,11 @@ extern "C" { * functionality lives in grpc_security.h. */ -GRPC_API void grpc_metadata_array_init(grpc_metadata_array *array); -GRPC_API 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); -GRPC_API void grpc_call_details_init(grpc_call_details *details); -GRPC_API 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. @@ -69,7 +69,7 @@ GRPC_API void grpc_call_details_destroy(grpc_call_details *details); (and hence so will \a init and \a destroy). It is safe to pass NULL to either argument. Plugins are destroyed in the reverse order they were initialized. */ -GRPC_API void grpc_register_plugin(void (*init)(void), void (*destroy)(void)); +GRPCAPI void grpc_register_plugin(void (*init)(void), void (*destroy)(void)); /** Initialize the grpc library. @@ -77,7 +77,7 @@ GRPC_API void grpc_register_plugin(void (*init)(void), void (*destroy)(void)); (To avoid overhead, little checking is done, and some things may work. We do not warrant that they will continue to do so in future revisions of this library). */ -GRPC_API void grpc_init(void); +GRPCAPI void grpc_init(void); /** Shut down the grpc library. @@ -85,13 +85,13 @@ GRPC_API void grpc_init(void); executing within the grpc library. Prior to calling, all application owned grpc objects must have been destroyed. */ -GRPC_API void grpc_shutdown(void); +GRPCAPI void grpc_shutdown(void); /** Return a string representing the current version of grpc */ -GRPC_API const char *grpc_version_string(void); +GRPCAPI const char *grpc_version_string(void); /** Create a completion queue */ -GRPC_API grpc_completion_queue *grpc_completion_queue_create(void *reserved); +GRPCAPI grpc_completion_queue *grpc_completion_queue_create(void *reserved); /** Blocks until an event is available, the completion queue is being shut down, or deadline is reached. @@ -101,9 +101,9 @@ GRPC_API grpc_completion_queue *grpc_completion_queue_create(void *reserved); Callers must not call grpc_completion_queue_next and grpc_completion_queue_pluck simultaneously on the same completion queue. */ -GRPC_API grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, - gpr_timespec deadline, - void *reserved); +GRPCAPI grpc_event grpc_completion_queue_next(grpc_completion_queue *cq, + gpr_timespec deadline, + void *reserved); /** Blocks until an event with tag 'tag' is available, the completion queue is being shutdown or deadline is reached. @@ -116,9 +116,9 @@ GRPC_API 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. */ -GRPC_API 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 */ @@ -131,11 +131,11 @@ grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag, After calling this function applications should ensure that no NEW work is added to be published on this completion queue. */ -GRPC_API 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 */ -GRPC_API void grpc_completion_queue_destroy(grpc_completion_queue *cq); +GRPCAPI void grpc_completion_queue_destroy(grpc_completion_queue *cq); /** Create a completion queue alarm instance associated to \a cq. * @@ -143,18 +143,18 @@ GRPC_API void grpc_completion_queue_destroy(grpc_completion_queue *cq); * 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). */ -GRPC_API grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, - gpr_timespec deadline, void *tag); +GRPCAPI grpc_alarm *grpc_alarm_create(grpc_completion_queue *cq, + gpr_timespec deadline, void *tag); /** Cancel a completion queue alarm. Calling this function over an alarm that * has already fired has no effect. */ -GRPC_API void grpc_alarm_cancel(grpc_alarm *alarm); +GRPCAPI void grpc_alarm_cancel(grpc_alarm *alarm); /** Destroy the given completion queue alarm, cancelling it in the process. */ -GRPC_API void grpc_alarm_destroy(grpc_alarm *alarm); +GRPCAPI void grpc_alarm_destroy(grpc_alarm *alarm); /** Check the connectivity state of a channel. */ -GRPC_API grpc_connectivity_state +GRPCAPI grpc_connectivity_state grpc_channel_check_connectivity_state(grpc_channel *channel, int try_to_connect); @@ -163,7 +163,7 @@ grpc_channel_check_connectivity_state(grpc_channel *channel, tag will be enqueued on cq with success=1. If deadline expires BEFORE the state is changed, tag will be enqueued on cq with success=0. */ -GRPC_API void grpc_channel_watch_connectivity_state( +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); @@ -173,24 +173,23 @@ GRPC_API void grpc_channel_watch_connectivity_state( If parent_call is non-NULL, it must be a server-side call. It will be used to propagate properties from the server call to this new client call. */ -GRPC_API grpc_call *grpc_channel_create_call( +GRPCAPI grpc_call *grpc_channel_create_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, const char *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. */ -GRPC_API 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. */ -GRPC_API 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 */ -GRPC_API grpc_call *grpc_channel_create_registered_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); @@ -206,9 +205,9 @@ GRPC_API grpc_call *grpc_channel_create_registered_call( needs to be synchronized. As an optimization, you may synchronize batches containing just send operations independently from batches containing just receive operations. */ -GRPC_API 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 @@ -218,36 +217,36 @@ GRPC_API 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. */ -GRPC_API 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(). */ -GRPC_API 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. */ -GRPC_API 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. */ -GRPC_API char *grpc_channel_get_target(grpc_channel *channel); +GRPCAPI char *grpc_channel_get_target(grpc_channel *channel); /** 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. */ -GRPC_API grpc_channel *grpc_insecure_channel_create( +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. */ -GRPC_API grpc_channel *grpc_lame_client_channel_create( +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 */ -GRPC_API 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 @@ -260,7 +259,7 @@ GRPC_API 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_destroy is called.*/ -GRPC_API 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. @@ -268,13 +267,13 @@ GRPC_API grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved); and description passed in. Importantly, this function does not send status nor description to the remote endpoint. */ -GRPC_API grpc_call_error +GRPCAPI grpc_call_error grpc_call_cancel_with_status(grpc_call *call, grpc_status_code status, const char *description, void *reserved); /** Destroy a call. THREAD SAFETY: grpc_call_destroy is thread-compatible */ -GRPC_API void grpc_call_destroy(grpc_call *call); +GRPCAPI void grpc_call_destroy(grpc_call *call); /** Request notification of a new call. Once a call is received, a notification tagged with \a tag_new is added to @@ -284,7 +283,7 @@ GRPC_API void grpc_call_destroy(grpc_call *call); to \a cq_bound_to_call. Note that \a cq_for_notification must have been registered to the server via \a grpc_server_register_completion_queue. */ -GRPC_API grpc_call_error +GRPCAPI grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, @@ -299,14 +298,13 @@ grpc_server_request_call(grpc_server *server, grpc_call **call, registered_method (as returned by this function). Must be called before grpc_server_start. Returns NULL on failure. */ -GRPC_API 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); /** Request notification of a new pre-registered call. 'cq_for_notification' must have been registered to the server via grpc_server_register_completion_queue. */ -GRPC_API grpc_call_error grpc_server_request_registered_call( +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, @@ -317,25 +315,25 @@ GRPC_API grpc_call_error grpc_server_request_registered_call( 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. */ -GRPC_API 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. */ -GRPC_API 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 */ -GRPC_API 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 */ -GRPC_API 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. @@ -344,19 +342,19 @@ GRPC_API 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. */ -GRPC_API 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. */ -GRPC_API 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). */ -GRPC_API void grpc_server_destroy(grpc_server *server); +GRPCAPI void grpc_server_destroy(grpc_server *server); /** Enable or disable a tracer. @@ -366,18 +364,17 @@ GRPC_API 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. */ -GRPC_API 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) */ -GRPC_API int grpc_header_key_is_legal(const char *key, size_t length); +GRPCAPI int grpc_header_key_is_legal(const char *key, size_t length); /** Check whether a non-binary metadata value is legal (will be accepted by core) */ -GRPC_API int grpc_header_nonbin_value_is_legal(const char *value, - size_t length); +GRPCAPI int grpc_header_nonbin_value_is_legal(const char *value, size_t length); /** Check whether a metadata key corresponds to a binary value */ -GRPC_API int grpc_is_binary_header(const char *key, size_t length); +GRPCAPI int grpc_is_binary_header(const char *key, size_t length); #ifdef __cplusplus } diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 28881c3a11ab9773f1d73f52aa056d16284d9acb..3de5cae8be22977294d18c4d673ca7cce6c0a12f 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -65,39 +65,39 @@ typedef struct grpc_auth_property { } grpc_auth_property; /* Returns NULL when the iterator is at the end. */ -GRPC_API const grpc_auth_property *grpc_auth_property_iterator_next( +GRPCAPI const grpc_auth_property *grpc_auth_property_iterator_next( grpc_auth_property_iterator *it); /* Iterates over the auth context. */ -GRPC_API grpc_auth_property_iterator +GRPCAPI grpc_auth_property_iterator 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. */ -GRPC_API grpc_auth_property_iterator +GRPCAPI grpc_auth_property_iterator 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. */ -GRPC_API grpc_auth_property_iterator +GRPCAPI grpc_auth_property_iterator grpc_auth_context_find_properties_by_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. */ -GRPC_API const char *grpc_auth_context_peer_identity_property_name( +GRPCAPI const char *grpc_auth_context_peer_identity_property_name( const grpc_auth_context *ctx); /* Returns 1 if the peer is authenticated, 0 otherwise. */ -GRPC_API int grpc_auth_context_peer_is_authenticated( +GRPCAPI int grpc_auth_context_peer_is_authenticated( const grpc_auth_context *ctx); /* Gets the auth context from the call. Caller needs to call grpc_auth_context_release on the returned context. */ -GRPC_API 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. */ -GRPC_API 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 @@ -105,19 +105,18 @@ GRPC_API void grpc_auth_context_release(grpc_auth_context *context); -- */ /* Add a property. */ -GRPC_API void grpc_auth_context_add_property(grpc_auth_context *ctx, - const char *name, - const char *value, - size_t value_length); +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. */ -GRPC_API 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). */ -GRPC_API int grpc_auth_context_set_peer_identity_property_name( +GRPCAPI int grpc_auth_context_set_peer_identity_property_name( grpc_auth_context *ctx, const char *name); /* --- grpc_channel_credentials object. --- @@ -129,7 +128,7 @@ typedef struct grpc_channel_credentials grpc_channel_credentials; /* Releases a channel credentials object. The creator of the credentials object is responsible for its release. */ -GRPC_API void grpc_channel_credentials_release(grpc_channel_credentials *creds); +GRPCAPI void grpc_channel_credentials_release(grpc_channel_credentials *creds); /* Environment variable that points to the google default application credentials json key or refresh token. Used in the @@ -139,7 +138,7 @@ GRPC_API 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. */ -GRPC_API grpc_channel_credentials *grpc_google_default_credentials_create(void); +GRPCAPI grpc_channel_credentials *grpc_google_default_credentials_create(void); /* Environment variable that points to the default SSL roots file. This file must be a PEM encoded file with all the roots such as the one that can be @@ -192,7 +191,7 @@ 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. */ -GRPC_API grpc_channel_credentials *grpc_ssl_credentials_create( +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); @@ -206,32 +205,32 @@ typedef struct grpc_call_credentials grpc_call_credentials; /* Releases a call credentials object. The creator of the credentials object is responsible for its release. */ -GRPC_API 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. */ -GRPC_API grpc_channel_credentials *grpc_composite_channel_credentials_create( +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. */ -GRPC_API grpc_call_credentials *grpc_composite_call_credentials_create( +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. */ -GRPC_API grpc_call_credentials *grpc_google_compute_engine_credentials_create( +GRPCAPI grpc_call_credentials *grpc_google_compute_engine_credentials_create( void *reserved); -GRPC_API gpr_timespec grpc_max_auth_token_lifetime(); +GRPCAPI gpr_timespec grpc_max_auth_token_lifetime(); /* 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. */ -GRPC_API grpc_call_credentials * +GRPCAPI grpc_call_credentials * grpc_service_account_jwt_access_credentials_create(const char *json_key, gpr_timespec token_lifetime, void *reserved); @@ -242,16 +241,16 @@ 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. */ -GRPC_API grpc_call_credentials *grpc_google_refresh_token_credentials_create( +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. */ -GRPC_API grpc_call_credentials *grpc_access_token_credentials_create( +GRPCAPI grpc_call_credentials *grpc_access_token_credentials_create( const char *access_token, void *reserved); /* Creates an IAM credentials object for connecting to Google. */ -GRPC_API grpc_call_credentials *grpc_google_iam_credentials_create( +GRPCAPI grpc_call_credentials *grpc_google_iam_credentials_create( const char *authorization_token, const char *authority_selector, void *reserved); @@ -313,13 +312,13 @@ typedef struct { } grpc_metadata_credentials_plugin; /* Creates a credentials object from a plugin. */ -GRPC_API grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( +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. */ -GRPC_API grpc_channel *grpc_secure_channel_create( +GRPCAPI grpc_channel *grpc_secure_channel_create( grpc_channel_credentials *creds, const char *target, const grpc_channel_args *args, void *reserved); @@ -332,7 +331,7 @@ 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. */ -GRPC_API void grpc_server_credentials_release(grpc_server_credentials *creds); +GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds); /* Creates an SSL server_credentials object. - pem_roots_cert is the NULL-terminated string containing the PEM encoding of @@ -345,7 +344,7 @@ GRPC_API 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. */ -GRPC_API grpc_server_credentials *grpc_ssl_server_credentials_create( +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); @@ -354,15 +353,15 @@ GRPC_API grpc_server_credentials *grpc_ssl_server_credentials_create( /* Add a HTTP2 over an encrypted link over tcp listener. Returns bound port number on success, 0 on failure. REQUIRES: server not started */ -GRPC_API 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. */ -GRPC_API grpc_call_error +GRPCAPI grpc_call_error grpc_call_set_credentials(grpc_call *call, grpc_call_credentials *creds); /* --- Auth Metadata Processing --- */ @@ -394,7 +393,7 @@ typedef struct { void *state; } grpc_auth_metadata_processor; -GRPC_API void grpc_server_credentials_set_auth_metadata_processor( +GRPCAPI void grpc_server_credentials_set_auth_metadata_processor( grpc_server_credentials *creds, grpc_auth_metadata_processor processor); #ifdef __cplusplus diff --git a/include/grpc/impl/codegen/alloc.h b/include/grpc/impl/codegen/alloc.h index dc7ba78846ce24f7800a203586cd785bd285388b..235135443306c331720305d42e93f4facb42a8f3 100644 --- a/include/grpc/impl/codegen/alloc.h +++ b/include/grpc/impl/codegen/alloc.h @@ -49,23 +49,23 @@ typedef struct gpr_allocation_functions { } gpr_allocation_functions; /* malloc, never returns NULL */ -GPR_API void *gpr_malloc(size_t size); +GPRAPI void *gpr_malloc(size_t size); /* free */ -GPR_API void gpr_free(void *ptr); +GPRAPI void gpr_free(void *ptr); /* realloc, never returns NULL */ -GPR_API void *gpr_realloc(void *p, size_t size); +GPRAPI void *gpr_realloc(void *p, size_t size); /* aligned malloc, never returns NULL, will align to 1 << alignment_log */ -GPR_API void *gpr_malloc_aligned(size_t size, size_t alignment_log); +GPRAPI void *gpr_malloc_aligned(size_t size, size_t alignment_log); /* free memory allocated by gpr_malloc_aligned */ -GPR_API 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 * guarantees are made about the default functions (eg, malloc) being called. */ -GPR_API void gpr_set_allocation_functions(gpr_allocation_functions functions); +GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions); /** Return the family of allocation functions currently in effect. */ -GPR_API gpr_allocation_functions gpr_get_allocation_functions(); +GPRAPI gpr_allocation_functions gpr_get_allocation_functions(); #ifdef __cplusplus } diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h index 5049461f73fd692141e883da6093d3f605a544bb..9e96d4bdae42af8dcf0a8c6f8af381dea96acff5 100644 --- a/include/grpc/impl/codegen/byte_buffer.h +++ b/include/grpc/impl/codegen/byte_buffer.h @@ -65,8 +65,8 @@ typedef struct grpc_byte_buffer grpc_byte_buffer; * * Increases the reference count for all \a slices processed. The user is * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/ -GRPC_API grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, - size_t nslices); +GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, + size_t nslices); /** Returns a *compressed* RAW byte buffer instance over the given slices (up to * \a nslices). The \a compression argument defines the compression algorithm @@ -74,44 +74,44 @@ GRPC_API grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_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.*/ -GRPC_API grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( +GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( gpr_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. */ -GRPC_API 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. */ -GRPC_API 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. */ -GRPC_API 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; typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader; /** Initialize \a reader to read over \a buffer */ -GRPC_API void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, - grpc_byte_buffer *buffer); +GRPCAPI void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, + grpc_byte_buffer *buffer); /** Cleanup and destroy \a reader */ -GRPC_API 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 * gpr_slice_unref on the result. */ -GRPC_API int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, - gpr_slice *slice); +GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, + gpr_slice *slice); /** Merge all data from \a reader into single slice */ -GRPC_API gpr_slice +GRPCAPI gpr_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader); /** Returns a RAW byte buffer instance from the output of \a reader. */ -GRPC_API grpc_byte_buffer *grpc_raw_byte_buffer_from_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/log.h b/include/grpc/impl/codegen/log.h index 5df91c65098574d702bff4d9025401906ec5c366..d6e18e9ca5f494abfc45cb37b5409fe1147da5f7 100644 --- a/include/grpc/impl/codegen/log.h +++ b/include/grpc/impl/codegen/log.h @@ -71,11 +71,11 @@ 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 */ -GPR_API void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *format, ...); +GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, + const char *format, ...); -GPR_API 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); /* Log overrides: applications can use this API to intercept logging calls and use their own implementations */ @@ -88,7 +88,7 @@ typedef struct { } gpr_log_func_args; typedef void (*gpr_log_func)(gpr_log_func_args *args); -GPR_API void gpr_set_log_function(gpr_log_func func); +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/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index d265e9b3922dfbb2933779bc5547ff3a40491330..92569043fcca618bb15493ad082e91af6850524f 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -34,6 +34,14 @@ #ifndef GRPC_IMPL_CODEGEN_PORT_PLATFORM_H #define GRPC_IMPL_CODEGEN_PORT_PLATFORM_H +/* + * Define GPR_BACKWARDS_COMPATIBILITY_MODE to try harder to be ABI + * compatible with older platforms (currently only on Linux) + * Causes: + * - some libc calls to be gotten via dlsym + * - some syscalls to be made directly + */ + /* Get windows.h included everywhere (we need it) */ #if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32) #ifndef WIN32_LEAN_AND_MEAN @@ -347,16 +355,16 @@ typedef unsigned __int64 uint64_t; } while (0) #endif /* GPR_FORBID_UNREACHABLE_CODE */ -#ifndef GPR_API -#define GPR_API +#ifndef GPRAPI +#define GPRAPI #endif -#ifndef GRPC_API -#define GRPC_API GPR_API +#ifndef GRPCAPI +#define GRPCAPI GPRAPI #endif -#ifndef CENSUS_API -#define CENSUS_API GRPC_API +#ifndef CENSUSAPI +#define CENSUSAPI GRPCAPI #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 d60a40ca352bfee8eef954e96815160efbaeba8b..a62fdd087bc96b937c8a75b3e14b05a235fad4b4 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -105,7 +105,7 @@ typedef struct gpr_slice { /* Increment the refcount of s. Requires slice is initialized. Returns s. */ -GPR_API gpr_slice gpr_slice_ref(gpr_slice s); +GPRAPI gpr_slice gpr_slice_ref(gpr_slice s); /* Decrement the ref count of s. If the ref count of s reaches zero, all slices sharing the ref count are destroyed, and considered no longer @@ -113,22 +113,22 @@ GPR_API gpr_slice gpr_slice_ref(gpr_slice s); len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is ultimately derived from a call to gpr_slice_new_with_len(start, len, dest) where dest!=NULL , then (*dest)(start, len). Requires s initialized. */ -GPR_API void gpr_slice_unref(gpr_slice s); +GPRAPI void gpr_slice_unref(gpr_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. */ -GPR_API gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); +GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); /* Equivalent to gpr_slice_new, but with a two argument destroy function that also takes the slice length. */ -GPR_API gpr_slice +GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, void (*destroy)(void *, size_t)); /* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc() call. Aborts if malloc() fails. */ -GPR_API gpr_slice gpr_slice_malloc(size_t length); +GPRAPI gpr_slice gpr_slice_malloc(size_t length); /* Create a slice by copying a string. Does not preserve null terminators. @@ -136,44 +136,44 @@ GPR_API gpr_slice gpr_slice_malloc(size_t length); size_t len = strlen(source); gpr_slice slice = gpr_slice_malloc(len); memcpy(slice->data, source, len); */ -GPR_API gpr_slice gpr_slice_from_copied_string(const char *source); +GPRAPI gpr_slice gpr_slice_from_copied_string(const char *source); /* Create a slice by copying a buffer. Equivalent to: gpr_slice slice = gpr_slice_malloc(len); memcpy(slice->data, source, len); */ -GPR_API gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len); +GPRAPI gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len); /* Create a slice pointing to constant memory */ -GPR_API gpr_slice gpr_slice_from_static_string(const char *source); +GPRAPI gpr_slice gpr_slice_from_static_string(const char *source); /* Return a result slice derived from s, which shares a ref count with s, where result.data==s.data+begin, and result.length==end-begin. The ref count of s is increased by one. Requires s initialized, begin <= end, begin <= s.length, and end <= source->length. */ -GPR_API gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end); +GPRAPI gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end); /* The same as gpr_slice_sub, but without altering the ref count */ -GPR_API gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end); +GPRAPI gpr_slice gpr_slice_sub_no_ref(gpr_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 */ -GPR_API gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split); +GPRAPI gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split); /* 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 */ -GPR_API gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split); +GPRAPI gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split); -GPR_API gpr_slice gpr_empty_slice(void); +GPRAPI gpr_slice gpr_empty_slice(void); /* Returns <0 if a < b, ==0 if a == b, >0 if a > b The order is arbitrary, and is not guaranteed to be stable across different versions of the API. */ -GPR_API int gpr_slice_cmp(gpr_slice a, gpr_slice b); -GPR_API int gpr_slice_str_cmp(gpr_slice a, const char *b); +GPRAPI int gpr_slice_cmp(gpr_slice a, gpr_slice b); +GPRAPI int gpr_slice_str_cmp(gpr_slice a, const char *b); #ifdef __cplusplus } diff --git a/include/grpc/impl/codegen/slice_buffer.h b/include/grpc/impl/codegen/slice_buffer.h index 8428c2f539b24089809c84f710e69888aefd0000..4fe909ee82a3332a85410f6418ef4c9c94ba3c30 100644 --- a/include/grpc/impl/codegen/slice_buffer.h +++ b/include/grpc/impl/codegen/slice_buffer.h @@ -59,13 +59,13 @@ typedef struct { } gpr_slice_buffer; /* initialize a slice buffer */ -GPR_API void gpr_slice_buffer_init(gpr_slice_buffer *sb); +GPRAPI void gpr_slice_buffer_init(gpr_slice_buffer *sb); /* destroy a slice buffer - unrefs any held elements */ -GPR_API void gpr_slice_buffer_destroy(gpr_slice_buffer *sb); +GPRAPI void gpr_slice_buffer_destroy(gpr_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. */ -GPR_API void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice); +GPRAPI void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_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 @@ -73,30 +73,30 @@ GPR_API void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_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. */ -GPR_API size_t +GPRAPI size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb, gpr_slice slice); -GPR_API void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices, - size_t n); +GPRAPI void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_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 */ -GPR_API uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len); +GPRAPI uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len); /* pop the last buffer, but don't unref it */ -GPR_API void gpr_slice_buffer_pop(gpr_slice_buffer *sb); +GPRAPI void gpr_slice_buffer_pop(gpr_slice_buffer *sb); /* clear a slice buffer, unref all elements */ -GPR_API void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb); +GPRAPI void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb); /* swap the contents of two slice buffers */ -GPR_API void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b); +GPRAPI void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b); /* move all of the elements of src into dst */ -GPR_API void gpr_slice_buffer_move_into(gpr_slice_buffer *src, - gpr_slice_buffer *dst); +GPRAPI void gpr_slice_buffer_move_into(gpr_slice_buffer *src, + gpr_slice_buffer *dst); /* remove n bytes from the end of a slice buffer */ -GPR_API void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n, - gpr_slice_buffer *garbage); +GPRAPI void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n, + gpr_slice_buffer *garbage); /* move the first n bytes of src into dst */ -GPR_API void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n, - gpr_slice_buffer *dst); +GPRAPI void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n, + gpr_slice_buffer *dst); /* take the first slice in the slice buffer */ -GPR_API gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src); +GPRAPI gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src); #ifdef __cplusplus } diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h index 04ff0dc5bf9d734bb44fd32967cc387e9bdf58c3..d2f19d37d66ebcc1ac706b499d38c76c54700421 100644 --- a/include/grpc/impl/codegen/sync.h +++ b/include/grpc/impl/codegen/sync.h @@ -78,26 +78,26 @@ extern "C" { gpr_mu are uninitialized when first declared. */ /* Initialize *mu. Requires: *mu uninitialized. */ -GPR_API 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. */ -GPR_API void gpr_mu_destroy(gpr_mu *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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API int gpr_mu_trylock(gpr_mu *mu); +GPRAPI int gpr_mu_trylock(gpr_mu *mu); /* --- Condition variable interface --- @@ -106,11 +106,11 @@ GPR_API int gpr_mu_trylock(gpr_mu *mu); uninitialized when first declared. */ /* Initialize *cv. Requires: *cv uninitialized. */ -GPR_API 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.*/ -GPR_API void gpr_cv_destroy(gpr_cv *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) @@ -119,16 +119,16 @@ GPR_API 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. */ -GPR_API 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. */ -GPR_API void gpr_cv_signal(gpr_cv *cv); +GPRAPI void gpr_cv_signal(gpr_cv *cv); /* Wake all threads waiting on *cv. Requires: *cv initialized. */ -GPR_API void gpr_cv_broadcast(gpr_cv *cv); +GPRAPI void gpr_cv_broadcast(gpr_cv *cv); /* --- One-time initialization --- @@ -141,7 +141,7 @@ GPR_API 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.*/ -GPR_API 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 --- @@ -151,43 +151,43 @@ GPR_API void gpr_once_init(gpr_once *once, void (*init_routine)(void)); It requires no destruction. */ /* Initialize *ev. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API void gpr_ref(gpr_refcount *r); +GPRAPI void gpr_ref(gpr_refcount *r); /* Increment the reference count *r by n. Requires *r initialized, n > 0. */ -GPR_API 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. */ -GPR_API int gpr_unref(gpr_refcount *r); +GPRAPI int gpr_unref(gpr_refcount *r); /* --- Stats counters --- @@ -198,13 +198,13 @@ GPR_API int gpr_unref(gpr_refcount *r); synchronize other events. */ /* Initialize *c to the value n. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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, diff --git a/include/grpc/impl/codegen/time.h b/include/grpc/impl/codegen/time.h index 4ed1c3cbd86b5c9769a61ae6aad1197c6363c72c..c22bedfe77c0dc6eb98dd7d3ec3b8ef4935e5b78 100644 --- a/include/grpc/impl/codegen/time.h +++ b/include/grpc/impl/codegen/time.h @@ -69,10 +69,10 @@ typedef struct gpr_timespec { } gpr_timespec; /* Time constants. */ -GPR_API gpr_timespec +GPRAPI gpr_timespec gpr_time_0(gpr_clock_type type); /* The zero time interval. */ -GPR_API gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */ -GPR_API gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */ +GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */ +GPRAPI gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */ #define GPR_MS_PER_SEC 1000 #define GPR_US_PER_SEC 1000000 @@ -82,48 +82,46 @@ GPR_API gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */ #define GPR_US_PER_MS 1000 /* initialize time subsystem */ -GPR_API void gpr_time_init(void); +GPRAPI void gpr_time_init(void); /* Return the current time measured from the given clocks epoch. */ -GPR_API gpr_timespec gpr_now(gpr_clock_type clock); +GPRAPI gpr_timespec gpr_now(gpr_clock_type clock); /* Convert a timespec from one clock to another */ -GPR_API gpr_timespec +GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock); /* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b respectively. */ -GPR_API int gpr_time_cmp(gpr_timespec a, gpr_timespec b); +GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b); -GPR_API gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b); -GPR_API gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b); +GPRAPI gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b); +GPRAPI gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b); /* Add and subtract times. Calculations saturate at infinities. */ -GPR_API gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b); -GPR_API gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b); +GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b); +GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b); /* Return a timespec representing a given number of time units. INT64_MIN is interpreted as gpr_inf_past, and INT64_MAX as gpr_inf_future. */ -GPR_API gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type); -GPR_API gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type); -GPR_API gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type); -GPR_API gpr_timespec -gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type); -GPR_API gpr_timespec -gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type); -GPR_API gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type); +GPRAPI gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type); -GPR_API int32_t gpr_time_to_millis(gpr_timespec timespec); +GPRAPI int32_t gpr_time_to_millis(gpr_timespec timespec); /* Return 1 if two times are equal or within threshold of each other, 0 otherwise */ -GPR_API int gpr_time_similar(gpr_timespec a, gpr_timespec b, - gpr_timespec threshold); +GPRAPI int gpr_time_similar(gpr_timespec a, gpr_timespec b, + gpr_timespec threshold); /* Sleep until at least 'until' - an absolute timeout */ -GPR_API void gpr_sleep_until(gpr_timespec until); +GPRAPI void gpr_sleep_until(gpr_timespec until); -GPR_API double gpr_timespec_to_micros(gpr_timespec t); +GPRAPI double gpr_timespec_to_micros(gpr_timespec t); #ifdef __cplusplus } diff --git a/include/grpc/support/avl.h b/include/grpc/support/avl.h index 3433124c6fa5d01bbdb3b208942c39f17d3db54b..28eb5b175ea6d0ff1d2af05eeddbe0d196cad6f7 100644 --- a/include/grpc/support/avl.h +++ b/include/grpc/support/avl.h @@ -69,23 +69,23 @@ typedef struct gpr_avl { } gpr_avl; /** create an immutable AVL tree */ -GPR_API 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 */ -GPR_API gpr_avl gpr_avl_ref(gpr_avl avl); +GPRAPI gpr_avl gpr_avl_ref(gpr_avl avl); /** remove a reference to a tree - destroying it if there are no references left */ -GPR_API void gpr_avl_unref(gpr_avl avl); +GPRAPI void gpr_avl_unref(gpr_avl avl); /** 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) */ -GPR_API gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value); +GPRAPI gpr_avl gpr_avl_add(gpr_avl avl, void *key, void *value); /** return a new tree with key deleted */ -GPR_API gpr_avl gpr_avl_remove(gpr_avl avl, void *key); +GPRAPI gpr_avl gpr_avl_remove(gpr_avl avl, void *key); /** lookup key, and return the associated value. does not mutate avl. returns NULL if key is not found. */ -GPR_API void *gpr_avl_get(gpr_avl avl, void *key); +GPRAPI void *gpr_avl_get(gpr_avl avl, void *key); #endif diff --git a/include/grpc/support/cmdline.h b/include/grpc/support/cmdline.h index 6f442e3cf23b2bd392cdea455d2d98753ee74697..55e2ffdffe6c46799da39e12a962de6fc55ba4c6 100644 --- a/include/grpc/support/cmdline.h +++ b/include/grpc/support/cmdline.h @@ -70,31 +70,31 @@ typedef struct gpr_cmdline gpr_cmdline; /* Construct a command line parser: takes a short description of the tool doing the parsing */ -GPR_API 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) */ -GPR_API 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 */ -GPR_API 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 */ -GPR_API 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, char **value); /* Set a callback for non-named arguments */ -GPR_API void gpr_cmdline_on_extra_arg( +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); /* Enable surviving failure: default behavior is to exit the process */ -GPR_API 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 */ -GPR_API 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 */ -GPR_API void gpr_cmdline_destroy(gpr_cmdline *cl); +GPRAPI void gpr_cmdline_destroy(gpr_cmdline *cl); /* Get a string describing usage */ -GPR_API 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/cpu.h b/include/grpc/support/cpu.h index db4bdd42aabbacb717797f1fb15c6c5c06ddfa60..3ca83b5a0d679437ba22e0883ac4f30a6458448b 100644 --- a/include/grpc/support/cpu.h +++ b/include/grpc/support/cpu.h @@ -44,13 +44,13 @@ extern "C" { /* Return the number of CPU cores on the current system. Will return 0 if the information is not available. */ -GPR_API unsigned gpr_cpu_num_cores(void); +GPRAPI unsigned gpr_cpu_num_cores(void); /* Return the CPU on which the current thread is executing; N.B. This should be considered advisory only - it is possible that the thread is switched to a different CPU at any time. Returns a value in range [0, gpr_cpu_num_cores() - 1] */ -GPR_API unsigned gpr_cpu_current_cpu(void); +GPRAPI unsigned gpr_cpu_current_cpu(void); #ifdef __cplusplus } // extern "C" diff --git a/include/grpc/support/histogram.h b/include/grpc/support/histogram.h index 9c807ea27db11ec944ad341afdff2303d08854ac..c34c8c840716b2ee7130a7c5f7d708ecf381c43e 100644 --- a/include/grpc/support/histogram.h +++ b/include/grpc/support/histogram.h @@ -43,34 +43,34 @@ extern "C" { typedef struct gpr_histogram gpr_histogram; -GPR_API gpr_histogram *gpr_histogram_create(double resolution, - double max_bucket_start); -GPR_API void gpr_histogram_destroy(gpr_histogram *h); -GPR_API void gpr_histogram_add(gpr_histogram *h, double x); +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 */ -GPR_API int gpr_histogram_merge(gpr_histogram *dst, const gpr_histogram *src); +GPRAPI int gpr_histogram_merge(gpr_histogram *dst, const gpr_histogram *src); -GPR_API double gpr_histogram_percentile(gpr_histogram *histogram, - double percentile); -GPR_API double gpr_histogram_mean(gpr_histogram *histogram); -GPR_API double gpr_histogram_stddev(gpr_histogram *histogram); -GPR_API double gpr_histogram_variance(gpr_histogram *histogram); -GPR_API double gpr_histogram_maximum(gpr_histogram *histogram); -GPR_API double gpr_histogram_minimum(gpr_histogram *histogram); -GPR_API double gpr_histogram_count(gpr_histogram *histogram); -GPR_API double gpr_histogram_sum(gpr_histogram *histogram); -GPR_API double gpr_histogram_sum_of_squares(gpr_histogram *histogram); +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); -GPR_API const uint32_t *gpr_histogram_get_contents(gpr_histogram *histogram, - size_t *count); -GPR_API 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); +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 } diff --git a/include/grpc/support/host_port.h b/include/grpc/support/host_port.h index ee9c294ebcd20492949867c4593790cb5e318404..53cc917acb4b6d273c7ce99c5d03d2d4c615196c 100644 --- a/include/grpc/support/host_port.h +++ b/include/grpc/support/host_port.h @@ -50,14 +50,14 @@ extern "C" { destroyed using gpr_free(). In the unlikely event of an error, returns -1 and sets *out to NULL. */ -GPR_API 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. */ -GPR_API 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_win32.h b/include/grpc/support/log_win32.h index 1470e5b48409f44590de793be163601d55a0093e..49c9ab0f91436b25fbe26e1b9169173a1ae3c601 100644 --- a/include/grpc/support/log_win32.h +++ b/include/grpc/support/log_win32.h @@ -42,7 +42,7 @@ extern "C" { * formatted error message, corresponding to the error messageid. * Use in conjunction with GetLastError() et al. */ -GPR_API 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 74f2cb371a278b7d20caed6d84e51d24d1a657f9..6fc38cb191fa62d2f6418a55915c79099b89bba0 100644 --- a/include/grpc/support/string_util.h +++ b/include/grpc/support/string_util.h @@ -42,7 +42,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. */ -GPR_API 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. @@ -52,7 +52,7 @@ GPR_API 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. */ -GPR_API int gpr_asprintf(char **strp, const char *format, ...); +GPRAPI int gpr_asprintf(char **strp, const char *format, ...); #ifdef __cplusplus } diff --git a/include/grpc/support/subprocess.h b/include/grpc/support/subprocess.h index ffbdf67357712fb6b2b16dd870ddbc5a14046a5f..6a4946014bed5bee01cccf76af4a5c69fba8257f 100644 --- a/include/grpc/support/subprocess.h +++ b/include/grpc/support/subprocess.h @@ -43,14 +43,14 @@ extern "C" { typedef struct gpr_subprocess gpr_subprocess; /* .exe on windows, empty on unices */ -GPR_API const char *gpr_subprocess_binary_extension(); +GPRAPI const char *gpr_subprocess_binary_extension(); -GPR_API 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 */ -GPR_API void gpr_subprocess_destroy(gpr_subprocess *p); +GPRAPI void gpr_subprocess_destroy(gpr_subprocess *p); /* returns exit status; can be called at most once */ -GPR_API int gpr_subprocess_join(gpr_subprocess *p); -GPR_API 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/thd.h b/include/grpc/support/thd.h index 84e964fc07bee10e895992373b06e0c2198d879e..abe57ebefb8f3844a2a4f389b6407013595f3d8e 100644 --- a/include/grpc/support/thd.h +++ b/include/grpc/support/thd.h @@ -59,30 +59,30 @@ typedef struct { in *t, and return true. If there are insufficient resources, return false. If options==NULL, default options are used. The thread is immediately runnable, and exits when (*thd_body)() returns. */ -GPR_API 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, void (*thd_body)(void *arg), void *arg, + const gpr_thd_options *options); /* Return a gpr_thd_options struct with all fields set to defaults. */ -GPR_API gpr_thd_options gpr_thd_options_default(void); +GPRAPI gpr_thd_options gpr_thd_options_default(void); /* Set the thread to become detached on startup - this is the default. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API 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. */ -GPR_API gpr_thd_id gpr_thd_currentid(void); +GPRAPI gpr_thd_id gpr_thd_currentid(void); /* Blocks until the specified thread properly terminates. Calling this on a detached thread has unpredictable results. */ -GPR_API void gpr_thd_join(gpr_thd_id t); +GPRAPI void gpr_thd_join(gpr_thd_id t); #ifdef __cplusplus } diff --git a/setup.py b/setup.py index ceca6f6808df65c5bfcc8d35ee713c6f820d49a9..69e59e3aff64d4145a3eb5fc2e553471909133a3 100644 --- a/setup.py +++ b/setup.py @@ -94,10 +94,10 @@ if "linux" in sys.platform: if not "win32" in sys.platform: EXTENSION_LIBRARIES += ('m',) -DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600)) +DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) -CFLAGS = () LDFLAGS = () +CFLAGS = () if "linux" in sys.platform: LDFLAGS += ('-Wl,-wrap,memcpy',) if "linux" in sys.platform or "darwin" in sys.platform: diff --git a/src/core/census/grpc_filter.c b/src/core/census/grpc_filter.c index a8db32b9d54dd01bc9437c85263523762dc6ebdf..c8aaf31e2d3a688717c669c0f9242f9f8814cfc8 100644 --- a/src/core/census/grpc_filter.c +++ b/src/core/census/grpc_filter.c @@ -107,8 +107,8 @@ static void server_mutate_op(grpc_call_element *elem, if (op->recv_initial_metadata) { /* substitute our callback for the op callback */ calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->on_complete; - op->on_complete = &calld->finish_recv; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->finish_recv; } } diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 43eee046b888cc12ce4496377f7191f07acf2227..1aa27208c2e9725aebfad8b2ddfc18a29a9671c1 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -127,8 +127,8 @@ static void hc_mutate_op(grpc_call_element *elem, if (op->recv_initial_metadata != NULL) { /* substitute our callback for the higher callback */ calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->on_complete; - op->on_complete = &calld->hc_on_recv; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->hc_on_recv; } } diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index bb75323933c7357f9f226c7e958a958a6a25e22d..370f8dbe423d3a6b4f09a18198369f0f4f930cbf 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -186,8 +186,8 @@ static void hs_mutate_op(grpc_call_element *elem, if (op->recv_initial_metadata) { /* substitute our callback for the higher callback */ calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->on_complete; - op->on_complete = &calld->hs_on_recv; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->hs_on_recv; } } diff --git a/src/core/channel/subchannel_call_holder.c b/src/core/channel/subchannel_call_holder.c index 3ad9fd9efb14c43f9ec114ea07fcdb401b3e8c82..81297c8d4490eff53d0015aa11ff3268b5ba8e46 100644 --- a/src/core/channel/subchannel_call_holder.c +++ b/src/core/channel/subchannel_call_holder.c @@ -241,10 +241,8 @@ static void fail_locked(grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) { size_t i; for (i = 0; i < holder->waiting_ops_count; i++) { - grpc_exec_ctx_enqueue(exec_ctx, holder->waiting_ops[i].on_complete, false, - NULL); - grpc_exec_ctx_enqueue(exec_ctx, holder->waiting_ops[i].recv_message_ready, - false, NULL); + grpc_transport_stream_op_finish_with_failure(exec_ctx, + &holder->waiting_ops[i]); } holder->waiting_ops_count = 0; } diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 4c78711387e7734785004a65d78568644c8eb748..3d8e5e8d35dda637c4b4132f155d2eab493be161 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -176,8 +176,8 @@ static void set_recv_ops_md_callbacks(grpc_call_element *elem, if (op->recv_initial_metadata != NULL) { /* substitute our callback for the higher callback */ calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv = op->on_complete; - op->on_complete = &calld->auth_on_recv; + calld->on_done_recv = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->auth_on_recv; calld->transport_op = *op; } } diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c index 442cd8298e2403d8de5ba8d403843fb554fcf8a6..1ca6fa1affe29a9d630afff58a262ff94504e9ee 100644 --- a/src/core/support/env_linux.c +++ b/src/core/support/env_linux.c @@ -52,6 +52,7 @@ #include "src/core/support/string.h" char *gpr_getenv(const char *name) { +#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) typedef char *(*getenv_type)(const char *); static getenv_type getenv_func = NULL; /* Check to see which getenv variant is supported (go from most @@ -62,6 +63,10 @@ char *gpr_getenv(const char *name) { } char *result = getenv_func(name); return result == NULL ? result : gpr_strdup(result); +#else + char *result = secure_getenv(name); + return result == NULL ? result : gpr_strdup(result); +#endif } void gpr_setenv(const char *name, const char *value) { diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c index 1f92d7f0908be642769fae243c78340ea462ac4a..36d75e7da2fbfa1b63051fbcf90509729107e269 100644 --- a/src/core/support/time_posix.c +++ b/src/core/support/time_posix.c @@ -86,7 +86,7 @@ gpr_timespec gpr_now(gpr_clock_type clock_type) { gpr_precise_clock_now(&ret); return ret; } else { -#if defined(__linux__) && !defined(GPR_NO_DIRECT_SYSCALLS) +#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) && defined(__linux__) /* avoid ABI problems by invoking syscalls directly */ syscall(SYS_clock_gettime, clockid_for_gpr_clock[clock_type], &now); #else diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 9495e748b5f9dfd7b347b5dbb1a1d214c123c642..1b117aa6b8ca752f7987688c474d159c9d60f2f5 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -159,6 +159,9 @@ struct grpc_call { uint8_t receiving_message; uint8_t received_final_op; + /* have we received initial metadata */ + bool has_initial_md_been_received; + batch_control active_batches[MAX_CONCURRENT_BATCHES]; /* first idx: is_receiving, second idx: is_trailing */ @@ -200,6 +203,7 @@ struct grpc_call { gpr_slice receiving_slice; grpc_closure receiving_slice_ready; grpc_closure receiving_stream_ready; + grpc_closure receiving_initial_metadata_ready; uint32_t test_only_last_message_flags; union { @@ -212,6 +216,11 @@ struct grpc_call { int *cancelled; } server; } final_op; + + struct { + void *bctlp; + bool success; + } saved_receiving_stream_ready_ctx; }; #define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1)) @@ -993,6 +1002,94 @@ static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp, } } +static void process_data_after_md(grpc_exec_ctx *exec_ctx, batch_control *bctl, + bool success) { + grpc_call *call = bctl->call; + if (call->receiving_stream == NULL) { + *call->receiving_buffer = NULL; + call->receiving_message = 0; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + } else if (call->receiving_stream->length > + grpc_channel_get_max_message_length(call->channel)) { + cancel_with_status(exec_ctx, call, GRPC_STATUS_INTERNAL, + "Max message size exceeded"); + grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); + call->receiving_stream = NULL; + *call->receiving_buffer = NULL; + call->receiving_message = 0; + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } + } else { + call->test_only_last_message_flags = call->receiving_stream->flags; + if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) && + (call->compression_algorithm > GRPC_COMPRESS_NONE)) { + *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create( + NULL, 0, call->compression_algorithm); + } else { + *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0); + } + grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready, + bctl); + continue_receiving_slices(exec_ctx, bctl); + /* early out */ + return; + } +} + +static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, + bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + + gpr_mu_lock(&bctl->call->mu); + if (bctl->call->has_initial_md_been_received) { + gpr_mu_unlock(&bctl->call->mu); + process_data_after_md(exec_ctx, bctlp, success); + } else { + call->saved_receiving_stream_ready_ctx.bctlp = bctlp; + call->saved_receiving_stream_ready_ctx.success = success; + gpr_mu_unlock(&bctl->call->mu); + } +} + +static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, + void *bctlp, bool success) { + batch_control *bctl = bctlp; + grpc_call *call = bctl->call; + + gpr_mu_lock(&call->mu); + + grpc_metadata_batch *md = + &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; + grpc_metadata_batch_filter(md, recv_initial_filter, call); + call->has_initial_md_been_received = true; + + if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) != + 0 && + !call->is_client) { + GPR_TIMER_BEGIN("set_deadline_alarm", 0); + set_deadline_alarm(exec_ctx, call, md->deadline); + GPR_TIMER_END("set_deadline_alarm", 0); + } + + if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) { + grpc_closure *saved_rsr_closure = grpc_closure_create( + receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp); + grpc_exec_ctx_enqueue(exec_ctx, saved_rsr_closure, + call->saved_receiving_stream_ready_ctx.success, NULL); + call->saved_receiving_stream_ready_ctx.bctlp = NULL; + } + + gpr_mu_unlock(&call->mu); + + if (gpr_unref(&bctl->steps_to_complete)) { + post_batch_completion(exec_ctx, bctl); + } +} + static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { batch_control *bctl = bctlp; grpc_call *call = bctl->call; @@ -1011,19 +1108,6 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { grpc_metadata_batch_destroy( &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]); } - if (bctl->recv_initial_metadata) { - grpc_metadata_batch *md = - &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; - grpc_metadata_batch_filter(md, recv_initial_filter, call); - - if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) != - 0 && - !call->is_client) { - GPR_TIMER_BEGIN("set_deadline_alarm", 0); - set_deadline_alarm(exec_ctx, call, md->deadline); - GPR_TIMER_END("set_deadline_alarm", 0); - } - } if (bctl->recv_final_op) { grpc_metadata_batch *md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; @@ -1065,45 +1149,6 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) { } } -static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp, - bool success) { - batch_control *bctl = bctlp; - grpc_call *call = bctl->call; - - if (call->receiving_stream == NULL) { - *call->receiving_buffer = NULL; - call->receiving_message = 0; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - } else if (call->receiving_stream->length > - grpc_channel_get_max_message_length(call->channel)) { - cancel_with_status(exec_ctx, call, GRPC_STATUS_INTERNAL, - "Max message size exceeded"); - grpc_byte_stream_destroy(exec_ctx, call->receiving_stream); - call->receiving_stream = NULL; - *call->receiving_buffer = NULL; - call->receiving_message = 0; - if (gpr_unref(&bctl->steps_to_complete)) { - post_batch_completion(exec_ctx, bctl); - } - } else { - call->test_only_last_message_flags = call->receiving_stream->flags; - if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) && - (call->compression_algorithm > GRPC_COMPRESS_NONE)) { - *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create( - NULL, 0, call->compression_algorithm); - } else { - *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0); - } - grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready, - bctl); - continue_receiving_slices(exec_ctx, bctl); - /* early out */ - return; - } -} - static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, grpc_call *call, const grpc_op *ops, size_t nops, void *notify_tag, @@ -1273,9 +1318,14 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, } call->received_initial_metadata = 1; call->buffered_metadata[0] = op->data.recv_initial_metadata; + grpc_closure_init(&call->receiving_initial_metadata_ready, + receiving_initial_metadata_ready, bctl); bctl->recv_initial_metadata = 1; stream_op.recv_initial_metadata = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; + stream_op.recv_initial_metadata_ready = + &call->receiving_initial_metadata_ready; + num_completion_callbacks_needed++; break; case GRPC_OP_RECV_MESSAGE: /* Flag validation: currently allow no flags */ diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index 705996cad35259e3998528adb746414d71da10cf..537069e9848c087d18969d6022ffc9545531f611 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -78,8 +78,7 @@ static void lame_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } else if (op->recv_trailing_metadata != NULL) { fill_metadata(elem, op->recv_trailing_metadata); } - grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, false, NULL); - grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, false, NULL); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op); } static char *lame_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 42cffccb4c9e00d975617aa12631a2501e0926a3..fb5e0d4b9e70a471d9b2bfc4db2793476d2adc64 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -596,8 +596,8 @@ static void server_mutate_op(grpc_call_element *elem, if (op->recv_initial_metadata != NULL) { calld->recv_initial_metadata = op->recv_initial_metadata; - calld->on_done_recv_initial_metadata = op->on_complete; - op->on_complete = &calld->server_on_recv_initial_metadata; + calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata; } } diff --git a/src/core/surface/validate_metadata.c b/src/core/surface/validate_metadata.c index df2e80b4b78cdf35a401fd475bfd6f10ad182a77..bf4126867fd7e68b4381f6a9d37d89ef075ba9b8 100644 --- a/src/core/surface/validate_metadata.c +++ b/src/core/surface/validate_metadata.c @@ -50,7 +50,7 @@ static int conforms_to(const char *s, size_t len, const uint8_t *legal_bits) { int grpc_header_key_is_legal(const char *key, size_t length) { static const uint8_t legal_header_bits[256 / 8] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (length == 0) { diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h index c611496e7e5793731052805c21f82d0995b119d9..0e1e2c42650f855f6d12b5b131cab3fc842d6221 100644 --- a/src/core/transport/chttp2/internal.h +++ b/src/core/transport/chttp2/internal.h @@ -385,7 +385,7 @@ typedef struct { grpc_closure *send_trailing_metadata_finished; grpc_metadata_batch *recv_initial_metadata; - grpc_closure *recv_initial_metadata_finished; + grpc_closure *recv_initial_metadata_ready; grpc_byte_stream **recv_message; grpc_closure *recv_message_ready; grpc_metadata_batch *recv_trailing_metadata; diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 9298573c7f4c56498c21f34ed9879674681009f8..617d98875c301e2eb5a381d9dc6cd3837b3a4d20 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -544,7 +544,7 @@ static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, GPR_ASSERT(s->global.send_initial_metadata_finished == NULL); GPR_ASSERT(s->global.send_message_finished == NULL); GPR_ASSERT(s->global.send_trailing_metadata_finished == NULL); - GPR_ASSERT(s->global.recv_initial_metadata_finished == NULL); + GPR_ASSERT(s->global.recv_initial_metadata_ready == NULL); GPR_ASSERT(s->global.recv_message_ready == NULL); GPR_ASSERT(s->global.recv_trailing_metadata_finished == NULL); grpc_chttp2_data_parser_destroy(exec_ctx, &s->parsing.data_parser); @@ -863,9 +863,9 @@ static void perform_stream_op_locked( } if (op->recv_initial_metadata != NULL) { - GPR_ASSERT(stream_global->recv_initial_metadata_finished == NULL); - stream_global->recv_initial_metadata_finished = - add_closure_barrier(on_complete); + GPR_ASSERT(stream_global->recv_initial_metadata_ready == NULL); + stream_global->recv_initial_metadata_ready = + op->recv_initial_metadata_ready; stream_global->recv_initial_metadata = op->recv_initial_metadata; grpc_chttp2_list_add_check_read_ops(transport_global, stream_global); } @@ -1009,13 +1009,14 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx, grpc_byte_stream *bs; while ( grpc_chttp2_list_pop_check_read_ops(transport_global, &stream_global)) { - if (stream_global->recv_initial_metadata_finished != NULL && + if (stream_global->recv_initial_metadata_ready != NULL && stream_global->published_initial_metadata) { grpc_chttp2_incoming_metadata_buffer_publish( &stream_global->received_initial_metadata, stream_global->recv_initial_metadata); - grpc_chttp2_complete_closure_step( - exec_ctx, &stream_global->recv_initial_metadata_finished, 1); + grpc_exec_ctx_enqueue( + exec_ctx, stream_global->recv_initial_metadata_ready, true, NULL); + stream_global->recv_initial_metadata_ready = NULL; } if (stream_global->recv_message_ready != NULL) { if (stream_global->incoming_frames.head != NULL) { diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c index 08d685668ccb73a2b418faa5c17b96c973f287bf..6e154b629ab872ab57a4561d822094cf8baa2982 100644 --- a/src/core/transport/transport.c +++ b/src/core/transport/transport.c @@ -126,6 +126,7 @@ char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, void grpc_transport_stream_op_finish_with_failure( grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op) { grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, false, NULL); + grpc_exec_ctx_enqueue(exec_ctx, op->recv_initial_metadata_ready, false, NULL); grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, false, NULL); } diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index f5cac77adcc51b70fe402ba279fc87da171a0881..8902c5d2f65f886e5535bc2fe2edc2631aee2941 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -92,6 +92,8 @@ typedef struct grpc_transport_stream_op { /** Receive initial metadata from the stream, into provided metadata batch. */ grpc_metadata_batch *recv_initial_metadata; + /** Should be enqueued when initial metadata is ready to be processed. */ + grpc_closure *recv_initial_metadata_ready; /** Receive message data from the stream, into provided byte stream. */ grpc_byte_stream **recv_message; @@ -103,7 +105,8 @@ typedef struct grpc_transport_stream_op { grpc_metadata_batch *recv_trailing_metadata; /** Should be enqueued when all requested operations (excluding recv_message - which has its own closure) in a given batch have been completed. */ + and recv_initial_metadata which have their own closures) in a given batch + have been completed. */ grpc_closure *on_complete; /** If != GRPC_STATUS_OK, cancel this stream */ diff --git a/src/node/performance/worker_server.js b/src/node/performance/worker.js similarity index 100% rename from src/node/performance/worker_server.js rename to src/node/performance/worker.js diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index b7c6cb3d7eaa01d1bc5cafd44b8755193e8299a1..6b7001a4899d774b747c6887d7cca582fefb0b74 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -79,6 +79,7 @@ unless File.exist?(File.join(grpc_lib_dir, 'libgrpc.a')) or windows ENV['EMBED_ZLIB'] = 'true' ENV['ARCH_FLAGS'] = RbConfig::CONFIG['ARCH_FLAG'] ENV['ARCH_FLAGS'] = '-arch i386 -arch x86_64' if RUBY_PLATFORM =~ /darwin/ + ENV['CFLAGS'] = '-DGPR_BACKWARDS_COMPATIBILITY_MODE' output_dir = File.expand_path(RbConfig::CONFIG['topdir']) grpc_lib_dir = File.join(output_dir, 'libs', grpc_config) diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 594fda1cd3e433f9408478c5951b2bf941e09c18..7ef534571f0e053c0d0a03a9e15b3a915cf96f0a 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -1,4 +1,4 @@ -# Copyright 2015, Google Inc. +# Copyright 2015-2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -198,6 +198,7 @@ shared_examples 'basic GRPC message delivery is OK' do # confirm the client can receive the server response and status. client_ops = { CallOps::SEND_CLOSE_FROM_CLIENT => nil, + CallOps::RECV_INITIAL_METADATA => nil, CallOps::RECV_MESSAGE => nil, CallOps::RECV_STATUS_ON_CLIENT => nil } diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template index 7cee562caaab8330506762d584904e30e55fd822..3ffbc0664322f207305419d215d5926765600545 100644 --- a/templates/binding.gyp.template +++ b/templates/binding.gyp.template @@ -57,7 +57,8 @@ 'UNICODE', '_UNICODE', 'NOMINMAX', - 'OPENSSL_NO_ASM' + 'OPENSSL_NO_ASM', + 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], "msvs_settings": { 'VCCLCompilerTool': { @@ -80,7 +81,8 @@ # supports ALPN. The target is "[major].[minor].[patch]". We split by # periods and take the first field to get the major version. 'defines': [ - 'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)' + 'TSI_OPENSSL_ALPN_SUPPORT=<!(echo <(target) | cut -d. -f1)', + 'GPR_BACKWARDS_COMPATIBILITY_MODE' ], 'include_dirs': [ '<(node_root_dir)/deps/openssl/openssl/include', diff --git a/test/core/fling/client.c b/test/core/fling/client.c index 02db681cfd3b7fa9507b98da939bf8f402f44db6..b36aef30935998b52a93f5dbbda0bffcc08314ef 100644 --- a/test/core/fling/client.c +++ b/test/core/fling/client.c @@ -51,7 +51,7 @@ static grpc_channel *channel; static grpc_completion_queue *cq; static grpc_call *call; static grpc_op ops[6]; -static grpc_op stream_init_op; +static grpc_op stream_init_ops[2]; static grpc_op stream_step_ops[2]; static grpc_metadata_array initial_metadata_recv; static grpc_metadata_array trailing_metadata_recv; @@ -105,13 +105,17 @@ static void step_ping_pong_request(void) { } static void init_ping_pong_stream(void) { + grpc_metadata_array_init(&initial_metadata_recv); + grpc_call_error error; call = grpc_channel_create_call(channel, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/Reflector/reflectStream", "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL); - stream_init_op.op = GRPC_OP_SEND_INITIAL_METADATA; - stream_init_op.data.send_initial_metadata.count = 0; - error = grpc_call_start_batch(call, &stream_init_op, 1, (void *)1, NULL); + stream_init_ops[0].op = GRPC_OP_SEND_INITIAL_METADATA; + stream_init_ops[0].data.send_initial_metadata.count = 0; + stream_init_ops[1].op = GRPC_OP_RECV_INITIAL_METADATA; + stream_init_ops[1].data.recv_initial_metadata = &initial_metadata_recv; + error = grpc_call_start_batch(call, stream_init_ops, 2, (void *)1, NULL); GPR_ASSERT(GRPC_CALL_OK == error); grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 252bda3798803de66977ba288ff0637c22dea459..a194c615cdfd1965623371d1627abc8c4d5af52f 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -479,8 +479,10 @@ TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { send_request.set_message("Hello"); std::pair<grpc::string, grpc::string> meta1("key1", "val1"); std::pair<grpc::string, grpc::string> meta2("key2", "val2"); + std::pair<grpc::string, grpc::string> meta3("g.r.d-bin", "xyz"); cli_ctx.AddMetadata(meta1.first, meta1.second); cli_ctx.AddMetadata(meta2.first, meta2.second); + cli_ctx.AddMetadata(meta3.first, meta3.second); std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader( stub_->AsyncEcho(&cli_ctx, send_request, cq_.get())); @@ -494,6 +496,8 @@ TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) { ToString(client_initial_metadata.find(meta1.first)->second)); EXPECT_EQ(meta2.second, ToString(client_initial_metadata.find(meta2.first)->second)); + EXPECT_EQ(meta3.second, + ToString(client_initial_metadata.find(meta3.first)->second)); EXPECT_GE(client_initial_metadata.size(), static_cast<size_t>(2)); send_response.set_message(recv_request.message()); diff --git a/test/distrib/python/distribtest.py b/test/distrib/python/distribtest.py index 66c1f88796454353c2efd6a55d2fe7df44ea8188..dc206881409ff9e5ef899a075e1c684ffecb9f00 100644 --- a/test/distrib/python/distribtest.py +++ b/test/distrib/python/distribtest.py @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google Inc. +# Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/tools/README.md b/tools/README.md index eb6633a866fba3e1504430ad4525bbabd0b8e5c1..a0c41eb79ffcdfea58e15b1d35a18e8cb4ab3210 100644 --- a/tools/README.md +++ b/tools/README.md @@ -8,6 +8,8 @@ dockerfile: Docker files to test gRPC. doxygen: gRPC C/C++ documentation generation via Doxygen. +gce: scripts to help setup testing infrastructure on GCE. + jenkins: support for running tests on Jenkins. profile_analyzer: pretty printer for gRPC profiling data. diff --git a/tools/buildgen/plugins/list_api.py b/tools/buildgen/plugins/list_api.py index 3396dcd39ba4e593b9a2eea60dc4e89c53b5fcf0..ff937a0ab837acd0b2365f3a16153eadbbc9dcab 100755 --- a/tools/buildgen/plugins/list_api.py +++ b/tools/buildgen/plugins/list_api.py @@ -37,7 +37,7 @@ import sys import yaml -_RE_API = r'(?:GPR_API|GRPC_API|CENSUS_API)([^;]*);' +_RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);' def list_c_apis(filenames): diff --git a/tools/codegen/core/gen_legal_metadata_characters.c b/tools/codegen/core/gen_legal_metadata_characters.c index 3c9e1c7619b1469cdc6680bd4e11d4aeb55148bb..10605d52bfa7bb07aaae36fa734321505b8a8951 100644 --- a/tools/codegen/core/gen_legal_metadata_characters.c +++ b/tools/codegen/core/gen_legal_metadata_characters.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,7 +52,7 @@ static void legal(int x) { static void dump(void) { int i; - printf("static const gpr_uint8 legal_header_bits[256/8] = "); + printf("static const uint8_t legal_header_bits[256/8] = "); for (i = 0; i < 256 / 8; i++) printf("%c 0x%02x", i ? ',' : '{', legal_bits[i]); printf(" };\n"); diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh new file mode 100755 index 0000000000000000000000000000000000000000..2a9e77ab1738d516b193860d84b503538213432d --- /dev/null +++ b/tools/gce/create_linux_worker.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Copyright 2015-2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Creates a standard jenkins worker on GCE. + +set -ex + +cd $(dirname $0) + +CLOUD_PROJECT=grpc-testing +ZONE=us-central1-a + +INSTANCE_NAME=grpc-jenkins-worker1 + +gcloud compute instances create $INSTANCE_NAME \ + --project="$CLOUD_PROJECT" \ + --zone "$ZONE" \ + --machine-type n1-standard-8 \ + --image ubuntu-14-04 \ + --boot-disk-size 1000 + +echo 'Created GCE instance, waiting 60 seconds for it to come online.' +sleep 60 + +gcloud compute copy-files \ + --project="$CLOUD_PROJECT" \ + --zone "$ZONE" \ + jenkins_master.pub linux_worker_init.sh ${INSTANCE_NAME}:~ + +gcloud compute ssh \ + --project="$CLOUD_PROJECT" \ + --zone "$ZONE" \ + $INSTANCE_NAME --command "./linux_worker_init.sh" diff --git a/tools/gce/jenkins_master.pub b/tools/gce/jenkins_master.pub new file mode 100644 index 0000000000000000000000000000000000000000..e9853224e13cd44692f13fa899e8ee44eb9eaf91 --- /dev/null +++ b/tools/gce/jenkins_master.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDzj9l7Tp4yKnMV8sSMNvm5Q9v/F2F187xF93niJFY8lz6ig4bhusqvNbAxPoeypds9NYjLDK6kONN9teemgv2+IcmmlAI4wkCkkWcL/kzdNNH0h5J7+YbPiUGFAu0hZNHg5jzwrZ3VFKwv6d/7dUdPOYmPaOG1JOEcxXcBvm1hMIe474jpUTTiG4/gMDJ1GhMg5T3cuCm2l0gCiv7ybRAgwaZ2EKEEWLy9qAL/pnr3umBjQvzAUGcOgXJyG0mbr977YdJo9kb+EELRTVN2q8mKZJEZ1BJAylkaI9783K2+cGaM8hPtKFcX4ImEYEkWgfOyGNolGDquWtvusGGzQXwF jenkins@grpc-jenkins-master diff --git a/tools/gce/linux_worker_init.sh b/tools/gce/linux_worker_init.sh new file mode 100755 index 0000000000000000000000000000000000000000..f56cac0ce2f1601a431acf3174e3d27b96512171 --- /dev/null +++ b/tools/gce/linux_worker_init.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# Copyright 2015-2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Initializes a fresh GCE VM to become a jenkins linux worker. +# You shouldn't run this script on your own, use create_linux_worker.sh +# instead. + +set -ex + +sudo apt-get update + +# Install JRE +sudo apt-get install -y openjdk-7-jre +sudo apt-get install -y unzip lsof + +# Install Docker +curl -sSL https://get.docker.com/ | sh + +# Setup jenkins user (or the user will already exist bcuz magic) +sudo adduser jenkins --disabled-password || true + +# Enable jenkins to use docker without sudo: +sudo usermod -aG docker jenkins + +# Use "overlay" storage driver for docker +# see https://github.com/grpc/grpc/issues/4988 +echo 'DOCKER_OPTS="${DOCKER_OPTS} --storage-driver=overlay"' | sudo tee --append /etc/default/docker + +# Install RVM +# TODO(jtattermusch): why is RVM needed? +gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 +curl -sSL https://get.rvm.io | bash -s stable --ruby + +# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@ +# This needs to happen as the last step to prevent Jenkins master from connecting +# to a machine that hasn't been properly setup yet. +cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys + +# Restart for docker to pickup the config changes. +echo 'Successfully initialized the linux worker, going for reboot in 10 seconds' +sleep 10 + +sudo reboot diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py index 74d2a4859c8272166bb9c6b9b1d8ff6bab9823f3..9cd02c5e432e0a517e74478f5c2f49c7588c620c 100644 --- a/tools/run_tests/artifact_targets.py +++ b/tools/run_tests/artifact_targets.py @@ -175,7 +175,8 @@ class CSharpExtArtifact: else: environ = {'CONFIG': 'opt', 'EMBED_OPENSSL': 'true', - 'EMBED_ZLIB': 'true'} + 'EMBED_ZLIB': 'true', + 'CFLAGS': '-DGPR_BACKWARDS_COMPATIBILITY_MODE'} if self.platform == 'linux': return create_docker_jobspec(self.name, 'tools/dockerfile/grpc_artifact_linux_%s' % self.arch, diff --git a/tools/run_tests/build_node.bat b/tools/run_tests/build_node.bat new file mode 100644 index 0000000000000000000000000000000000000000..6896bc1d1bb1480ea66c222390b9a5104168d367 --- /dev/null +++ b/tools/run_tests/build_node.bat @@ -0,0 +1,30 @@ +@rem Copyright 2016, Google Inc. +@rem All rights reserved. +@rem +@rem Redistribution and use in source and binary forms, with or without +@rem modification, are permitted provided that the following conditions are +@rem met: +@rem +@rem * Redistributions of source code must retain the above copyright +@rem notice, this list of conditions and the following disclaimer. +@rem * Redistributions in binary form must reproduce the above +@rem copyright notice, this list of conditions and the following disclaimer +@rem in the documentation and/or other materials provided with the +@rem distribution. +@rem * Neither the name of Google Inc. nor the names of its +@rem contributors may be used to endorse or promote products derived from +@rem this software without specific prior written permission. +@rem +@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +npm install --build-from-source \ No newline at end of file diff --git a/tools/run_tests/pre_build_node.bat b/tools/run_tests/pre_build_node.bat new file mode 100644 index 0000000000000000000000000000000000000000..6e7cbe5d420d58060f8c26dbc9b5953f92e9ee1c --- /dev/null +++ b/tools/run_tests/pre_build_node.bat @@ -0,0 +1,39 @@ +@rem Copyright 2016, Google Inc. +@rem All rights reserved. +@rem +@rem Redistribution and use in source and binary forms, with or without +@rem modification, are permitted provided that the following conditions are +@rem met: +@rem +@rem * Redistributions of source code must retain the above copyright +@rem notice, this list of conditions and the following disclaimer. +@rem * Redistributions in binary form must reproduce the above +@rem copyright notice, this list of conditions and the following disclaimer +@rem in the documentation and/or other materials provided with the +@rem distribution. +@rem * Neither the name of Google Inc. nor the names of its +@rem contributors may be used to endorse or promote products derived from +@rem this software without specific prior written permission. +@rem +@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@rem Expire cache after 1 week +npm update --cache-min 604800 + +npm install node-gyp-install +.\node_modules\.bin\node-gyp-install.cmd + +@rem delete the redundant openssl headers +for /f "delims=v" %%v in ('node --version') do ( + rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\%%v\include\node\openssl" /S /Q +) \ No newline at end of file diff --git a/tools/run_tests/run_node.bat b/tools/run_tests/run_node.bat new file mode 100644 index 0000000000000000000000000000000000000000..f5cf01f0959844c06041468eeb57d3934fe9e7fe --- /dev/null +++ b/tools/run_tests/run_node.bat @@ -0,0 +1,32 @@ +@rem Copyright 2016, Google Inc. +@rem All rights reserved. +@rem +@rem Redistribution and use in source and binary forms, with or without +@rem modification, are permitted provided that the following conditions are +@rem met: +@rem +@rem * Redistributions of source code must retain the above copyright +@rem notice, this list of conditions and the following disclaimer. +@rem * Redistributions in binary form must reproduce the above +@rem copyright notice, this list of conditions and the following disclaimer +@rem in the documentation and/or other materials provided with the +@rem distribution. +@rem * Neither the name of Google Inc. nor the names of its +@rem contributors may be used to endorse or promote products derived from +@rem this software without specific prior written permission. +@rem +@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set JUNIT_REPORT_PATH=src\node\reports.xml +set JUNIT_REPORT_STACK=1 +.\node_modules\.bin\mocha.cmd --reporter mocha-jenkins-reporter src\node\test \ No newline at end of file diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index f40586644257b594901edef26c5162720d4cfe9c..de3716bc887e743c2fa42cbb751ee3c18a21e3f2 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -195,16 +195,22 @@ class CLanguage(object): class NodeLanguage(object): def __init__(self): + self.platform = platform_string() self.node_version = '0.12' def test_specs(self, config, args): - return [config.job_spec(['tools/run_tests/run_node.sh', self.node_version], - None, - environ=_FORCE_ENVIRON_FOR_WRAPPERS)] + if self.platform == 'windows': + return [config.job_spec(['tools\\run_tests\\run_node.bat'], None)] + else: + return [config.job_spec(['tools/run_tests/run_node.sh', self.node_version], + None, + environ=_FORCE_ENVIRON_FOR_WRAPPERS)] def pre_build_steps(self): - # Default to 1 week cache expiration - return [['tools/run_tests/pre_build_node.sh', self.node_version]] + if self.platform == 'windows': + return [['tools\\run_tests\\pre_build_node.bat']] + else: + return [['tools/run_tests/pre_build_node.sh', self.node_version]] def make_targets(self, test_regex): return [] @@ -213,7 +219,10 @@ class NodeLanguage(object): return [] def build_steps(self): - return [['tools/run_tests/build_node.sh', self.node_version]] + if self.platform == 'windows': + return [['tools\\run_tests\\build_node.bat']] + else: + return [['tools/run_tests/build_node.sh', self.node_version]] def post_tests_steps(self): return []