Chromium Code Reviews| Index: ppapi/nacl_irt/manifest_service.cc |
| diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc |
| index 85b7fae2c960c9ca5ca156abf3213b9deed1524a..e6d3c0ff0e290bb07f591f3734173fdec83a629d 100644 |
| --- a/ppapi/nacl_irt/manifest_service.cc |
| +++ b/ppapi/nacl_irt/manifest_service.cc |
| @@ -17,11 +17,54 @@ namespace ppapi { |
| const char kFilePrefix[] = "files/"; |
| +// IPC channel is asynchronously set up. So, the NaCl process may be try to |
| +// send a OpenResource message to the host before the connection is |
| +// established. In such a case, it is necessary to wait for the set up |
| +// completion. |
| +class ManifestMessageFilter : public IPC::SyncMessageFilter { |
| + public: |
| + ManifestMessageFilter(base::WaitableEvent* shutdown_event) |
| + : SyncMessageFilter(shutdown_event), |
| + connected_event_( |
| + true /* manual_reset */, false /* initially_signaled */) { |
| + } |
| + |
| + virtual bool Send(IPC::Message* message) OVERRIDE { |
| + // Wait until set up is actually done. |
| + connected_event_.Wait(); |
| + return SyncMessageFilter::Send(message); |
| + } |
| + |
| + // When set up is done, OnFilterAdded is called on IO thread. Unblocks the |
| + // Send(). |
| + virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE { |
|
hidehiko
2014/06/16 03:39:44
FYI: Rebasing needs to change the arg's type.
cf)
|
| + SyncMessageFilter::OnFilterAdded(sender); |
| + connected_event_.Signal(); |
| + } |
| + |
| + // If an error is found, unblocks the Send(), too, to return an error. |
| + virtual void OnChannelError() OVERRIDE { |
| + SyncMessageFilter::OnChannelError(); |
| + connected_event_.Signal(); |
| + } |
| + |
| + // Similar to OnChannelError, unblocks the Send() on the channel closing. |
| + virtual void OnChannelClosing() OVERRIDE { |
| + SyncMessageFilter::OnChannelClosing(); |
| + connected_event_.Signal(); |
| + } |
| + |
| + private: |
| + base::WaitableEvent connected_event_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ManifestMessageFilter); |
| +}; |
| + |
| ManifestService::ManifestService( |
| const IPC::ChannelHandle& handle, |
| scoped_refptr<base::MessageLoopProxy> io_message_loop, |
| base::WaitableEvent* shutdown_event) { |
| - filter_ = new IPC::SyncMessageFilter(shutdown_event); |
| + filter_ = new ManifestMessageFilter(shutdown_event); |
| channel_ = IPC::ChannelProxy::Create(handle, |
| IPC::Channel::MODE_SERVER, |
| NULL, // Listener |