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.
5 #ifndef IPC_IPC_MESSAGE_PIPE_READER_H_
6 #define IPC_IPC_MESSAGE_PIPE_READER_H_
10 #include "base/atomicops.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/threading/thread_checker.h"
14 #include "ipc/ipc_message.h"
15 #include "third_party/mojo/src/mojo/public/c/environment/async_waiter.h"
16 #include "third_party/mojo/src/mojo/public/cpp/system/core.h"
21 class AsyncHandleWaiter
;
23 // A helper class to handle bytestream directly over mojo::MessagePipe
24 // in template-method pattern. MessagePipeReader manages the lifetime
25 // of given MessagePipe and participates the event loop, and
26 // read the stream and call the client when it is ready.
28 // Each client has to:
30 // * Provide a subclass implemenation of a specific use of a MessagePipe
31 // and implement callbacks.
32 // * Create the subclass instance with a MessagePipeHandle.
33 // The constructor automatically start listening on the pipe.
35 // All functions must be called on the IO thread, except for Send(), which can
36 // be called on any thread. All |Delegate| functions will be called on the IO
39 class MessagePipeReader
{
43 virtual void OnMessageReceived(Message
& message
) = 0;
44 virtual void OnPipeClosed(MessagePipeReader
* reader
) = 0;
45 virtual void OnPipeError(MessagePipeReader
* reader
) = 0;
48 // Delay the object deletion using the current message loop.
49 // This is intended to used by MessagePipeReader owners.
50 class DelayedDeleter
{
52 typedef base::DefaultDeleter
<MessagePipeReader
> DefaultType
;
54 static void DeleteNow(MessagePipeReader
* ptr
) { delete ptr
; }
57 explicit DelayedDeleter(const DefaultType
&) {}
58 DelayedDeleter
& operator=(const DefaultType
&) { return *this; }
60 void operator()(MessagePipeReader
* ptr
) const;
63 // Both parameters must be non-null.
64 // Build a reader that reads messages from |handle| and lets |delegate| know.
65 // Note that MessagePipeReader doesn't delete |delete|.
66 MessagePipeReader(mojo::ScopedMessagePipeHandle handle
, Delegate
* delegate
);
67 virtual ~MessagePipeReader();
69 MojoHandle
handle() const { return handle_copy_
; }
71 // Returns received bytes.
72 const std::vector
<char>& data_buffer() const {
76 // Delegate received handles ownership. The subclass should take the
77 // ownership over in its OnMessageReceived(). They will leak otherwise.
78 void TakeHandleBuffer(std::vector
<MojoHandle
>* handle_buffer
) {
79 handle_buffer_
.swap(*handle_buffer
);
82 // Close and destroy the MessagePipe.
84 // Close the mesage pipe with notifying the client with the error.
85 void CloseWithError(MojoResult error
);
86 void CloseWithErrorLater(MojoResult error
);
87 void CloseWithErrorIfPending();
89 // Return true if the MessagePipe is alive.
90 bool IsValid() { return pipe_
.is_valid(); }
92 bool Send(scoped_ptr
<Message
> message
);
93 void ReadMessagesThenWait();
96 void OnMessageReceived();
98 void OnPipeError(MojoResult error
);
100 MojoResult
ReadMessageBytes();
101 void PipeIsReady(MojoResult wait_result
);
102 void ReadAvailableMessages();
104 std::vector
<char> data_buffer_
;
105 std::vector
<MojoHandle
> handle_buffer_
;
106 mojo::ScopedMessagePipeHandle pipe_
;
107 // Constant copy of the message pipe handle. For use by Send(), which can run
108 // concurrently on non-IO threads.
109 // TODO(amistry): This isn't quite right because handles can be re-used and
110 // using this can run into the ABA problem. Currently, this is highly unlikely
111 // because Mojo internally uses an increasing uint32_t as handle values, but
112 // this could change. See crbug.com/524894.
113 const MojoHandle handle_copy_
;
114 // |delegate_| and |async_waiter_| are null once the message pipe is closed.
116 scoped_ptr
<AsyncHandleWaiter
> async_waiter_
;
117 base::subtle::Atomic32 pending_send_error_
;
118 base::ThreadChecker thread_checker_
;
120 DISALLOW_COPY_AND_ASSIGN(MessagePipeReader
);
123 } // namespace internal
126 #endif // IPC_IPC_MESSAGE_PIPE_READER_H_