1// Copyright 2013 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 PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_
6#define PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_
7
8#include <map>
9#include <set>
10
11#include "base/basictypes.h"
12#include "base/memory/ref_counted.h"
13#include "base/synchronization/lock.h"
14#include "ppapi/c/pp_resource.h"
15#include "ppapi/proxy/ppapi_proxy_export.h"
16
17
18namespace base {
19class MessageLoopProxy;
20}
21
22namespace IPC {
23class Message;
24}
25
26namespace ppapi {
27
28class TrackedCallback;
29
30namespace proxy {
31
32class ResourceMessageReplyParams;
33
34// ResourceReplyThreadRegistrar records the handling thread for
35// PpapiPluginMsg_ResourceReply messages.
36// This class is thread safe.
37class PPAPI_PROXY_EXPORT ResourceReplyThreadRegistrar
38    : public base::RefCountedThreadSafe<ResourceReplyThreadRegistrar> {
39 public:
40  explicit ResourceReplyThreadRegistrar(
41      scoped_refptr<base::MessageLoopProxy> main_thread);
42
43  // This method can only be called while holding the Pepper proxy lock; the
44  // other methods can be called with/without the Pepper proxy lock.
45  void Register(PP_Resource resource,
46                int32_t sequence_number,
47                scoped_refptr<TrackedCallback> reply_thread_hint);
48  void Unregister(PP_Resource resource);
49
50  // This results in Resource::OnReplyReceived() for the specified message type
51  // to be called on the IO thread directly, while holding the Pepper proxy
52  // lock.
53  void HandleOnIOThread(uint32 nested_msg_type);
54
55  // This method returns NULL if the target thread is the IO thread (because
56  // that is the thread on which this method is supposed to be called).
57  scoped_refptr<base::MessageLoopProxy> GetTargetThread(
58      const ResourceMessageReplyParams& reply_params,
59      const IPC::Message& nested_msg);
60
61 private:
62  friend class base::RefCountedThreadSafe<ResourceReplyThreadRegistrar>;
63
64  typedef std::map<int32_t, scoped_refptr<base::MessageLoopProxy> >
65      SequenceThreadMap;
66  typedef std::map<PP_Resource, SequenceThreadMap> ResourceMap;
67
68  ~ResourceReplyThreadRegistrar();
69
70  // The lock that protects the data members below.
71  // Please note that we should never try to acquire the Pepper proxy lock while
72  // holding |lock_|, otherwise we will cause deadlock.
73  base::Lock lock_;
74  ResourceMap map_;
75  std::set<uint32> io_thread_message_types_;
76  scoped_refptr<base::MessageLoopProxy> main_thread_;
77
78  DISALLOW_COPY_AND_ASSIGN(ResourceReplyThreadRegistrar);
79};
80
81}  // namespace proxy
82}  // namespace ppapi
83
84#endif   // PPAPI_PROXY_RESOURCE_REPLY_THREAD_REGISTRAR_H_
85