• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 JINGLE_GLUE_THREAD_WRAPPER_H_
6 #define JINGLE_GLUE_THREAD_WRAPPER_H_
7 
8 #include <list>
9 #include <map>
10 
11 #include "base/compiler_specific.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/synchronization/lock.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "third_party/libjingle/source/talk/base/thread.h"
16 
17 namespace jingle_glue {
18 
19 // JingleThreadWrapper implements talk_base::Thread interface on top of
20 // Chromium's SingleThreadTaskRunner interface. Currently only the bare minimum
21 // that is used by P2P part of libjingle is implemented. There are two ways to
22 // create this object:
23 //
24 // - Call EnsureForCurrentMessageLoop(). This approach works only on threads
25 //   that have MessageLoop In this case JingleThreadWrapper deletes itself
26 //   automatically when MessageLoop is destroyed.
27 // - Using JingleThreadWrapper() constructor. In this case the creating code
28 //   must pass a valid task runner for the current thread and also delete the
29 //   wrapper later.
30 class JingleThreadWrapper : public base::MessageLoop::DestructionObserver,
31                             public talk_base::Thread {
32  public:
33   // Create JingleThreadWrapper for the current thread if it hasn't been created
34   // yet. The thread wrapper is destroyed automatically when the current
35   // MessageLoop is destroyed.
36   static void EnsureForCurrentMessageLoop();
37 
38   // Returns thread wrapper for the current thread. NULL is returned
39   // if EnsureForCurrentMessageLoop() has never been called for this
40   // thread.
41   static JingleThreadWrapper* current();
42 
43   explicit JingleThreadWrapper(
44      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
45   virtual ~JingleThreadWrapper();
46 
47   // Sets whether the thread can be used to send messages
48   // synchronously to another thread using Send() method. Set to false
49   // by default to avoid potential jankiness when Send() used on
50   // renderer thread. It should be set explicitly for threads that
51   // need to call Send() for other threads.
set_send_allowed(bool allowed)52   void set_send_allowed(bool allowed) { send_allowed_ = allowed; }
53 
54   // MessageLoop::DestructionObserver implementation.
55   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
56 
57   // talk_base::MessageQueue overrides.
58   virtual void Post(talk_base::MessageHandler *phandler,
59                     uint32 id,
60                     talk_base::MessageData *pdata,
61                     bool time_sensitive) OVERRIDE;
62   virtual void PostDelayed(int delay_ms,
63                            talk_base::MessageHandler* handler,
64                            uint32 id,
65                            talk_base::MessageData* data) OVERRIDE;
66   virtual void Clear(talk_base::MessageHandler* handler,
67                      uint32 id,
68                      talk_base::MessageList* removed) OVERRIDE;
69   virtual void Send(talk_base::MessageHandler *handler,
70                     uint32 id,
71                     talk_base::MessageData *data) OVERRIDE;
72 
73   // Following methods are not supported.They are overriden just to
74   // ensure that they are not called (each of them contain NOTREACHED
75   // in the body). Some of this methods can be implemented if it
76   // becomes neccessary to use libjingle code that calls them.
77   virtual void Quit() OVERRIDE;
78   virtual bool IsQuitting() OVERRIDE;
79   virtual void Restart() OVERRIDE;
80   virtual bool Get(talk_base::Message* message,
81                    int delay_ms,
82                    bool process_io) OVERRIDE;
83   virtual bool Peek(talk_base::Message* message,
84                     int delay_ms) OVERRIDE;
85   virtual void PostAt(uint32 timestamp,
86                       talk_base::MessageHandler* handler,
87                       uint32 id,
88                       talk_base::MessageData* data) OVERRIDE;
89   virtual void Dispatch(talk_base::Message* message) OVERRIDE;
90   virtual void ReceiveSends() OVERRIDE;
91   virtual int GetDelay() OVERRIDE;
92 
93   // talk_base::Thread overrides.
94   virtual void Stop() OVERRIDE;
95   virtual void Run() OVERRIDE;
96 
97  private:
98   typedef std::map<int, talk_base::Message> MessagesQueue;
99   struct PendingSend;
100 
101   void PostTaskInternal(
102       int delay_ms, talk_base::MessageHandler* handler,
103       uint32 message_id, talk_base::MessageData* data);
104   void RunTask(int task_id);
105   void ProcessPendingSends();
106 
107   // Task runner used to execute messages posted on this thread.
108   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
109 
110   bool send_allowed_;
111 
112   // |lock_| must be locked when accessing |messages_|.
113   base::Lock lock_;
114   int last_task_id_;
115   MessagesQueue messages_;
116   std::list<PendingSend*> pending_send_messages_;
117   base::WaitableEvent pending_send_event_;
118 
119   base::WeakPtr<JingleThreadWrapper> weak_ptr_;
120   base::WeakPtrFactory<JingleThreadWrapper> weak_ptr_factory_;
121 
122   DISALLOW_COPY_AND_ASSIGN(JingleThreadWrapper);
123 };
124 
125 }  // namespace jingle_glue
126 
127 #endif  // JINGLE_GLUE_THREAD_WRAPPER_H_
128