flutter_flutter/engine/src/flutter/fml/concurrent_message_loop.h
Chinmay Garde ef31000576 Allow embedders to schedule a callback on all engine managed threads. (flutter/engine#15980)
`FlutterEnginePostCallbackOnAllNativeThreads` schedule a callback to be run on
all engine managed threads. The engine will attempt to service this callback the
next time the message loops for each managed thread is idle. Since the engine
manages the entire lifecycle of multiple threads, there is no opportunity for
the embedders to finely tune the priorities of threads directly, or, perform
other thread specific configuration (for example, setting thread names for
tracing). This callback gives embedders a chance to affect such tuning.

Fixes flutter/flutter#49551
Fixes b/143774406
Fixes b/148278215
Fixes b/148278931
2020-01-27 13:49:39 -08:00

80 lines
1.9 KiB
C++

// Copyright 2013 The Flutter 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_CONCURRENT_MESSAGE_LOOP_H_
#define FLUTTER_FML_CONCURRENT_MESSAGE_LOOP_H_
#include <condition_variable>
#include <map>
#include <queue>
#include <thread>
#include "flutter/fml/closure.h"
#include "flutter/fml/macros.h"
namespace fml {
class ConcurrentTaskRunner;
class ConcurrentMessageLoop
: public std::enable_shared_from_this<ConcurrentMessageLoop> {
public:
static std::shared_ptr<ConcurrentMessageLoop> Create(
size_t worker_count = std::thread::hardware_concurrency());
~ConcurrentMessageLoop();
size_t GetWorkerCount() const;
std::shared_ptr<ConcurrentTaskRunner> GetTaskRunner();
void Terminate();
void PostTaskToAllWorkers(fml::closure task);
private:
friend ConcurrentTaskRunner;
size_t worker_count_ = 0;
std::vector<std::thread> workers_;
std::mutex tasks_mutex_;
std::condition_variable tasks_condition_;
std::queue<fml::closure> tasks_;
std::vector<std::thread::id> worker_thread_ids_;
std::map<std::thread::id, std::vector<fml::closure>> thread_tasks_;
bool shutdown_ = false;
ConcurrentMessageLoop(size_t worker_count);
void WorkerMain();
void PostTask(const fml::closure& task);
bool HasThreadTasksLocked() const;
std::vector<fml::closure> GetThreadTasksLocked();
FML_DISALLOW_COPY_AND_ASSIGN(ConcurrentMessageLoop);
};
class ConcurrentTaskRunner {
public:
ConcurrentTaskRunner(std::weak_ptr<ConcurrentMessageLoop> weak_loop);
~ConcurrentTaskRunner();
void PostTask(const fml::closure& task);
private:
friend ConcurrentMessageLoop;
std::weak_ptr<ConcurrentMessageLoop> weak_loop_;
FML_DISALLOW_COPY_AND_ASSIGN(ConcurrentTaskRunner);
};
} // namespace fml
#endif // FLUTTER_FML_CONCURRENT_MESSAGE_LOOP_H_