Skip to content

Commit

Permalink
Add unit tests for RuntimeScheduler::executeNowOnTheSameThread
Browse files Browse the repository at this point in the history
Summary: Changelog: [internal]

Reviewed By: philIip

Differential Revision: D33062204

fbshipit-source-id: f37375400fea645f5540b85c3c1ef6343e64be2e
  • Loading branch information
sammy-SC authored and facebook-github-bot committed Dec 16, 2021
1 parent 6a046fb commit fd18225
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,64 @@ TEST_F(RuntimeSchedulerTest, handlingError) {
EXPECT_EQ(stubErrorUtils_->getReportFatalCallCount(), 1);
}

TEST_F(RuntimeSchedulerTest, basicSameThreadExecution) {
bool didRunSynchronousTask = false;
std::thread t1([this, &didRunSynchronousTask]() {
runtimeScheduler_->executeNowOnTheSameThread(
[this, &didRunSynchronousTask](jsi::Runtime &rt) {
EXPECT_TRUE(runtimeScheduler_->getIsSynchronous());
didRunSynchronousTask = true;
});
EXPECT_FALSE(runtimeScheduler_->getIsSynchronous());
});

auto hasTask = stubQueue_->waitForTask(1ms);

EXPECT_TRUE(hasTask);
EXPECT_FALSE(didRunSynchronousTask);
EXPECT_EQ(stubQueue_->size(), 1);

stubQueue_->tick();

t1.join();

EXPECT_TRUE(didRunSynchronousTask);
}

TEST_F(RuntimeSchedulerTest, sameThreadTaskCreatesImmediatePriorityTask) {
bool didRunSynchronousTask = false;
bool didRunSubsequentTask = false;
std::thread t1([this, &didRunSynchronousTask, &didRunSubsequentTask]() {
runtimeScheduler_->executeNowOnTheSameThread(
[this, &didRunSynchronousTask, &didRunSubsequentTask](
jsi::Runtime &rt) {
didRunSynchronousTask = true;

auto callback = createHostFunctionFromLambda(
[&didRunSubsequentTask](bool didUserCallbackTimeout) {
didRunSubsequentTask = true;
EXPECT_FALSE(didUserCallbackTimeout);
return jsi::Value::undefined();
});

runtimeScheduler_->scheduleTask(
SchedulerPriority::ImmediatePriority, std::move(callback));
});
});

auto hasTask = stubQueue_->waitForTask(1ms);

EXPECT_TRUE(hasTask);
EXPECT_FALSE(didRunSynchronousTask);
EXPECT_FALSE(didRunSubsequentTask);
EXPECT_EQ(stubQueue_->size(), 1);

stubQueue_->tick();

t1.join();

EXPECT_TRUE(didRunSynchronousTask);
EXPECT_TRUE(didRunSubsequentTask);
}

} // namespace facebook::react
33 changes: 27 additions & 6 deletions ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,48 @@
class StubQueue {
public:
void runOnQueue(std::function<void()> &&func) {
callbackQueue_.push(func);
{
std::lock_guard<std::mutex> lock(mutex_);
callbackQueue_.push(func);
}

signal_.notify_one();
}

void flush() {
while (!callbackQueue_.empty()) {
while (size() > 0) {
tick();
}
}

void tick() {
if (!callbackQueue_.empty()) {
auto callback = callbackQueue_.front();
std::function<void()> callback;
{
std::lock_guard<std::mutex> lock(mutex_);
if (!callbackQueue_.empty()) {
callback = callbackQueue_.front();
callbackQueue_.pop();
}
}

if (callback) {
callback();
callbackQueue_.pop();
}
}

int size() {
size_t size() const {
std::lock_guard<std::mutex> lock(mutex_);
return callbackQueue_.size();
}

bool waitForTask(std::chrono::duration<double> timeout) const {
std::unique_lock<std::mutex> lock(mutex_);
return signal_.wait_for(
lock, timeout, [this]() { return !callbackQueue_.empty(); });
}

private:
mutable std::condition_variable signal_;
mutable std::mutex mutex_;
std::queue<std::function<void()>> callbackQueue_;
};

0 comments on commit fd18225

Please sign in to comment.