summaryrefslogtreecommitdiffstats
path: root/ppapi/nacl_irt/manifest_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ppapi/nacl_irt/manifest_service.cc')
-rw-r--r--ppapi/nacl_irt/manifest_service.cc45
1 files changed, 44 insertions, 1 deletions
diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc
index 85b7fae..441c401 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