121 lines
3.6 KiB
C
121 lines
3.6 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_CEFCLIENT_MAIN_MESSAGE_LOOP_H_
|
||
|
#define CEF_TESTS_CEFCLIENT_MAIN_MESSAGE_LOOP_H_
|
||
|
|
||
|
#include "include/base/cef_bind.h"
|
||
|
#include "include/base/cef_scoped_ptr.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(const base::Closure& closure);
|
||
|
|
||
|
// Used in combination with DeleteOnMainThread to delete |object| on the
|
||
|
// correct thread.
|
||
|
template<class T>
|
||
|
void DeleteSoon(const T* object) {
|
||
|
// Execute DeleteHelper on the main thread.
|
||
|
PostClosure(base::Bind(&MainMessageLoop::DeleteHelper, object));
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
// Only allow deletion via scoped_ptr.
|
||
|
friend struct base::DefaultDeleter<MainMessageLoop>;
|
||
|
|
||
|
MainMessageLoop();
|
||
|
virtual ~MainMessageLoop();
|
||
|
|
||
|
private:
|
||
|
// Helper for deleting |object|.
|
||
|
template<class T>
|
||
|
static void DeleteHelper(const T* object) {
|
||
|
delete object;
|
||
|
}
|
||
|
|
||
|
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 = NULL; // 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()->DeleteSoon(x);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace client
|
||
|
|
||
|
#endif // CEF_TESTS_CEFCLIENT_MAIN_MESSAGE_LOOP_H_
|