1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef IPC_IPC_MESSAGE_PIPE_READER_H_
6#define IPC_IPC_MESSAGE_PIPE_READER_H_
7
8#include <vector>
9
10#include "base/memory/scoped_ptr.h"
11#include "mojo/public/c/environment/async_waiter.h"
12#include "mojo/public/cpp/system/core.h"
13
14namespace IPC {
15namespace internal {
16
17// A helper class to handle bytestream directly over mojo::MessagePipe
18// in template-method pattern. MessagePipeReader manages the lifetime
19// of given MessagePipe and participates the event loop, and
20// read the stream and call the client when it is ready.
21//
22// Each client has to:
23//
24//  * Provide a subclass implemenation of a specific use of a MessagePipe
25//    and implement callbacks.
26//  * Create the subclass instance with a MessagePipeHandle.
27//    The constructor automatically start listening on the pipe.
28//
29// MessageReader has to be used in IO thread. It isn't thread-safe.
30//
31class MessagePipeReader {
32 public:
33  // Delay the object deletion using the current message loop.
34  // This is intended to used by MessagePipeReader owners.
35  class DelayedDeleter {
36   public:
37    typedef base::DefaultDeleter<MessagePipeReader> DefaultType;
38
39    static void DeleteNow(MessagePipeReader* ptr) { delete ptr; }
40
41    DelayedDeleter() {}
42    DelayedDeleter(const DefaultType&) {}
43    DelayedDeleter& operator=(const DefaultType&) { return *this; }
44
45    void operator()(MessagePipeReader* ptr) const;
46  };
47
48  explicit MessagePipeReader(mojo::ScopedMessagePipeHandle handle);
49  virtual ~MessagePipeReader();
50
51  MojoHandle handle() const { return pipe_.get().value(); }
52
53  // Returns received bytes.
54  const std::vector<char>& data_buffer() const {
55    return data_buffer_;
56  }
57
58  // Delegate received handles ownership. The subclass should take the
59  // ownership over in its OnMessageReceived(). They will leak otherwise.
60  void TakeHandleBuffer(std::vector<MojoHandle>* handle_buffer) {
61    handle_buffer_.swap(*handle_buffer);
62  }
63
64  // Close and destroy the MessagePipe.
65  void Close();
66  // Close the mesage pipe with notifying the client with the error.
67  void CloseWithError(MojoResult error);
68  // Return true if the MessagePipe is alive.
69  bool IsValid() { return pipe_.is_valid(); }
70
71  //
72  // The client have to implment these callback to get the readiness
73  // event from the reader
74  //
75  virtual void OnMessageReceived() = 0;
76  virtual void OnPipeClosed() = 0;
77  virtual void OnPipeError(MojoResult error) = 0;
78
79 private:
80  static void InvokePipeIsReady(void* closure, MojoResult result);
81
82  MojoResult ReadMessageBytes();
83  void PipeIsReady(MojoResult wait_result);
84  void StartWaiting();
85  void StopWaiting();
86
87  std::vector<char>  data_buffer_;
88  std::vector<MojoHandle> handle_buffer_;
89  MojoAsyncWaitID pipe_wait_id_;
90  mojo::ScopedMessagePipeHandle pipe_;
91
92  DISALLOW_COPY_AND_ASSIGN(MessagePipeReader);
93};
94
95}  // namespace internal
96}  // namespace IPC
97
98#endif  // IPC_IPC_MESSAGE_PIPE_READER_H_
99