Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 'use strict'; | 5 'use strict'; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Namespace for async utility functions. | 8 * Namespace for async utility functions. |
| 9 */ | 9 */ |
| 10 var AsyncUtil = {}; | 10 var AsyncUtil = {}; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 callback(iterationCompletionCallback, element, index, array); | 36 callback(iterationCompletionCallback, element, index, array); |
| 37 }.bind(null, array[i], i)); | 37 }.bind(null, array[i], i)); |
| 38 } | 38 } |
| 39 queue.run(function(iterationCompletionCallback) { | 39 queue.run(function(iterationCompletionCallback) { |
| 40 completionCallback(); // Don't pass iteration completion callback. | 40 completionCallback(); // Don't pass iteration completion callback. |
| 41 }); | 41 }); |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 /** | 44 /** |
| 45 * Creates a class for executing several asynchronous closures in a fifo queue. | 45 * Creates a class for executing several asynchronous closures in a fifo queue. |
| 46 * Added tasks will be started in order they were added. Tasks are run | |
| 47 * concurrently. At most, |limit| jobs will be run at the same time. | |
| 48 * | |
| 49 * @param {number} limit The number of jobs to run at the same time. | |
| 50 * @constructor | |
| 51 */ | |
| 52 AsyncUtil.ConcurrentQueue = function(limit) { | |
| 53 console.assert(limit > 0, '|limit| must be larger than 2'); | |
| 54 | |
| 55 this.limit_ = limit; | |
| 56 this.addedTasks_ = []; | |
| 57 this.pendingTasks_ = []; | |
| 58 this.isCancelled_ = false; | |
| 59 | |
| 60 Object.seal(this); | |
| 61 }; | |
| 62 | |
| 63 /** | |
| 64 * @return {boolean} True when a task is running, otherwise false. | |
| 65 */ | |
| 66 AsyncUtil.ConcurrentQueue.prototype.isRunning = function() { | |
| 67 return this.pendingTasks_.length !== 0; | |
| 68 }; | |
| 69 | |
| 70 /** | |
| 71 * @return {number} Number of waiting tasks. | |
| 72 */ | |
| 73 AsyncUtil.ConcurrentQueue.prototype.getWaitingTasksCount = function() { | |
| 74 return this.addedTasks_.length; | |
| 75 }; | |
| 76 | |
| 77 /** | |
| 78 * @return {boolean} Number of running tasks. | |
| 79 */ | |
| 80 AsyncUtil.ConcurrentQueue.prototype.getRunningTasksCount = function() { | |
| 81 return this.pendingTasks_.length; | |
| 82 }; | |
| 83 | |
| 84 /** | |
| 85 * Enqueues a closure to be executed. | |
| 86 * @param {function(function(callback, isCancelled=))} closure Closure with a | |
| 87 * completion callback to be executed. | |
| 88 */ | |
| 89 AsyncUtil.ConcurrentQueue.prototype.run = function(closure) { | |
| 90 if (this.isCancelled_) { | |
| 91 console.error('Queue is calcelled. Cannot add a new task.'); | |
| 92 return; | |
| 93 } | |
| 94 | |
| 95 this.addedTasks_.push(closure); | |
| 96 this.continue_(); | |
| 97 return; | |
|
hirono
2014/05/26 09:19:42
nit: Is it needed?
yoshiki
2014/05/26 09:36:33
Done.
| |
| 98 }; | |
| 99 | |
| 100 /** | |
| 101 * Cancels the queue. It removes all the not-run (yet) tasks. Note that this | |
| 102 * does NOT stop tasks currently running. | |
| 103 */ | |
| 104 AsyncUtil.ConcurrentQueue.prototype.cancel = function() { | |
| 105 this.isCancelled_ = true; | |
| 106 this.addedTasks_ = []; | |
| 107 }; | |
| 108 | |
| 109 /** | |
| 110 * @return {boolean} True when the queue have been requested to cancel or is | |
| 111 * already cancelled. Otherwise false. | |
| 112 */ | |
| 113 AsyncUtil.ConcurrentQueue.prototype.isCancelled = function() { | |
| 114 return this.isCancelled_; | |
| 115 }; | |
| 116 | |
| 117 /** | |
| 118 * Runs the next tasks if available. | |
| 119 * @private | |
| 120 */ | |
| 121 AsyncUtil.ConcurrentQueue.prototype.continue_ = function() { | |
| 122 if (this.addedTasks_.length === 0) | |
| 123 return; | |
| 124 | |
| 125 console.assert( | |
| 126 this.pendingTasks_.length <= this.limit_, | |
| 127 'Too many jobs are running (' + this.pendingTasks_.length + ')'); | |
| 128 | |
| 129 if (this.pendingTasks_.length >= this.limit_) | |
| 130 return; | |
| 131 | |
| 132 // Run the next closure. | |
| 133 var closure = this.addedTasks_.shift(); | |
| 134 this.pendingTasks_.push(closure); | |
| 135 closure(this.onTaskFinished_.bind(this, closure), this.isCancelled_); | |
| 136 | |
| 137 this.continue_(); | |
| 138 }; | |
| 139 | |
| 140 /** | |
| 141 * Called when a task is finished. Removes the tasks from pending task list. | |
| 142 * @private | |
| 143 */ | |
| 144 AsyncUtil.ConcurrentQueue.prototype.onTaskFinished_ = function(closure) { | |
| 145 var index = this.pendingTasks_.indexOf(closure); | |
| 146 console.assert(index >= 0, 'Invalid task is finished'); | |
| 147 this.pendingTasks_.splice(index, 1); | |
| 148 | |
| 149 this.continue_(); | |
| 150 }; | |
| 151 | |
| 152 /** | |
| 153 * Creates a class for executing several asynchronous closures in a fifo queue. | |
| 46 * Added tasks will be executed sequentially in order they were added. | 154 * Added tasks will be executed sequentially in order they were added. |
| 47 * | 155 * |
| 48 * @constructor | 156 * @constructor |
| 157 * @extends {AsyncUtil.ConcurrentQueue} | |
| 49 */ | 158 */ |
| 50 AsyncUtil.Queue = function() { | 159 AsyncUtil.Queue = function() { |
| 51 this.running_ = false; | 160 AsyncUtil.ConcurrentQueue.call(this, 1); |
| 52 this.closures_ = []; | |
| 53 }; | 161 }; |
| 54 | 162 |
| 55 /** | 163 AsyncUtil.Queue.prototype.__proto__ = AsyncUtil.ConcurrentQueue.prototype; |
| 56 * @return {boolean} True when a task is running, otherwise false. | |
| 57 */ | |
| 58 AsyncUtil.Queue.prototype.isRunning = function() { | |
| 59 return this.running_; | |
| 60 }; | |
| 61 | |
| 62 /** | |
| 63 * Enqueues a closure to be executed. | |
| 64 * @param {function(function())} closure Closure with a completion callback to | |
| 65 * be executed. | |
| 66 */ | |
| 67 AsyncUtil.Queue.prototype.run = function(closure) { | |
| 68 this.closures_.push(closure); | |
| 69 if (!this.running_) | |
| 70 this.continue_(); | |
| 71 }; | |
| 72 | |
| 73 /** | |
| 74 * Serves the next closure from the queue. | |
| 75 * @private | |
| 76 */ | |
| 77 AsyncUtil.Queue.prototype.continue_ = function() { | |
| 78 if (!this.closures_.length) { | |
| 79 this.running_ = false; | |
| 80 return; | |
| 81 } | |
| 82 | |
| 83 // Run the next closure. | |
| 84 this.running_ = true; | |
| 85 var closure = this.closures_.shift(); | |
| 86 closure(this.continue_.bind(this)); | |
| 87 }; | |
| 88 | |
| 89 /** | |
| 90 * Cancels all pending tasks. Note that this does NOT cancel the task running | |
| 91 * currently. | |
| 92 */ | |
| 93 AsyncUtil.Queue.prototype.cancel = function() { | |
| 94 this.closures_ = []; | |
| 95 }; | |
| 96 | 164 |
| 97 /** | 165 /** |
| 98 * Creates a class for executing several asynchronous closures in a group in | 166 * Creates a class for executing several asynchronous closures in a group in |
| 99 * a dependency order. | 167 * a dependency order. |
| 100 * | 168 * |
| 101 * @constructor | 169 * @constructor |
| 102 */ | 170 */ |
| 103 AsyncUtil.Group = function() { | 171 AsyncUtil.Group = function() { |
| 104 this.addedTasks_ = {}; | 172 this.addedTasks_ = {}; |
| 105 this.pendingTasks_ = {}; | 173 this.pendingTasks_ = {}; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 /** | 321 /** |
| 254 * Cancels all scheduled runs (if any). | 322 * Cancels all scheduled runs (if any). |
| 255 * @private | 323 * @private |
| 256 */ | 324 */ |
| 257 AsyncUtil.Aggregation.prototype.cancelScheduledRuns_ = function() { | 325 AsyncUtil.Aggregation.prototype.cancelScheduledRuns_ = function() { |
| 258 if (this.scheduledRunsTimer_) { | 326 if (this.scheduledRunsTimer_) { |
| 259 clearTimeout(this.scheduledRunsTimer_); | 327 clearTimeout(this.scheduledRunsTimer_); |
| 260 this.scheduledRunsTimer_ = null; | 328 this.scheduledRunsTimer_ = null; |
| 261 } | 329 } |
| 262 }; | 330 }; |
| OLD | NEW |