| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 37a60a8 commit c2431d5
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -284,6 +284,10 @@ static struct { | |||
| 284 | 284 | platform_->DrainBackgroundTasks(isolate); | |
| 285 | 285 | } | |
| 286 | 286 | ||
| 287 | + void CancelVMTasks(Isolate* isolate) { | ||
| 288 | + platform_->CancelPendingDelayedTasks(isolate); | ||
| 289 | + } | ||
| 290 | + | ||
| 287 | 291 | #if HAVE_INSPECTOR | |
| 288 | 292 | bool StartInspector(Environment *env, const char* script_path, | |
| 289 | 293 | const node::DebugOptions& options) { | |
@@ -316,6 +320,7 @@ static struct { | |||
| 316 | 320 | void Initialize(int thread_pool_size) {} | |
| 317 | 321 | void Dispose() {} | |
| 318 | 322 | void DrainVMTasks(Isolate* isolate) {} | |
| 323 | + void CancelVMTasks(Isolate* isolate) {} | ||
| 319 | 324 | bool StartInspector(Environment *env, const char* script_path, | |
| 320 | 325 | const node::DebugOptions& options) { | |
| 321 | 326 | env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0"); | |
@@ -4891,6 +4896,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, | |||
| 4891 | 4896 | uv_key_delete(&thread_local_env); | |
| 4892 | 4897 | ||
| 4893 | 4898 | v8_platform.DrainVMTasks(isolate); | |
| 4899 | + v8_platform.CancelVMTasks(isolate); | ||
| 4894 | 4900 | WaitForInspectorDisconnect(&env); | |
| 4895 | 4901 | #if defined(LEAK_SANITIZER) | |
| 4896 | 4902 | __lsan_do_leak_check(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -214,6 +214,7 @@ class MultiIsolatePlatform : public v8::Platform { | |||
| 214 | 214 | public: | |
| 215 | 215 | virtual ~MultiIsolatePlatform() { } | |
| 216 | 216 | virtual void DrainBackgroundTasks(v8::Isolate* isolate) = 0; | |
| 217 | + virtual void CancelPendingDelayedTasks(v8::Isolate* isolate) = 0; | ||
| 217 | 218 | ||
| 218 | 219 | // These will be called by the `IsolateData` creation/destruction functions. | |
| 219 | 220 | virtual void RegisterIsolate(IsolateData* isolate_data, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,7 @@ | |||
| 4 | 4 | #include "env.h" | |
| 5 | 5 | #include "env-inl.h" | |
| 6 | 6 | #include "util.h" | |
| 7 | + #include <algorithm> | ||
| 7 | 8 | ||
| 8 | 9 | namespace node { | |
| 9 | 10 | ||
@@ -45,13 +46,17 @@ void PerIsolatePlatformData::CallOnForegroundThread(Task* task) { | |||
| 45 | 46 | ||
| 46 | 47 | void PerIsolatePlatformData::CallDelayedOnForegroundThread( | |
| 47 | 48 | Task* task, double delay_in_seconds) { | |
| 48 | - auto pair = new std::pair<Task*, double>(task, delay_in_seconds); | ||
| 49 | - foreground_delayed_tasks_.Push(pair); | ||
| 49 | + auto delayed = new DelayedTask(); | ||
| 50 | + delayed->task = task; | ||
| 51 | + delayed->platform_data = this; | ||
| 52 | + delayed->timeout = delay_in_seconds; | ||
| 53 | + foreground_delayed_tasks_.Push(delayed); | ||
| 50 | 54 | uv_async_send(flush_tasks_); | |
| 51 | 55 | } | |
| 52 | 56 | ||
| 53 | 57 | PerIsolatePlatformData::~PerIsolatePlatformData() { | |
| 54 | 58 | FlushForegroundTasksInternal(); | |
| 59 | + CancelPendingDelayedTasks(); | ||
| 55 | 60 | ||
| 56 | 61 | uv_close(reinterpret_cast<uv_handle_t*>(flush_tasks_), | |
| 57 | 62 | [](uv_handle_t* handle) { | |
@@ -120,7 +125,7 @@ size_t NodePlatform::NumberOfAvailableBackgroundThreads() { | |||
| 120 | 125 | return threads_.size(); | |
| 121 | 126 | } | |
| 122 | 127 | ||
| 123 | - static void RunForegroundTask(Task* task) { | ||
| 128 | + void PerIsolatePlatformData::RunForegroundTask(Task* task) { | ||
| 124 | 129 | Isolate* isolate = Isolate::GetCurrent(); | |
| 125 | 130 | HandleScope scope(isolate); | |
| 126 | 131 | Environment* env = Environment::GetCurrent(isolate); | |
@@ -130,14 +135,29 @@ static void RunForegroundTask(Task* task) { | |||
| 130 | 135 | delete task; | |
| 131 | 136 | } | |
| 132 | 137 | ||
| 133 | - static void RunForegroundTask(uv_timer_t* handle) { | ||
| 134 | - Task* task = static_cast<Task*>(handle->data); | ||
| 135 | - RunForegroundTask(task); | ||
| 136 | - uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) { | ||
| 137 | - delete reinterpret_cast<uv_timer_t*>(handle); | ||
| 138 | + void PerIsolatePlatformData::RunForegroundTask(uv_timer_t* handle) { | ||
| 139 | + DelayedTask* delayed = static_cast<DelayedTask*>(handle->data); | ||
| 140 | + auto& tasklist = delayed->platform_data->scheduled_delayed_tasks_; | ||
| 141 | + auto it = std::find(tasklist.begin(), tasklist.end(), delayed); | ||
| 142 | + CHECK_NE(it, tasklist.end()); | ||
| 143 | + tasklist.erase(it); | ||
| 144 | + RunForegroundTask(delayed->task); | ||
| 145 | + uv_close(reinterpret_cast<uv_handle_t*>(&delayed->timer), | ||
| 146 | + [](uv_handle_t* handle) { | ||
| 147 | + delete static_cast<DelayedTask*>(handle->data); | ||
| 138 | 148 | }); | |
| 139 | 149 | } | |
| 140 | 150 | ||
| 151 | + void PerIsolatePlatformData::CancelPendingDelayedTasks() { | ||
| 152 | + for (auto delayed : scheduled_delayed_tasks_) { | ||
| 153 | + uv_close(reinterpret_cast<uv_handle_t*>(&delayed->timer), | ||
| 154 | + [](uv_handle_t* handle) { | ||
| 155 | + delete static_cast<DelayedTask*>(handle->data); | ||
| 156 | + }); | ||
| 157 | + } | ||
| 158 | + scheduled_delayed_tasks_.clear(); | ||
| 159 | + } | ||
| 160 | + | ||
| 141 | 161 | void NodePlatform::DrainBackgroundTasks(Isolate* isolate) { | |
| 142 | 162 | PerIsolatePlatformData* per_isolate = ForIsolate(isolate); | |
| 143 | 163 | ||
@@ -152,18 +172,18 @@ void NodePlatform::DrainBackgroundTasks(Isolate* isolate) { | |||
| 152 | 172 | ||
| 153 | 173 | bool PerIsolatePlatformData::FlushForegroundTasksInternal() { | |
| 154 | 174 | bool did_work = false; | |
| 175 | + | ||
| 155 | 176 | while (auto delayed = foreground_delayed_tasks_.Pop()) { | |
| 156 | 177 | did_work = true; | |
| 157 | 178 | uint64_t delay_millis = | |
| 158 | - static_cast<uint64_t>(delayed->second + 0.5) * 1000; | ||
| 159 | - uv_timer_t* handle = new uv_timer_t(); | ||
| 160 | - handle->data = static_cast<void*>(delayed->first); | ||
| 161 | - uv_timer_init(loop_, handle); | ||
| 179 | + static_cast<uint64_t>(delayed->timeout + 0.5) * 1000; | ||
| 180 | + delayed->timer.data = static_cast<void*>(delayed); | ||
| 181 | + uv_timer_init(loop_, &delayed->timer); | ||
| 162 | 182 | // Timers may not guarantee queue ordering of events with the same delay if | |
| 163 | 183 | // the delay is non-zero. This should not be a problem in practice. | |
| 164 | - uv_timer_start(handle, RunForegroundTask, delay_millis, 0); | ||
| 165 | - uv_unref(reinterpret_cast<uv_handle_t*>(handle)); | ||
| 166 | - delete delayed; | ||
| 184 | + uv_timer_start(&delayed->timer, RunForegroundTask, delay_millis, 0); | ||
| 185 | + uv_unref(reinterpret_cast<uv_handle_t*>(&delayed->timer)); | ||
| 186 | + scheduled_delayed_tasks_.push_back(delayed); | ||
| 167 | 187 | } | |
| 168 | 188 | while (Task* task = foreground_tasks_.Pop()) { | |
| 169 | 189 | did_work = true; | |
@@ -199,6 +219,10 @@ void NodePlatform::FlushForegroundTasks(v8::Isolate* isolate) { | |||
| 199 | 219 | ForIsolate(isolate)->FlushForegroundTasksInternal(); | |
| 200 | 220 | } | |
| 201 | 221 | ||
| 222 | + void NodePlatform::CancelPendingDelayedTasks(v8::Isolate* isolate) { | ||
| 223 | + ForIsolate(isolate)->CancelPendingDelayedTasks(); | ||
| 224 | + } | ||
| 225 | + | ||
| 202 | 226 | bool NodePlatform::IdleTasksEnabled(Isolate* isolate) { return false; } | |
| 203 | 227 | ||
| 204 | 228 | double NodePlatform::MonotonicallyIncreasingTime() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,7 @@ namespace node { | |||
| 14 | 14 | ||
| 15 | 15 | class NodePlatform; | |
| 16 | 16 | class IsolateData; | |
| 17 | + class PerIsolatePlatformData; | ||
| 17 | 18 | ||
| 18 | 19 | template <class T> | |
| 19 | 20 | class TaskQueue { | |
@@ -37,6 +38,13 @@ class TaskQueue { | |||
| 37 | 38 | std::queue<T*> task_queue_; | |
| 38 | 39 | }; | |
| 39 | 40 | ||
| 41 | + struct DelayedTask { | ||
| 42 | + v8::Task* task; | ||
| 43 | + uv_timer_t timer; | ||
| 44 | + double timeout; | ||
| 45 | + PerIsolatePlatformData* platform_data; | ||
| 46 | + }; | ||
| 47 | + | ||
| 40 | 48 | class PerIsolatePlatformData { | |
| 41 | 49 | public: | |
| 42 | 50 | PerIsolatePlatformData(v8::Isolate* isolate, uv_loop_t* loop); | |
@@ -52,15 +60,20 @@ class PerIsolatePlatformData { | |||
| 52 | 60 | ||
| 53 | 61 | // Returns true iff work was dispatched or executed. | |
| 54 | 62 | bool FlushForegroundTasksInternal(); | |
| 63 | + void CancelPendingDelayedTasks(); | ||
| 64 | + | ||
| 55 | 65 | private: | |
| 56 | 66 | static void FlushTasks(uv_async_t* handle); | |
| 67 | + static void RunForegroundTask(v8::Task* task); | ||
| 68 | + static void RunForegroundTask(uv_timer_t* timer); | ||
| 57 | 69 | ||
| 58 | 70 | int ref_count_ = 1; | |
| 59 | 71 | v8::Isolate* isolate_; | |
| 60 | 72 | uv_loop_t* const loop_; | |
| 61 | 73 | uv_async_t* flush_tasks_ = nullptr; | |
| 62 | 74 | TaskQueue<v8::Task> foreground_tasks_; | |
| 63 | - TaskQueue<std::pair<v8::Task*, double>> foreground_delayed_tasks_; | ||
| 75 | + TaskQueue<DelayedTask> foreground_delayed_tasks_; | ||
| 76 | + std::vector<DelayedTask*> scheduled_delayed_tasks_; | ||
| 64 | 77 | }; | |
| 65 | 78 | ||
| 66 | 79 | class NodePlatform : public MultiIsolatePlatform { | |
@@ -69,6 +82,7 @@ class NodePlatform : public MultiIsolatePlatform { | |||
| 69 | 82 | virtual ~NodePlatform() {} | |
| 70 | 83 | ||
| 71 | 84 | void DrainBackgroundTasks(v8::Isolate* isolate) override; | |
| 85 | + void CancelPendingDelayedTasks(v8::Isolate* isolate) override; | ||
| 72 | 86 | void Shutdown(); | |
| 73 | 87 | ||
| 74 | 88 | // v8::Platform implementation. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments