Home | History | Annotate | Download | only in glue
      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/webrtc/base/thread.h"
     16 
     17 namespace jingle_glue {
     18 
     19 // JingleThreadWrapper implements rtc::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 rtc::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.
     52   void set_send_allowed(bool allowed) { send_allowed_ = allowed; }
     53 
     54   // MessageLoop::DestructionObserver implementation.
     55   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
     56 
     57   // rtc::MessageQueue overrides.
     58   virtual void Post(rtc::MessageHandler *phandler,
     59                     uint32 id,
     60                     rtc::MessageData *pdata,
     61                     bool time_sensitive) OVERRIDE;
     62   virtual void PostDelayed(int delay_ms,
     63                            rtc::MessageHandler* handler,
     64                            uint32 id,
     65                            rtc::MessageData* data) OVERRIDE;
     66   virtual void Clear(rtc::MessageHandler* handler,
     67                      uint32 id,
     68                      rtc::MessageList* removed) OVERRIDE;
     69   virtual void Send(rtc::MessageHandler *handler,
     70                     uint32 id,
     71                     rtc::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(rtc::Message* message,
     81                    int delay_ms,
     82                    bool process_io) OVERRIDE;
     83   virtual bool Peek(rtc::Message* message,
     84                     int delay_ms) OVERRIDE;
     85   virtual void PostAt(uint32 timestamp,
     86                       rtc::MessageHandler* handler,
     87                       uint32 id,
     88                       rtc::MessageData* data) OVERRIDE;
     89   virtual void Dispatch(rtc::Message* message) OVERRIDE;
     90   virtual void ReceiveSends() OVERRIDE;
     91   virtual int GetDelay() OVERRIDE;
     92 
     93   // rtc::Thread overrides.
     94   virtual void Stop() OVERRIDE;
     95   virtual void Run() OVERRIDE;
     96 
     97  private:
     98   typedef std::map<int, rtc::Message> MessagesQueue;
     99   struct PendingSend;
    100 
    101   void PostTaskInternal(
    102       int delay_ms, rtc::MessageHandler* handler,
    103       uint32 message_id, rtc::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