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