I find that if I call `grpc_call_start_batch` with an empty batch of grpc_op,
then it will kick its completion queue immediately[1] and the call to
`grpc_call_start_batch` becomes thread-safe[2] because it does not contain any
send operations or receive operations.
Does it well-document or undefined behavior to start an empty batch?
I am working on grpc-rs[3], a rust implementation, and trying to replace alarms
with calls to kick completion queues.
1: Code about an empty batch,
2: Quote from grpc.h:
/** Start a batch of operations defined in the array ops; when complete, post a
completion of type 'tag' to the completion queue bound to the call.
The order of ops specified in the batch has no significance.
Only one operation of each type can be active at once in any given
batch.
If a call to grpc_call_start_batch returns GRPC_CALL_OK you must call
grpc_completion_queue_next or grpc_completion_queue_pluck on the completion
queue associated with 'call' for work to be performed. If a call to
grpc_call_start_batch returns any value other than GRPC_CALL_OK it is
guaranteed that no state associated with 'call' is changed and it is not
appropriate to call grpc_completion_queue_next or
grpc_completion_queue_pluck consequent to the failed grpc_call_start_batch
call.
THREAD SAFETY: access to grpc_call_start_batch in multi-threaded environment
needs to be synchronized. As an optimization, you may synchronize batches
containing just send operations independently from batches containing just
receive operations. */
GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call* call,
const grpc_op* ops, size_t nops,
void* tag, void* reserved);