| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2018-07-30 23:08:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Semaphore { | 
					
						
							| 
									
										
										
										
											2018-05-04 00:57:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Creates an instance of Semaphore. | 
					
						
							|  |  |  | 	 * @param {number} available the amount available number of "tasks" | 
					
						
							|  |  |  | 	 * in the Semaphore | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 	constructor(available) { | 
					
						
							|  |  |  | 		this.available = available; | 
					
						
							| 
									
										
										
										
											2018-05-15 18:20:17 +08:00
										 |  |  | 		/** @type {(function(): void)[]} */ | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 		this.waiters = []; | 
					
						
							| 
									
										
										
										
											2018-05-04 00:57:02 +08:00
										 |  |  | 		/** @private */ | 
					
						
							| 
									
										
										
										
											2018-04-12 21:54:35 +08:00
										 |  |  | 		this._continue = this._continue.bind(this); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 00:57:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {function(): void} callback function block to capture and run | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 	acquire(callback) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.available > 0) { | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 			this.available--; | 
					
						
							|  |  |  | 			callback(); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			this.waiters.push(callback); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	release() { | 
					
						
							| 
									
										
										
										
											2018-04-12 21:54:35 +08:00
										 |  |  | 		this.available++; | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.waiters.length > 0) { | 
					
						
							| 
									
										
										
										
											2018-04-12 21:54:35 +08:00
										 |  |  | 			process.nextTick(this._continue); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_continue() { | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 		if (this.available > 0 && this.waiters.length > 0) { | 
					
						
							|  |  |  | 			this.available--; | 
					
						
							|  |  |  | 			const callback = /** @type {(function(): void)} */ (this.waiters.pop()); | 
					
						
							|  |  |  | 			callback(); | 
					
						
							| 
									
										
										
										
											2017-08-11 22:11:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = Semaphore; |