110 lines
3.3 KiB
C++
110 lines
3.3 KiB
C++
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
|
// reserved. Use of this source code is governed by a BSD-style license that
|
|
// can be found in the LICENSE file.
|
|
|
|
#ifndef CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
|
|
#define CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include "include/base/cef_callback.h"
|
|
#include "include/cef_task.h"
|
|
|
|
#if defined(OS_WIN)
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
namespace client {
|
|
|
|
// Represents the message loop running on the main application thread in the
|
|
// browser process. This will be the same as the CEF UI thread on Linux, OS X
|
|
// and Windows when not using multi-threaded message loop mode. The methods of
|
|
// this class are thread-safe unless otherwise indicated.
|
|
class MainMessageLoop {
|
|
public:
|
|
// Returns the singleton instance of this object.
|
|
static MainMessageLoop* Get();
|
|
|
|
// Run the message loop. The thread that this method is called on will be
|
|
// considered the main thread. This blocks until Quit() is called.
|
|
virtual int Run() = 0;
|
|
|
|
// Quit the message loop.
|
|
virtual void Quit() = 0;
|
|
|
|
// Post a task for execution on the main message loop.
|
|
virtual void PostTask(CefRefPtr<CefTask> task) = 0;
|
|
|
|
// Returns true if this message loop runs tasks on the current thread.
|
|
virtual bool RunsTasksOnCurrentThread() const = 0;
|
|
|
|
#if defined(OS_WIN)
|
|
// Set the current modeless dialog on Windows for proper delivery of dialog
|
|
// messages when using multi-threaded message loop mode. This method must be
|
|
// called from the main thread. See http://support.microsoft.com/kb/71450 for
|
|
// background.
|
|
virtual void SetCurrentModelessDialog(HWND hWndDialog) = 0;
|
|
#endif
|
|
|
|
// Post a closure for execution on the main message loop.
|
|
void PostClosure(base::OnceClosure closure);
|
|
void PostClosure(const base::RepeatingClosure& closure);
|
|
|
|
protected:
|
|
// Only allow deletion via std::unique_ptr.
|
|
friend std::default_delete<MainMessageLoop>;
|
|
|
|
MainMessageLoop();
|
|
virtual ~MainMessageLoop();
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(MainMessageLoop);
|
|
};
|
|
|
|
#define CURRENTLY_ON_MAIN_THREAD() \
|
|
client::MainMessageLoop::Get()->RunsTasksOnCurrentThread()
|
|
|
|
#define REQUIRE_MAIN_THREAD() DCHECK(CURRENTLY_ON_MAIN_THREAD())
|
|
|
|
#define MAIN_POST_TASK(task) client::MainMessageLoop::Get()->PostTask(task)
|
|
|
|
#define MAIN_POST_CLOSURE(closure) \
|
|
client::MainMessageLoop::Get()->PostClosure(closure)
|
|
|
|
// Use this struct in conjuction with RefCountedThreadSafe to ensure that an
|
|
// object is deleted on the main thread. For example:
|
|
//
|
|
// class Foo : public base::RefCountedThreadSafe<Foo, DeleteOnMainThread> {
|
|
// public:
|
|
// Foo();
|
|
// void DoSomething();
|
|
//
|
|
// private:
|
|
// // Allow deletion via scoped_refptr only.
|
|
// friend struct DeleteOnMainThread;
|
|
// friend class base::RefCountedThreadSafe<Foo, DeleteOnMainThread>;
|
|
//
|
|
// virtual ~Foo() {}
|
|
// };
|
|
//
|
|
// base::scoped_refptr<Foo> foo = new Foo();
|
|
// foo->DoSomething();
|
|
// foo = nullptr; // Deletion of |foo| will occur on the main thread.
|
|
//
|
|
struct DeleteOnMainThread {
|
|
template <typename T>
|
|
static void Destruct(const T* x) {
|
|
if (CURRENTLY_ON_MAIN_THREAD()) {
|
|
delete x;
|
|
} else {
|
|
client::MainMessageLoop::Get()->PostClosure(base::BindOnce(
|
|
&DeleteOnMainThread::Destruct<T>, base::Unretained(x)));
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace client
|
|
|
|
#endif // CEF_TESTS_SHARED_BROWSER_MAIN_MESSAGE_LOOP_H_
|