Skip to content

Commit

Permalink
Rename some methods in RuntimeScheduler_Modern to refer to event loop…
Browse files Browse the repository at this point in the history
… more explicitly

Summary:
Changelog: [internal]

Just a small refactor of some private methods in `RuntimeScheduler_Modern` to refer to some concepts in terms of the event loop.

Reviewed By: christophpurrer

Differential Revision: D58948811
  • Loading branch information
rubennorte authored and facebook-github-bot committed Jun 24, 2024
1 parent 9ba600c commit acddd0c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,33 +158,33 @@ void RuntimeScheduler_Modern::executeNowOnTheSameThread(

syncTaskRequests_--;
runtimePtr = &runtime;
executeTask(runtime, task, currentTime);
runEventLoopTick(runtime, task, currentTime);
runtimePtr = nullptr;
});

} else {
// Protecting against re-entry into `executeNowOnTheSameThread` from within
// `executeNowOnTheSameThread`. Without accounting for re-rentry, a deadlock
// will occur when trying to gain access to the runtime.
return executeTask(*runtimePtr, task, currentTime);
return runEventLoopTick(*runtimePtr, task, currentTime);
}

bool shouldScheduleWorkLoop = false;
bool shouldScheduleEventLoop = false;

{
// Unique access because we might write to `isWorkLoopScheduled_`.
// Unique access because we might write to `isEventLoopScheduled_`.
std::unique_lock lock(schedulingMutex_);

// We only need to schedule the work loop if there any remaining tasks
// We only need to schedule the event loop if there any remaining tasks
// in the queue.
if (!taskQueue_.empty() && !isWorkLoopScheduled_) {
isWorkLoopScheduled_ = true;
shouldScheduleWorkLoop = true;
if (!taskQueue_.empty() && !isEventLoopScheduled_) {
isEventLoopScheduled_ = true;
shouldScheduleEventLoop = true;
}
}

if (shouldScheduleWorkLoop) {
scheduleWorkLoop();
if (shouldScheduleEventLoop) {
scheduleEventLoop();
}
}

Expand All @@ -195,7 +195,7 @@ void RuntimeScheduler_Modern::callExpiredTasks(jsi::Runtime& runtime) {
}

SystraceSection s("RuntimeScheduler::callExpiredTasks");
startWorkLoop(runtime, true);
runEventLoop(runtime, true);
}

void RuntimeScheduler_Modern::scheduleRenderingUpdate(
Expand All @@ -220,37 +220,37 @@ void RuntimeScheduler_Modern::setShadowTreeRevisionConsistencyManager(
#pragma mark - Private

void RuntimeScheduler_Modern::scheduleTask(std::shared_ptr<Task> task) {
bool shouldScheduleWorkLoop = false;
bool shouldScheduleEventLoop = false;

{
std::unique_lock lock(schedulingMutex_);

// We only need to schedule the work loop if the task we're about to
// We only need to schedule the event loop if the task we're about to
// schedule is the only one in the queue.
// Otherwise, we don't need to schedule it because there's another one
// running already that will pick up the new task.
if (taskQueue_.empty() && !isWorkLoopScheduled_) {
isWorkLoopScheduled_ = true;
shouldScheduleWorkLoop = true;
if (taskQueue_.empty() && !isEventLoopScheduled_) {
isEventLoopScheduled_ = true;
shouldScheduleEventLoop = true;
}

taskQueue_.push(task);
}

if (shouldScheduleWorkLoop) {
scheduleWorkLoop();
if (shouldScheduleEventLoop) {
scheduleEventLoop();
}
}

void RuntimeScheduler_Modern::scheduleWorkLoop() {
void RuntimeScheduler_Modern::scheduleEventLoop() {
runtimeExecutor_(
[this](jsi::Runtime& runtime) { startWorkLoop(runtime, false); });
[this](jsi::Runtime& runtime) { runEventLoop(runtime, false); });
}

void RuntimeScheduler_Modern::startWorkLoop(
void RuntimeScheduler_Modern::runEventLoop(
jsi::Runtime& runtime,
bool onlyExpired) {
SystraceSection s("RuntimeScheduler::startWorkLoop");
SystraceSection s("RuntimeScheduler::runEventLoop");

auto previousPriority = currentPriority_;

Expand All @@ -264,7 +264,7 @@ void RuntimeScheduler_Modern::startWorkLoop(
break;
}

executeTask(runtime, *topPriorityTask, currentTime);
runEventLoopTick(runtime, *topPriorityTask, currentTime);
}

currentPriority_ = previousPriority;
Expand All @@ -279,7 +279,7 @@ std::shared_ptr<Task> RuntimeScheduler_Modern::selectTask(

// It's safe to reset the flag here, as its access is also synchronized with
// the access to the task queue.
isWorkLoopScheduled_ = false;
isEventLoopScheduled_ = false;

// Skip executed tasks
while (!taskQueue_.empty() && !taskQueue_.top()->callback) {
Expand All @@ -297,18 +297,11 @@ std::shared_ptr<Task> RuntimeScheduler_Modern::selectTask(
return nullptr;
}

void RuntimeScheduler_Modern::executeTask(
void RuntimeScheduler_Modern::runEventLoopTick(
jsi::Runtime& runtime,
Task& task,
RuntimeSchedulerTimePoint currentTime) {
auto didUserCallbackTimeout = task.expirationTime <= currentTime;

SystraceSection s(
"RuntimeScheduler::executeTask",
"priority",
serialize(task.priority),
"didUserCallbackTimeout",
didUserCallbackTimeout);
SystraceSection s("RuntimeScheduler::runEventLoopTick");

currentTask_ = &task;
currentPriority_ = task.priority;
Expand All @@ -317,7 +310,8 @@ void RuntimeScheduler_Modern::executeTask(
ScopedShadowTreeRevisionLock revisionLock(
shadowTreeRevisionConsistencyManager_);

executeMacrotask(runtime, task, didUserCallbackTimeout);
auto didUserCallbackTimeout = task.expirationTime <= currentTime;
executeTask(runtime, task, didUserCallbackTimeout);

if (ReactNativeFeatureFlags::enableMicrotasks()) {
// "Perform a microtask checkpoint" step.
Expand Down Expand Up @@ -350,11 +344,16 @@ void RuntimeScheduler_Modern::updateRendering() {
}
}

void RuntimeScheduler_Modern::executeMacrotask(
void RuntimeScheduler_Modern::executeTask(
jsi::Runtime& runtime,
Task& task,
bool didUserCallbackTimeout) const {
SystraceSection s("RuntimeScheduler::executeMacrotask");
SystraceSection s(
"RuntimeScheduler::executeTask",
"priority",
serialize(task.priority),
"didUserCallbackTimeout",
didUserCallbackTimeout);

try {
auto result = task.execute(runtime, didUserCallbackTimeout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,23 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {

/*
* Adds a JavaScript callback to the priority queue with the given priority.
* Triggers workloop if needed.
* Triggers event loop if needed.
*/
std::shared_ptr<Task> scheduleTask(
SchedulerPriority priority,
jsi::Function&& callback) noexcept override;

/*
* Adds a custom callback to the priority queue with the given priority.
* Triggers workloop if needed.
* Triggers event loop if needed.
*/
std::shared_ptr<Task> scheduleTask(
SchedulerPriority priority,
RawCallback&& callback) noexcept override;

/*
* Adds a JavaScript callback to the idle queue with the given timeout.
* Triggers workloop if needed.
* Triggers event loop if needed.
*/
std::shared_ptr<Task> scheduleIdleTask(
jsi::Function&& callback,
Expand All @@ -81,7 +81,7 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {

/*
* Adds a custom callback to the idle queue with the given timeout.
* Triggers workloop if needed.
* Triggers event loop if needed.
*/
std::shared_ptr<Task> scheduleIdleTask(
RawCallback&& callback,
Expand Down Expand Up @@ -156,15 +156,15 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
Task* currentTask_{};

/**
* This protects the access to `taskQueue_` and `isWorkLoopScheduled_`.
* This protects the access to `taskQueue_` and `isevent loopScheduled_`.
*/
mutable std::shared_mutex schedulingMutex_;

const RuntimeExecutor runtimeExecutor_;
SchedulerPriority currentPriority_{SchedulerPriority::NormalPriority};

void scheduleWorkLoop();
void startWorkLoop(jsi::Runtime& runtime, bool onlyExpired);
void scheduleEventLoop();
void runEventLoop(jsi::Runtime& runtime, bool onlyExpired);

std::shared_ptr<Task> selectTask(
RuntimeSchedulerTimePoint currentTime,
Expand All @@ -178,12 +178,12 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
* In the future, this will include other steps in the Web event loop, like
* updating the UI in native, executing resize observer callbacks, etc.
*/
void executeTask(
void runEventLoopTick(
jsi::Runtime& runtime,
Task& task,
RuntimeSchedulerTimePoint currentTime);

void executeMacrotask(
void executeTask(
jsi::Runtime& runtime,
Task& task,
bool didUserCallbackTimeout) const;
Expand All @@ -203,7 +203,7 @@ class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
* Flag indicating if callback on JavaScript queue has been
* scheduled.
*/
bool isWorkLoopScheduled_{false};
bool isEventLoopScheduled_{false};

std::queue<RuntimeSchedulerRenderingUpdate> pendingRenderingUpdates_;
ShadowTreeRevisionConsistencyManager* shadowTreeRevisionConsistencyManager_{
Expand Down

0 comments on commit acddd0c

Please sign in to comment.