| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 99e0b91 commit 6bf816f
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -961,6 +961,7 @@ | |||
| 961 | 961 | 'test/cctest/test_base64.cc', | |
| 962 | 962 | 'test/cctest/test_node_postmortem_metadata.cc', | |
| 963 | 963 | 'test/cctest/test_environment.cc', | |
| 964 | + 'test/cctest/test_platform.cc', | ||
| 964 | 965 | 'test/cctest/test_util.cc', | |
| 965 | 966 | 'test/cctest/test_url.cc' | |
| 966 | 967 | ], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -316,7 +316,7 @@ class NodeInspectorClient : public V8InspectorClient { | |||
| 316 | 316 | terminated_ = false; | |
| 317 | 317 | running_nested_loop_ = true; | |
| 318 | 318 | while (!terminated_ && channel_->waitForFrontendMessage()) { | |
| 319 | - platform_->FlushForegroundTasks(env_->isolate()); | ||
| 319 | + while (platform_->FlushForegroundTasks(env_->isolate())) {} | ||
| 320 | 320 | } | |
| 321 | 321 | terminated_ = false; | |
| 322 | 322 | running_nested_loop_ = false; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -95,7 +95,7 @@ void PerIsolatePlatformData::PostDelayedTask( | |||
| 95 | 95 | } | |
| 96 | 96 | ||
| 97 | 97 | PerIsolatePlatformData::~PerIsolatePlatformData() { | |
| 98 | - FlushForegroundTasksInternal(); | ||
| 98 | + while (FlushForegroundTasksInternal()) {} | ||
| 99 | 99 | CancelPendingDelayedTasks(); | |
| 100 | 100 | ||
| 101 | 101 | uv_close(reinterpret_cast<uv_handle_t*>(flush_tasks_), | |
@@ -223,7 +223,13 @@ bool PerIsolatePlatformData::FlushForegroundTasksInternal() { | |||
| 223 | 223 | }); | |
| 224 | 224 | }); | |
| 225 | 225 | } | |
| 226 | - while (std::unique_ptr<Task> task = foreground_tasks_.Pop()) { | ||
| 226 | + // Move all foreground tasks into a separate queue and flush that queue. | ||
| 227 | + // This way tasks that are posted while flushing the queue will be run on the | ||
| 228 | + // next call of FlushForegroundTasksInternal. | ||
| 229 | + std::queue<std::unique_ptr<Task>> tasks = foreground_tasks_.PopAll(); | ||
| 230 | + while (!tasks.empty()) { | ||
| 231 | + std::unique_ptr<Task> task = std::move(tasks.front()); | ||
| 232 | + tasks.pop(); | ||
| 227 | 233 | did_work = true; | |
| 228 | 234 | RunForegroundTask(std::move(task)); | |
| 229 | 235 | } | |
@@ -254,8 +260,8 @@ void NodePlatform::CallDelayedOnForegroundThread(Isolate* isolate, | |||
| 254 | 260 | std::unique_ptr<Task>(task), delay_in_seconds); | |
| 255 | 261 | } | |
| 256 | 262 | ||
| 257 | - void NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) { | ||
| 258 | - ForIsolate(isolate)->FlushForegroundTasksInternal(); | ||
| 263 | + bool NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) { | ||
| 264 | + return ForIsolate(isolate)->FlushForegroundTasksInternal(); | ||
| 259 | 265 | } | |
| 260 | 266 | ||
| 261 | 267 | void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) { | |
@@ -348,4 +354,12 @@ void TaskQueue<T>::Stop() { | |||
| 348 | 354 | tasks_available_.Broadcast(scoped_lock); | |
| 349 | 355 | } | |
| 350 | 356 | ||
| 357 | + template <class T> | ||
| 358 | + std::queue<std::unique_ptr<T>> TaskQueue<T>::PopAll() { | ||
| 359 | + Mutex::ScopedLock scoped_lock(lock_); | ||
| 360 | + std::queue<std::unique_ptr<T>> result; | ||
| 361 | + result.swap(task_queue_); | ||
| 362 | + return result; | ||
| 363 | + } | ||
| 364 | + | ||
| 351 | 365 | } // namespace node | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,6 +26,7 @@ class TaskQueue { | |||
| 26 | 26 | void Push(std::unique_ptr<T> task); | |
| 27 | 27 | std::unique_ptr<T> Pop(); | |
| 28 | 28 | std::unique_ptr<T> BlockingPop(); | |
| 29 | + std::queue<std::unique_ptr<T>> PopAll(); | ||
| 29 | 30 | void NotifyOfCompletion(); | |
| 30 | 31 | void BlockingDrain(); | |
| 31 | 32 | void Stop(); | |
@@ -65,7 +66,9 @@ class PerIsolatePlatformData : | |||
| 65 | 66 | void ref(); | |
| 66 | 67 | int unref(); | |
| 67 | 68 | ||
| 68 | - // Returns true iff work was dispatched or executed. | ||
| 69 | + // Returns true if work was dispatched or executed. New tasks that are | ||
| 70 | + // posted during flushing of the queue are postponed until the next | ||
| 71 | + // flushing. | ||
| 69 | 72 | bool FlushForegroundTasksInternal(); | |
| 70 | 73 | void CancelPendingDelayedTasks(); | |
| 71 | 74 | ||
@@ -130,7 +133,10 @@ class NodePlatform : public MultiIsolatePlatform { | |||
| 130 | 133 | double CurrentClockTimeMillis() override; | |
| 131 | 134 | v8::TracingController* GetTracingController() override; | |
| 132 | 135 | ||
| 133 | - void FlushForegroundTasks(v8::Isolate* isolate); | ||
| 136 | + // Returns true if work was dispatched or executed. New tasks that are | ||
| 137 | + // posted during flushing of the queue are postponed until the next | ||
| 138 | + // flushing. | ||
| 139 | + bool FlushForegroundTasks(v8::Isolate* isolate); | ||
| 134 | 140 | ||
| 135 | 141 | void RegisterIsolate(IsolateData* isolate_data, uv_loop_t* loop) override; | |
| 136 | 142 | void UnregisterIsolate(IsolateData* isolate_data) override; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,55 @@ | |||
| 1 | + #include "node_internals.h" | ||
| 2 | + #include "libplatform/libplatform.h" | ||
| 3 | + | ||
| 4 | + #include <string> | ||
| 5 | + #include "gtest/gtest.h" | ||
| 6 | + #include "node_test_fixture.h" | ||
| 7 | + | ||
| 8 | + // This task increments the given run counter and reposts itself until the | ||
| 9 | + // repost counter reaches zero. | ||
| 10 | + class RepostingTask : public v8::Task { | ||
| 11 | + public: | ||
| 12 | + explicit RepostingTask(int repost_count, | ||
| 13 | + int* run_count, | ||
| 14 | + v8::Isolate* isolate, | ||
| 15 | + node::NodePlatform* platform) | ||
| 16 | + : repost_count_(repost_count), | ||
| 17 | + run_count_(run_count), | ||
| 18 | + isolate_(isolate), | ||
| 19 | + platform_(platform) {} | ||
| 20 | + | ||
| 21 | + // v8::Task implementation | ||
| 22 | + void Run() final { | ||
| 23 | + ++*run_count_; | ||
| 24 | + if (repost_count_ > 0) { | ||
| 25 | + --repost_count_; | ||
| 26 | + platform_->CallOnForegroundThread(isolate_, | ||
| 27 | + new RepostingTask(repost_count_, run_count_, isolate_, platform_)); | ||
| 28 | + } | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + private: | ||
| 32 | + int repost_count_; | ||
| 33 | + int* run_count_; | ||
| 34 | + v8::Isolate* isolate_; | ||
| 35 | + node::NodePlatform* platform_; | ||
| 36 | + }; | ||
| 37 | + | ||
| 38 | + class PlatformTest : public EnvironmentTestFixture {}; | ||
| 39 | + | ||
| 40 | + TEST_F(PlatformTest, SkipNewTasksInFlushForegroundTasks) { | ||
| 41 | + v8::Isolate::Scope isolate_scope(isolate_); | ||
| 42 | + const v8::HandleScope handle_scope(isolate_); | ||
| 43 | + const Argv argv; | ||
| 44 | + Env env {handle_scope, argv}; | ||
| 45 | + int run_count = 0; | ||
| 46 | + platform->CallOnForegroundThread( | ||
| 47 | + isolate_, new RepostingTask(2, &run_count, isolate_, platform.get())); | ||
| 48 | + EXPECT_TRUE(platform->FlushForegroundTasks(isolate_)); | ||
| 49 | + EXPECT_EQ(1, run_count); | ||
| 50 | + EXPECT_TRUE(platform->FlushForegroundTasks(isolate_)); | ||
| 51 | + EXPECT_EQ(2, run_count); | ||
| 52 | + EXPECT_TRUE(platform->FlushForegroundTasks(isolate_)); | ||
| 53 | + EXPECT_EQ(3, run_count); | ||
| 54 | + EXPECT_FALSE(platform->FlushForegroundTasks(isolate_)); | ||
| 55 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments