• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #ifndef CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
6 #define CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
7 #pragma once
8 
9 #include "include/base/cef_bind.h"
10 #include "include/base/cef_scoped_ptr.h"
11 #include "include/cef_task.h"
12 
13 #if defined(OS_WIN)
14 #include <windows.h>
15 #endif
16 
17 namespace client {
18 
19 // Represents the message loop running on the main application thread in the
20 // browser process. This will be the same as the CEF UI thread on Linux, OS X
21 // and Windows when not using multi-threaded message loop mode. The methods of
22 // this class are thread-safe unless otherwise indicated.
23 class MainMessageLoop {
24  public:
25   // Returns the singleton instance of this object.
26   static MainMessageLoop* Get();
27 
28   // Run the message loop. The thread that this method is called on will be
29   // considered the main thread. This blocks until Quit() is called.
30   virtual int Run() = 0;
31 
32   // Quit the message loop.
33   virtual void Quit() = 0;
34 
35   // Post a task for execution on the main message loop.
36   virtual void PostTask(CefRefPtr<CefTask> task) = 0;
37 
38   // Returns true if this message loop runs tasks on the current thread.
39   virtual bool RunsTasksOnCurrentThread() const = 0;
40 
41 #if defined(OS_WIN)
42   // Set the current modeless dialog on Windows for proper delivery of dialog
43   // messages when using multi-threaded message loop mode. This method must be
44   // called from the main thread. See http://support.microsoft.com/kb/71450 for
45   // background.
46   virtual void SetCurrentModelessDialog(HWND hWndDialog) = 0;
47 #endif
48 
49   // Post a closure for execution on the main message loop.
50   void PostClosure(const base::Closure& closure);
51 
52  protected:
53   // Only allow deletion via scoped_ptr.
54   friend struct base::DefaultDeleter<MainMessageLoop>;
55 
56   MainMessageLoop();
57   virtual ~MainMessageLoop();
58 
59  private:
60   DISALLOW_COPY_AND_ASSIGN(MainMessageLoop);
61 };
62 
63 #define CURRENTLY_ON_MAIN_THREAD() \
64   client::MainMessageLoop::Get()->RunsTasksOnCurrentThread()
65 
66 #define REQUIRE_MAIN_THREAD() DCHECK(CURRENTLY_ON_MAIN_THREAD())
67 
68 #define MAIN_POST_TASK(task) client::MainMessageLoop::Get()->PostTask(task)
69 
70 #define MAIN_POST_CLOSURE(closure) \
71   client::MainMessageLoop::Get()->PostClosure(closure)
72 
73 // Use this struct in conjuction with RefCountedThreadSafe to ensure that an
74 // object is deleted on the main thread. For example:
75 //
76 // class Foo : public base::RefCountedThreadSafe<Foo, DeleteOnMainThread> {
77 //  public:
78 //   Foo();
79 //   void DoSomething();
80 //
81 //  private:
82 //   // Allow deletion via scoped_refptr only.
83 //   friend struct DeleteOnMainThread;
84 //   friend class base::RefCountedThreadSafe<Foo, DeleteOnMainThread>;
85 //
86 //   virtual ~Foo() {}
87 // };
88 //
89 // base::scoped_refptr<Foo> foo = new Foo();
90 // foo->DoSomething();
91 // foo = nullptr;  // Deletion of |foo| will occur on the main thread.
92 //
93 struct DeleteOnMainThread {
94   template <typename T>
95   static void Destruct(const T* x) {
96     if (CURRENTLY_ON_MAIN_THREAD()) {
97       delete x;
98     } else {
99       client::MainMessageLoop::Get()->PostClosure(
100           base::Bind(&DeleteOnMainThread::Destruct<T>, x));
101     }
102   }
103 };
104 
105 }  // namespace client
106 
107 #endif  // CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
108