Fabric: Introducing EventBeatBasedExecutor
Summary: EventBeatBasedExecutor is an executor derived from EventBeat and using EventBeat to ensure proper threading. Why do we need yet another executor? Because otherwise, we have to make it platform specific-dependency that each platform-specific implementation has to implement and provide. We already have all that we need in already provided EventBeat, so we can just convert that into simple executor in a platform-agnostic way. Reviewed By: mdvacca Differential Revision: D9995783 fbshipit-source-id: f8aa72a9744e50ebecbea9ad0e2546f41f5358f2
This commit is contained in:
parent
08961c1e97
commit
78746afd92
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "EventBeatBasedExecutor.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using Mode = EventBeatBasedExecutor::Mode;
|
||||
|
||||
EventBeatBasedExecutor::EventBeatBasedExecutor(std::unique_ptr<EventBeat> eventBeat):
|
||||
eventBeat_(std::move(eventBeat)) {
|
||||
|
||||
eventBeat_->setBeatCallback(std::bind(&EventBeatBasedExecutor::onBeat, this));
|
||||
}
|
||||
|
||||
void EventBeatBasedExecutor::operator()(Routine routine, Mode mode) const {
|
||||
if (mode == Mode::Asynchronous) {
|
||||
execute({.routine = std::move(routine)});
|
||||
return;
|
||||
}
|
||||
|
||||
std::mutex mutex;
|
||||
mutex.lock();
|
||||
|
||||
execute({
|
||||
.routine = std::move(routine),
|
||||
.callback = [&mutex]() {
|
||||
mutex.unlock();
|
||||
}
|
||||
});
|
||||
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void EventBeatBasedExecutor::execute(Task task) const {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
tasks_.push_back(std::move(task));
|
||||
}
|
||||
|
||||
eventBeat_->request();
|
||||
eventBeat_->induce();
|
||||
}
|
||||
|
||||
void EventBeatBasedExecutor::onBeat() const {
|
||||
std::vector<Task> tasks;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (tasks_.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tasks = std::move(tasks_);
|
||||
assert(tasks_.size() == 0);
|
||||
}
|
||||
|
||||
for (const auto task : tasks) {
|
||||
task.routine();
|
||||
|
||||
if (task.callback) {
|
||||
task.callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include <fabric/events/EventBeat.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* General purpose executor that uses EventBeat to ensure proper threading.
|
||||
*/
|
||||
class EventBeatBasedExecutor {
|
||||
|
||||
public:
|
||||
using Routine = std::function<void()>;
|
||||
using Callback = std::function<void()>;
|
||||
|
||||
struct Task {
|
||||
Routine routine;
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
enum class Mode {
|
||||
Synchronous,
|
||||
Asynchronous
|
||||
};
|
||||
|
||||
EventBeatBasedExecutor(std::unique_ptr<EventBeat> eventBeat);
|
||||
|
||||
/*
|
||||
* Executes given routine with given mode.
|
||||
*/
|
||||
void operator()(Routine routine, Mode mode = Mode::Asynchronous) const;
|
||||
|
||||
private:
|
||||
void onBeat() const;
|
||||
void execute(Task task) const;
|
||||
|
||||
std::unique_ptr<EventBeat> eventBeat_;
|
||||
mutable std::vector<Task> tasks_; // Protected by `mutex_`.
|
||||
mutable std::mutex mutex_;
|
||||
};
|
||||
|
||||
using EventBeatFactory = std::function<std::unique_ptr<EventBeat>()>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Loading…
Reference in New Issue