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