|  | @@ -34,6 +34,9 @@
 | 
	
		
			
				|  |  |  #ifndef __GRPCPP_STREAM_H__
 | 
	
		
			
				|  |  |  #define __GRPCPP_STREAM_H__
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#include <grpc++/call.h>
 | 
	
		
			
				|  |  | +#include <grpc++/channel_interface.h>
 | 
	
		
			
				|  |  | +#include <grpc++/completion_queue.h>
 | 
	
		
			
				|  |  |  #include <grpc++/stream_context_interface.h>
 | 
	
		
			
				|  |  |  #include <grpc++/status.h>
 | 
	
		
			
				|  |  |  #include <grpc/support/log.h>
 | 
	
	
		
			
				|  | @@ -45,16 +48,12 @@ class ClientStreamingInterface {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    virtual ~ClientStreamingInterface() {}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Try to cancel the stream. Wait() still needs to be called to get the final
 | 
	
		
			
				|  |  | -  // status. Cancelling after the stream has finished has no effects.
 | 
	
		
			
				|  |  | -  virtual void Cancel() = 0;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    // Wait until the stream finishes, and return the final status. When the
 | 
	
		
			
				|  |  |    // client side declares it has no more message to send, either implicitly or
 | 
	
		
			
				|  |  |    // by calling WritesDone, it needs to make sure there is no more message to
 | 
	
		
			
				|  |  |    // be received from the server, either implicitly or by getting a false from
 | 
	
		
			
				|  |  |    // a Read(). Otherwise, this implicitly cancels the stream.
 | 
	
		
			
				|  |  | -  virtual const Status& Wait() = 0;
 | 
	
		
			
				|  |  | +  virtual Status Finish() = 0;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // An interface that yields a sequence of R messages.
 | 
	
	
		
			
				|  | @@ -82,95 +81,127 @@ class WriterInterface {
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <class R>
 | 
	
		
			
				|  |  | -class ClientReader : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | -                     public ReaderInterface<R> {
 | 
	
		
			
				|  |  | +class ClientReader final : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | +                           public ReaderInterface<R> {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    // Blocking create a stream and write the first request out.
 | 
	
		
			
				|  |  | -  explicit ClientReader(StreamContextInterface* context) : context_(context) {
 | 
	
		
			
				|  |  | -    GPR_ASSERT(context_);
 | 
	
		
			
				|  |  | -    context_->Start(true);
 | 
	
		
			
				|  |  | -    context_->Write(context_->request(), true);
 | 
	
		
			
				|  |  | +  explicit ClientReader(ChannelInterface *channel, const RpcMethod &method,
 | 
	
		
			
				|  |  | +                        ClientContext *context,
 | 
	
		
			
				|  |  | +                        const google::protobuf::Message &request)
 | 
	
		
			
				|  |  | +      : call_(channel->CreateCall(method, context, &cq_), channel) {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddSendMessage(request);
 | 
	
		
			
				|  |  | +    buf.AddClientSendClose();
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)1);
 | 
	
		
			
				|  |  | +    cq_.Pluck((void *)1);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  ~ClientReader() { delete context_; }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  virtual bool Read(R* msg) { return context_->Read(msg); }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  virtual void Cancel() { context_->Cancel(); }
 | 
	
		
			
				|  |  | +  virtual bool Read(R *msg) {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddRecvMessage(msg);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)2);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)2);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  virtual const Status& Wait() { return context_->Wait(); }
 | 
	
		
			
				|  |  | +  virtual Status Finish() override {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    Status status;
 | 
	
		
			
				|  |  | +    buf.AddClientRecvStatus(&status);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)3);
 | 
	
		
			
				|  |  | +    GPR_ASSERT(cq_.Pluck((void *)3));
 | 
	
		
			
				|  |  | +    return status;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |   private:
 | 
	
		
			
				|  |  | -  StreamContextInterface* const context_;
 | 
	
		
			
				|  |  | +  CompletionQueue cq_;
 | 
	
		
			
				|  |  | +  Call call_;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <class W>
 | 
	
		
			
				|  |  | -class ClientWriter : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | -                     public WriterInterface<W> {
 | 
	
		
			
				|  |  | +class ClientWriter final : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | +                           public WriterInterface<W> {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    // Blocking create a stream.
 | 
	
		
			
				|  |  | -  explicit ClientWriter(StreamContextInterface* context) : context_(context) {
 | 
	
		
			
				|  |  | -    GPR_ASSERT(context_);
 | 
	
		
			
				|  |  | -    context_->Start(false);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  ~ClientWriter() { delete context_; }
 | 
	
		
			
				|  |  | +  explicit ClientWriter(ChannelInterface *channel, const RpcMethod &method,
 | 
	
		
			
				|  |  | +                        ClientContext *context,
 | 
	
		
			
				|  |  | +                        google::protobuf::Message *response)
 | 
	
		
			
				|  |  | +      : response_(response),
 | 
	
		
			
				|  |  | +        call_(channel->CreateCall(method, context, &cq_), channel) {}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    virtual bool Write(const W& msg) {
 | 
	
		
			
				|  |  | -    return context_->Write(const_cast<W*>(&msg), false);
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddSendMessage(msg);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)2);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)2);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  virtual void WritesDone() { context_->Write(nullptr, true); }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  virtual void Cancel() { context_->Cancel(); }
 | 
	
		
			
				|  |  | +  virtual bool WritesDone() {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddClientSendClose();
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)3);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)3);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Read the final response and wait for the final status.
 | 
	
		
			
				|  |  | -  virtual const Status& Wait() {
 | 
	
		
			
				|  |  | -    bool success = context_->Read(context_->response());
 | 
	
		
			
				|  |  | -    if (!success) {
 | 
	
		
			
				|  |  | -      Cancel();
 | 
	
		
			
				|  |  | -    } else {
 | 
	
		
			
				|  |  | -      success = context_->Read(nullptr);
 | 
	
		
			
				|  |  | -      if (success) {
 | 
	
		
			
				|  |  | -        Cancel();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    return context_->Wait();
 | 
	
		
			
				|  |  | +  virtual Status Finish() override {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    Status status;
 | 
	
		
			
				|  |  | +    buf.AddClientRecvStatus(&status);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)4);
 | 
	
		
			
				|  |  | +    GPR_ASSERT(cq_.Pluck((void *)4));
 | 
	
		
			
				|  |  | +    return status;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |   private:
 | 
	
		
			
				|  |  | -  StreamContextInterface* const context_;
 | 
	
		
			
				|  |  | +  google::protobuf::Message *const response_;
 | 
	
		
			
				|  |  | +  CompletionQueue cq_;
 | 
	
		
			
				|  |  | +  Call call_;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Client-side interface for bi-directional streaming.
 | 
	
		
			
				|  |  |  template <class W, class R>
 | 
	
		
			
				|  |  | -class ClientReaderWriter : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | -                           public WriterInterface<W>,
 | 
	
		
			
				|  |  | -                           public ReaderInterface<R> {
 | 
	
		
			
				|  |  | +class ClientReaderWriter final : public ClientStreamingInterface,
 | 
	
		
			
				|  |  | +                                 public WriterInterface<W>,
 | 
	
		
			
				|  |  | +                                 public ReaderInterface<R> {
 | 
	
		
			
				|  |  |   public:
 | 
	
		
			
				|  |  |    // Blocking create a stream.
 | 
	
		
			
				|  |  | -  explicit ClientReaderWriter(StreamContextInterface* context)
 | 
	
		
			
				|  |  | -      : context_(context) {
 | 
	
		
			
				|  |  | -    GPR_ASSERT(context_);
 | 
	
		
			
				|  |  | -    context_->Start(false);
 | 
	
		
			
				|  |  | +  explicit ClientReaderWriter(ChannelInterface *channel,
 | 
	
		
			
				|  |  | +                              const RpcMethod &method, ClientContext *context)
 | 
	
		
			
				|  |  | +      : call_(channel->CreateCall(method, context, &cq_), channel) {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  virtual bool Read(R *msg) {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddRecvMessage(msg);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)2);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)2);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  ~ClientReaderWriter() { delete context_; }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  virtual bool Read(R* msg) { return context_->Read(msg); }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    virtual bool Write(const W& msg) {
 | 
	
		
			
				|  |  | -    return context_->Write(const_cast<W*>(&msg), false);
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddSendMessage(msg);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)3);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)3);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  virtual void WritesDone() { context_->Write(nullptr, true); }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  virtual void Cancel() { context_->Cancel(); }
 | 
	
		
			
				|  |  | +  virtual bool WritesDone() {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    buf.AddClientSendClose();
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)4);
 | 
	
		
			
				|  |  | +    return cq_.Pluck((void *)4);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  virtual const Status& Wait() { return context_->Wait(); }
 | 
	
		
			
				|  |  | +  virtual Status Finish() override {
 | 
	
		
			
				|  |  | +    CallOpBuffer buf;
 | 
	
		
			
				|  |  | +    Status status;
 | 
	
		
			
				|  |  | +    buf.AddClientRecvStatus(&status);
 | 
	
		
			
				|  |  | +    call_.PerformOps(buf, (void *)5);
 | 
	
		
			
				|  |  | +    GPR_ASSERT(cq_.Pluck((void *)5));
 | 
	
		
			
				|  |  | +    return status;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |   private:
 | 
	
		
			
				|  |  | -  StreamContextInterface* const context_;
 | 
	
		
			
				|  |  | +  CompletionQueue cq_;
 | 
	
		
			
				|  |  | +  Call call_;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  template <class R>
 |