| 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..441c401e92381ff529b53325452992a50709fef4 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 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 {
|
| + 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
|
|
|