提交 772a0db5 编写于 作者: M Michael Goderbauer 提交者: GitHub

Partially port FML to Windows. (#3562)

* Partially port FML to Windows.

* Adds a message loop impl for Windows
* Ports `thread.cc` to Windows

All FML unittests are now passing on Windows.

FML as a whole does not compile on windows yet because `mapping.cc` imports `sys/mman.h`, which is not available on Windows and the replacement API for memory-mapped files is very different on Windows, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa366556%28v=vs.85%29.aspx.

* update licenses

* review comments
上级 5d9a6422
......@@ -90,6 +90,13 @@ source_set("fml") {
"platform/linux/timerfd.h",
]
}
if (is_win) {
sources += [
"platform/win/message_loop_win.cc",
"platform/win/message_loop_win.h",
]
}
}
executable("fml_unittests") {
......
......@@ -25,6 +25,11 @@ using PlatformMessageLoopImpl = fml::MessageLoopAndroid;
#include "flutter/fml/platform/linux/message_loop_linux.h"
using PlatformMessageLoopImpl = fml::MessageLoopLinux;
#elif OS_WIN
#include "flutter/fml/platform/win/message_loop_win.h"
using PlatformMessageLoopImpl = fml::MessageLoopWin;
#else
#error This platform does not have a message loop implementation.
......
......@@ -193,7 +193,7 @@ TEST(MessageLoop, TIME_SENSITIVE(MultipleDelayedTasksWithIncreasingDeltas)) {
for (int target_ms = 0 + 2; target_ms < count + 2; target_ms++) {
auto begin = ftl::TimePoint::Now();
loop.GetTaskRunner()->PostDelayedTask(
[begin, target_ms, &checked]() {
[begin, target_ms, &checked, count]() {
auto delta = ftl::TimePoint::Now() - begin;
auto ms = delta.ToMillisecondsF();
ASSERT_GE(ms, target_ms - 2);
......@@ -217,10 +217,10 @@ TEST(MessageLoop, TIME_SENSITIVE(MultipleDelayedTasksWithDecreasingDeltas)) {
std::thread thread([&checked, count]() {
fml::MessageLoop::EnsureInitializedForCurrentThread();
auto& loop = fml::MessageLoop::GetCurrent();
for (int target_ms = count + 2; target_ms >= 0 + 2; target_ms--) {
for (int target_ms = count + 2; target_ms > 0 + 2; target_ms--) {
auto begin = ftl::TimePoint::Now();
loop.GetTaskRunner()->PostDelayedTask(
[begin, target_ms, &checked]() {
[begin, target_ms, &checked, count]() {
auto delta = ftl::TimePoint::Now() - begin;
auto ms = delta.ToMillisecondsF();
ASSERT_GE(ms, target_ms - 2);
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/fml/platform/win/message_loop_win.h"
namespace fml {
MessageLoopWin::MessageLoopWin()
: timer_(CreateWaitableTimer(NULL, FALSE, NULL)) {
FTL_CHECK(timer_.is_valid());
}
MessageLoopWin::~MessageLoopWin() = default;
void MessageLoopWin::Run() {
running_ = true;
while (running_) {
FTL_CHECK(WaitForSingleObject(timer_.get(), INFINITE) == 0);
RunExpiredTasksNow();
}
}
void MessageLoopWin::Terminate() {
running_ = false;
WakeUp(ftl::TimePoint::Now());
}
void MessageLoopWin::WakeUp(ftl::TimePoint time_point) {
LARGE_INTEGER due_time = {0};
ftl::TimePoint now = ftl::TimePoint::Now();
if (time_point > now) {
due_time.QuadPart = (time_point - now).ToNanoseconds() / -100;
}
FTL_CHECK(SetWaitableTimer(timer_.get(), &due_time, 0, NULL, NULL, FALSE));
}
} // namespace fml
// Copyright 2017 The Chromium 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 FLUTTER_FML_PLATFORM_WIN_MESSAGE_LOOP_WIN_H_
#define FLUTTER_FML_PLATFORM_WIN_MESSAGE_LOOP_WIN_H_
#include <atomic>
#include <windows.h>
#include "flutter/fml/message_loop_impl.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/unique_object.h"
namespace fml {
class MessageLoopWin : public MessageLoopImpl {
private:
struct UniqueHandleTraits {
static HANDLE InvalidValue() { return NULL; }
static bool IsValid(HANDLE value) { return value != NULL; }
static void Free(HANDLE value) { CloseHandle(value); }
};
bool running_;
ftl::UniqueObject<HANDLE, UniqueHandleTraits> timer_;
MessageLoopWin();
~MessageLoopWin() override;
void Run() override;
void Terminate() override;
void WakeUp(ftl::TimePoint time_point) override;
FRIEND_MAKE_REF_COUNTED(MessageLoopWin);
FRIEND_REF_COUNTED_THREAD_SAFE(MessageLoopWin);
FTL_DISALLOW_COPY_AND_ASSIGN(MessageLoopWin);
};
} // namespace fml
#endif // FLUTTER_FML_PLATFORM_GENERIC_MESSAGE_LOOP_GENERIC_H_
......@@ -4,13 +4,18 @@
#include "flutter/fml/thread.h"
#include "lib/ftl/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#else
#include <pthread.h>
#endif
#include <memory>
#include <string>
#include "flutter/fml/message_loop.h"
#include "lib/ftl/build_config.h"
#include "lib/ftl/synchronization/waitable_event.h"
namespace fml {
......@@ -47,6 +52,18 @@ void Thread::Join() {
thread_->join();
}
#if defined(OS_WIN)
// The information on how to set the thread name comes from
// a MSDN article: http://msdn2.microsoft.com/en-us/library/xcb2z8hs.aspx
const DWORD kVCThreadNameException = 0x406D1388;
typedef struct tagTHREADNAME_INFO {
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#endif
void Thread::SetCurrentThreadName(const std::string& name) {
if (name == "") {
return;
......@@ -55,6 +72,17 @@ void Thread::SetCurrentThreadName(const std::string& name) {
pthread_setname_np(name.c_str());
#elif OS_LINUX || OS_ANDROID
pthread_setname_np(pthread_self(), name.c_str());
#elif OS_WIN
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = name.c_str();
info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0;
__try {
RaiseException(kVCThreadNameException, 0, sizeof(info)/sizeof(DWORD),
reinterpret_cast<DWORD_PTR*>(&info));
} __except(EXCEPTION_CONTINUE_EXECUTION) {
}
#else
#error Unsupported Platform
#endif
......
......@@ -1399,6 +1399,8 @@ FILE: ../../../flutter/fml/platform/linux/message_loop_linux.h
FILE: ../../../flutter/fml/platform/linux/paths_linux.cc
FILE: ../../../flutter/fml/platform/linux/timerfd.cc
FILE: ../../../flutter/fml/platform/linux/timerfd.h
FILE: ../../../flutter/fml/platform/win/message_loop_win.cc
FILE: ../../../flutter/fml/platform/win/message_loop_win.h
FILE: ../../../flutter/fml/task_observer.h
FILE: ../../../flutter/fml/task_runner.cc
FILE: ../../../flutter/fml/task_runner.h
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册