Update Files
This commit is contained in:
		
							
								
								
									
										63
									
								
								Kha/Tools/macos/std/sys/thread/Deque.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Kha/Tools/macos/std/sys/thread/Deque.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	A Deque is a double-ended queue with a `pop` method that can block until
 | 
			
		||||
	an element is available. It is commonly used to synchronize threads.
 | 
			
		||||
 */
 | 
			
		||||
@:coreApi extern class Deque<T> {
 | 
			
		||||
	/**
 | 
			
		||||
		Create a new Deque instance which is initially empty.
 | 
			
		||||
	**/
 | 
			
		||||
	function new():Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Adds an element at the end of `this` Deque.
 | 
			
		||||
 | 
			
		||||
		(Java,Jvm): throws `java.lang.NullPointerException` if `i` is `null`.
 | 
			
		||||
	**/
 | 
			
		||||
	function add(i:T):Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Adds an element at the front of `this` Deque.
 | 
			
		||||
 | 
			
		||||
		(Java,Jvm): throws `java.lang.NullPointerException` if `i` is `null`.
 | 
			
		||||
	**/
 | 
			
		||||
	function push(i:T):Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Tries to retrieve an element from the front of `this` Deque.
 | 
			
		||||
 | 
			
		||||
		If an element is available, it is removed from the queue and returned.
 | 
			
		||||
 | 
			
		||||
		If no element is available and `block` is `false`, `null` is returned.
 | 
			
		||||
 | 
			
		||||
		Otherwise, execution blocks until an element is available and returns it.
 | 
			
		||||
	**/
 | 
			
		||||
	function pop(block:Bool):Null<T>;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										198
									
								
								Kha/Tools/macos/std/sys/thread/ElasticThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								Kha/Tools/macos/std/sys/thread/ElasticThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,198 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
import haxe.Exception;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	Thread pool with a varying amount of threads.
 | 
			
		||||
 | 
			
		||||
	A new thread is spawned every time a task is submitted while all existing
 | 
			
		||||
	threads are busy.
 | 
			
		||||
**/
 | 
			
		||||
@:coreApi
 | 
			
		||||
class ElasticThreadPool implements IThreadPool {
 | 
			
		||||
	/* Amount of alive threads in this pool. */
 | 
			
		||||
	public var threadsCount(get,null):Int;
 | 
			
		||||
	/* Maximum amount of threads in this pool. */
 | 
			
		||||
	public var maxThreadsCount:Int;
 | 
			
		||||
	/** Indicates if `shutdown` method of this pool has been called. */
 | 
			
		||||
	public var isShutdown(get,never):Bool;
 | 
			
		||||
	var _isShutdown = false;
 | 
			
		||||
	function get_isShutdown():Bool return _isShutdown;
 | 
			
		||||
 | 
			
		||||
	final pool:Array<Worker> = [];
 | 
			
		||||
	final queue = new Deque<()->Void>();
 | 
			
		||||
	final mutex = new Mutex();
 | 
			
		||||
	final threadTimeout:Float;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Create a new thread pool with `threadsCount` threads.
 | 
			
		||||
 | 
			
		||||
		If a worker thread does not receive a task for `threadTimeout` seconds it
 | 
			
		||||
		is terminated.
 | 
			
		||||
	**/
 | 
			
		||||
	public function new(maxThreadsCount:Int, threadTimeout:Float = 60):Void {
 | 
			
		||||
		if(maxThreadsCount < 1)
 | 
			
		||||
			throw new ThreadPoolException('ElasticThreadPool needs maxThreadsCount to be at least 1.');
 | 
			
		||||
		this.maxThreadsCount = maxThreadsCount;
 | 
			
		||||
		this.threadTimeout = threadTimeout;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Submit a task to run in a thread.
 | 
			
		||||
 | 
			
		||||
		Throws an exception if the pool is shut down.
 | 
			
		||||
	**/
 | 
			
		||||
	public function run(task:()->Void):Void {
 | 
			
		||||
		if(_isShutdown)
 | 
			
		||||
			throw new ThreadPoolException('Task is rejected. Thread pool is shut down.');
 | 
			
		||||
		if(task == null)
 | 
			
		||||
			throw new ThreadPoolException('Task to run must not be null.');
 | 
			
		||||
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		var submitted = false;
 | 
			
		||||
		var deadWorker = null;
 | 
			
		||||
		for(worker in pool) {
 | 
			
		||||
			if(deadWorker == null && worker.dead) {
 | 
			
		||||
				deadWorker = worker;
 | 
			
		||||
			}
 | 
			
		||||
			if(worker.task == null) {
 | 
			
		||||
				submitted = true;
 | 
			
		||||
				worker.wakeup(task);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if(!submitted) {
 | 
			
		||||
			if(deadWorker != null) {
 | 
			
		||||
				deadWorker.wakeup(task);
 | 
			
		||||
			} else if(pool.length < maxThreadsCount) {
 | 
			
		||||
				var worker = new Worker(queue, threadTimeout);
 | 
			
		||||
				pool.push(worker);
 | 
			
		||||
				worker.wakeup(task);
 | 
			
		||||
			} else {
 | 
			
		||||
				queue.add(task);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Initiates a shutdown.
 | 
			
		||||
		All previousely submitted tasks will be executed, but no new tasks will
 | 
			
		||||
		be accepted.
 | 
			
		||||
 | 
			
		||||
		Multiple calls to this method have no effect.
 | 
			
		||||
	**/
 | 
			
		||||
	public function shutdown():Void {
 | 
			
		||||
		if(_isShutdown) return;
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		_isShutdown = true;
 | 
			
		||||
		for(worker in pool) {
 | 
			
		||||
			worker.shutdown();
 | 
			
		||||
		}
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function get_threadsCount():Int {
 | 
			
		||||
		var result = 0;
 | 
			
		||||
		for(worker in pool)
 | 
			
		||||
			if(!worker.dead)
 | 
			
		||||
				++result;
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private class Worker {
 | 
			
		||||
	public var task(default,null):Null<()->Void>;
 | 
			
		||||
	public var dead(default,null) = false;
 | 
			
		||||
 | 
			
		||||
	final deathMutex = new Mutex();
 | 
			
		||||
	final waiter = new Lock();
 | 
			
		||||
	final queue:Deque<()->Void>;
 | 
			
		||||
	final timeout:Float;
 | 
			
		||||
	var thread:Thread;
 | 
			
		||||
	var isShutdown = false;
 | 
			
		||||
 | 
			
		||||
	public function new(queue:Deque<()->Void>, timeout:Float) {
 | 
			
		||||
		this.queue = queue;
 | 
			
		||||
		this.timeout = timeout;
 | 
			
		||||
		start();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function wakeup(task:()->Void) {
 | 
			
		||||
		deathMutex.acquire();
 | 
			
		||||
		if(dead)
 | 
			
		||||
			start();
 | 
			
		||||
		this.task = task;
 | 
			
		||||
		waiter.release();
 | 
			
		||||
		deathMutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function shutdown() {
 | 
			
		||||
		isShutdown = true;
 | 
			
		||||
		waiter.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function start() {
 | 
			
		||||
		dead = false;
 | 
			
		||||
		thread = Thread.create(loop);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function loop() {
 | 
			
		||||
		try {
 | 
			
		||||
			while(waiter.wait(timeout)) {
 | 
			
		||||
				switch task {
 | 
			
		||||
					case null:
 | 
			
		||||
						if(isShutdown)
 | 
			
		||||
							break;
 | 
			
		||||
					case fn:
 | 
			
		||||
						fn();
 | 
			
		||||
						//if more tasks were added while all threads were busy
 | 
			
		||||
						while(true) {
 | 
			
		||||
							switch queue.pop(false) {
 | 
			
		||||
								case null: break;
 | 
			
		||||
								case fn: fn();
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						task = null;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			deathMutex.acquire();
 | 
			
		||||
			//in case a task was submitted right after the lock timed out
 | 
			
		||||
			if(task != null)
 | 
			
		||||
				start()
 | 
			
		||||
			else
 | 
			
		||||
				dead = true;
 | 
			
		||||
			deathMutex.release();
 | 
			
		||||
		} catch(e) {
 | 
			
		||||
			task = null;
 | 
			
		||||
			start();
 | 
			
		||||
			throw e;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										275
									
								
								Kha/Tools/macos/std/sys/thread/EventLoop.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								Kha/Tools/macos/std/sys/thread/EventLoop.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,275 @@
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	When an event loop has an available event to execute.
 | 
			
		||||
**/
 | 
			
		||||
enum NextEventTime {
 | 
			
		||||
	/** There's already an event waiting to be executed */
 | 
			
		||||
	Now;
 | 
			
		||||
	/** No new events are expected. */
 | 
			
		||||
	Never;
 | 
			
		||||
	/**
 | 
			
		||||
		An event is expected to arrive at any time.
 | 
			
		||||
		If `time` is specified, then the event will be ready at that time for sure.
 | 
			
		||||
	*/
 | 
			
		||||
	AnyTime(time:Null<Float>);
 | 
			
		||||
	/** An event is expected to be ready for execution at `time`. */
 | 
			
		||||
	At(time:Float);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	An event loop implementation used for `sys.thread.Thread`
 | 
			
		||||
**/
 | 
			
		||||
@:coreApi
 | 
			
		||||
class EventLoop {
 | 
			
		||||
	final mutex = new Mutex();
 | 
			
		||||
	final oneTimeEvents = new Array<Null<()->Void>>();
 | 
			
		||||
	var oneTimeEventsIdx = 0;
 | 
			
		||||
	final waitLock = new Lock();
 | 
			
		||||
	var promisedEventsCount = 0;
 | 
			
		||||
	var regularEvents:Null<RegularEvent>;
 | 
			
		||||
 | 
			
		||||
	public function new():Void {}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Schedule event for execution every `intervalMs` milliseconds in current loop.
 | 
			
		||||
	**/
 | 
			
		||||
	public function repeat(event:()->Void, intervalMs:Int):EventHandler {
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		var interval = 0.001 * intervalMs;
 | 
			
		||||
		var event = new RegularEvent(event, Sys.time() + interval, interval);
 | 
			
		||||
		inline insertEventByTime(event);
 | 
			
		||||
		waitLock.release();
 | 
			
		||||
		mutex.release();
 | 
			
		||||
		return event;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function insertEventByTime(event:RegularEvent):Void {
 | 
			
		||||
		switch regularEvents {
 | 
			
		||||
			case null:
 | 
			
		||||
				regularEvents = event;
 | 
			
		||||
			case current:
 | 
			
		||||
				var previous = null;
 | 
			
		||||
				while(true) {
 | 
			
		||||
					if(current == null) {
 | 
			
		||||
						previous.next = event;
 | 
			
		||||
						event.previous = previous;
 | 
			
		||||
						break;
 | 
			
		||||
					} else if(event.nextRunTime < current.nextRunTime) {
 | 
			
		||||
						event.next = current;
 | 
			
		||||
						current.previous = event;
 | 
			
		||||
						switch previous {
 | 
			
		||||
							case null:
 | 
			
		||||
								regularEvents = event;
 | 
			
		||||
								case _:
 | 
			
		||||
								event.previous = previous;
 | 
			
		||||
								previous.next = event;
 | 
			
		||||
								current.previous = event;
 | 
			
		||||
						}
 | 
			
		||||
						break;
 | 
			
		||||
					} else {
 | 
			
		||||
						previous = current;
 | 
			
		||||
						current = current.next;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Prevent execution of a previously scheduled event in current loop.
 | 
			
		||||
	**/
 | 
			
		||||
	public function cancel(eventHandler:EventHandler):Void {
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		var event:RegularEvent = eventHandler;
 | 
			
		||||
		event.cancelled = true;
 | 
			
		||||
		if(regularEvents == event) {
 | 
			
		||||
			regularEvents = event.next;
 | 
			
		||||
		}
 | 
			
		||||
		switch event.next {
 | 
			
		||||
			case null:
 | 
			
		||||
			case e: e.previous = event.previous;
 | 
			
		||||
		}
 | 
			
		||||
		switch event.previous {
 | 
			
		||||
			case null:
 | 
			
		||||
			case e: e.next = event.next;
 | 
			
		||||
		}
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Notify this loop about an upcoming event.
 | 
			
		||||
		This makes the thread to stay alive and wait for as many events as many times
 | 
			
		||||
		`.promise()` was called. These events should be added via `.runPromised()`
 | 
			
		||||
	**/
 | 
			
		||||
	public function promise():Void {
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		++promisedEventsCount;
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Execute `event` as soon as possible.
 | 
			
		||||
	**/
 | 
			
		||||
	public function run(event:()->Void):Void {
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		oneTimeEvents[oneTimeEventsIdx++] = event;
 | 
			
		||||
		waitLock.release();
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Add previously promised `event` for execution.
 | 
			
		||||
	**/
 | 
			
		||||
	public function runPromised(event:()->Void):Void {
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		oneTimeEvents[oneTimeEventsIdx++] = event;
 | 
			
		||||
		--promisedEventsCount;
 | 
			
		||||
		waitLock.release();
 | 
			
		||||
		mutex.release();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Executes all pending events.
 | 
			
		||||
 | 
			
		||||
		The returned time stamps can be used with `Sys.time()` for calculations.
 | 
			
		||||
 | 
			
		||||
		Depending on a target platform this method may be non-reentrant. It must
 | 
			
		||||
		not be called from event callbacks.
 | 
			
		||||
	**/
 | 
			
		||||
	public function progress():NextEventTime {
 | 
			
		||||
		return switch __progress(Sys.time(), [], []) {
 | 
			
		||||
			case {nextEventAt:-2}: Now;
 | 
			
		||||
			case {nextEventAt:-1, anyTime:false}: Never;
 | 
			
		||||
			case {nextEventAt:-1, anyTime:true}: AnyTime(null);
 | 
			
		||||
			case {nextEventAt:time, anyTime:true}: AnyTime(time);
 | 
			
		||||
			case {nextEventAt:time, anyTime:false}: At(time);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Blocks until a new event is added or `timeout` (in seconds) to expires.
 | 
			
		||||
 | 
			
		||||
		Depending on a target platform this method may also automatically execute arriving
 | 
			
		||||
		events while waiting. However if any event is executed it will stop waiting.
 | 
			
		||||
 | 
			
		||||
		Returns `true` if more events are expected.
 | 
			
		||||
		Returns `false` if no more events expected.
 | 
			
		||||
 | 
			
		||||
		Depending on a target platform this method may be non-reentrant. It must
 | 
			
		||||
		not be called from event callbacks.
 | 
			
		||||
	**/
 | 
			
		||||
	public function wait(?timeout:Float):Bool {
 | 
			
		||||
		return waitLock.wait(timeout);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Execute all pending events.
 | 
			
		||||
		Wait and execute as many events as many times `promiseEvent()` was called.
 | 
			
		||||
		Runs until all repeating events are cancelled and no more events is expected.
 | 
			
		||||
 | 
			
		||||
		Depending on a target platform this method may be non-reentrant. It must
 | 
			
		||||
		not be called from event callbacks.
 | 
			
		||||
	**/
 | 
			
		||||
	public function loop():Void {
 | 
			
		||||
		var recycleRegular = [];
 | 
			
		||||
		var recycleOneTimers = [];
 | 
			
		||||
		while(true) {
 | 
			
		||||
			var r = __progress(Sys.time(), recycleRegular, recycleOneTimers);
 | 
			
		||||
			switch r {
 | 
			
		||||
				case {nextEventAt:-2}:
 | 
			
		||||
				case {nextEventAt:-1, anyTime:false}:
 | 
			
		||||
					break;
 | 
			
		||||
				case {nextEventAt:-1, anyTime:true}:
 | 
			
		||||
					waitLock.wait();
 | 
			
		||||
				case {nextEventAt:time}:
 | 
			
		||||
					var timeout = time - Sys.time();
 | 
			
		||||
					waitLock.wait(Math.max(0, timeout));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		`.progress` implementation with a reusable array for internal usage.
 | 
			
		||||
		The `nextEventAt` field of the return value denotes when the next event
 | 
			
		||||
		is expected to run:
 | 
			
		||||
		* -1 - never
 | 
			
		||||
		* -2 - now
 | 
			
		||||
		* other values - at specified time
 | 
			
		||||
	**/
 | 
			
		||||
	inline function __progress(now:Float, recycleRegular:Array<RegularEvent>, recycleOneTimers:Array<()->Void>):{nextEventAt:Float, anyTime:Bool} {
 | 
			
		||||
		var regularsToRun = recycleRegular;
 | 
			
		||||
		var eventsToRunIdx = 0;
 | 
			
		||||
		// When the next event is expected to run
 | 
			
		||||
		var nextEventAt:Float = -1;
 | 
			
		||||
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		//reset waitLock
 | 
			
		||||
		while(waitLock.wait(0.0)) {}
 | 
			
		||||
		// Collect regular events to run
 | 
			
		||||
		var current = regularEvents;
 | 
			
		||||
		while(current != null) {
 | 
			
		||||
			if(current.nextRunTime <= now) {
 | 
			
		||||
				regularsToRun[eventsToRunIdx++] = current;
 | 
			
		||||
				current.nextRunTime += current.interval;
 | 
			
		||||
				nextEventAt = -2;
 | 
			
		||||
			} else if(nextEventAt == -1 || current.nextRunTime < nextEventAt) {
 | 
			
		||||
				nextEventAt = current.nextRunTime;
 | 
			
		||||
			}
 | 
			
		||||
			current = current.next;
 | 
			
		||||
		}
 | 
			
		||||
		mutex.release();
 | 
			
		||||
 | 
			
		||||
		// Run regular events
 | 
			
		||||
		for(i in 0...eventsToRunIdx) {
 | 
			
		||||
			if(!regularsToRun[i].cancelled) 
 | 
			
		||||
				regularsToRun[i].run();
 | 
			
		||||
			regularsToRun[i] = null;
 | 
			
		||||
		}
 | 
			
		||||
		eventsToRunIdx = 0;
 | 
			
		||||
 | 
			
		||||
		var oneTimersToRun = recycleOneTimers;
 | 
			
		||||
		// Collect pending one-time events
 | 
			
		||||
		mutex.acquire();
 | 
			
		||||
		for(i => event in oneTimeEvents) {
 | 
			
		||||
			switch event {
 | 
			
		||||
				case null:
 | 
			
		||||
					break;
 | 
			
		||||
				case _:
 | 
			
		||||
					oneTimersToRun[eventsToRunIdx++] = event;
 | 
			
		||||
					oneTimeEvents[i] = null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		oneTimeEventsIdx = 0;
 | 
			
		||||
		var hasPromisedEvents = promisedEventsCount > 0;
 | 
			
		||||
		mutex.release();
 | 
			
		||||
 | 
			
		||||
		//run events
 | 
			
		||||
		for(i in 0...eventsToRunIdx) {
 | 
			
		||||
			oneTimersToRun[i]();
 | 
			
		||||
			oneTimersToRun[i] = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Some events were executed. They could add new events to run.
 | 
			
		||||
		if(eventsToRunIdx > 0) {
 | 
			
		||||
			nextEventAt = -2;
 | 
			
		||||
		}
 | 
			
		||||
		return {nextEventAt:nextEventAt, anyTime:hasPromisedEvents}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract EventHandler(RegularEvent) from RegularEvent to RegularEvent {}
 | 
			
		||||
 | 
			
		||||
private class RegularEvent {
 | 
			
		||||
	public var nextRunTime:Float;
 | 
			
		||||
	public final interval:Float;
 | 
			
		||||
	public final run:()->Void;
 | 
			
		||||
	public var next:Null<RegularEvent>;
 | 
			
		||||
	public var previous:Null<RegularEvent>;
 | 
			
		||||
	public var cancelled:Bool = false;
 | 
			
		||||
 | 
			
		||||
	public function new(run:()->Void, nextRunTime:Float, interval:Float) {
 | 
			
		||||
		this.run = run;
 | 
			
		||||
		this.nextRunTime = nextRunTime;
 | 
			
		||||
		this.interval = interval;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								Kha/Tools/macos/std/sys/thread/FixedThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Kha/Tools/macos/std/sys/thread/FixedThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
import haxe.Exception;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	Thread pool with a constant amount of threads.
 | 
			
		||||
	Threads in the pool will exist until the pool is explicitly shut down.
 | 
			
		||||
**/
 | 
			
		||||
@:coreApi
 | 
			
		||||
class FixedThreadPool implements IThreadPool {
 | 
			
		||||
	/* Amount of threads in this pool. */
 | 
			
		||||
	public var threadsCount(get,null):Int;
 | 
			
		||||
	function get_threadsCount():Int return threadsCount;
 | 
			
		||||
 | 
			
		||||
	/** Indicates if `shutdown` method of this pool has been called. */
 | 
			
		||||
	public var isShutdown(get,never):Bool;
 | 
			
		||||
	var _isShutdown = false;
 | 
			
		||||
	function get_isShutdown():Bool return _isShutdown;
 | 
			
		||||
 | 
			
		||||
	final pool:Array<Worker>;
 | 
			
		||||
	final poolMutex = new Mutex();
 | 
			
		||||
	final queue = new Deque<()->Void>();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Create a new thread pool with `threadsCount` threads.
 | 
			
		||||
	**/
 | 
			
		||||
	public function new(threadsCount:Int):Void {
 | 
			
		||||
		if(threadsCount < 1)
 | 
			
		||||
			throw new ThreadPoolException('FixedThreadPool needs threadsCount to be at least 1.');
 | 
			
		||||
		this.threadsCount = threadsCount;
 | 
			
		||||
		pool = [for(i in 0...threadsCount) new Worker(queue)];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Submit a task to run in a thread.
 | 
			
		||||
 | 
			
		||||
		Throws an exception if the pool is shut down.
 | 
			
		||||
	**/
 | 
			
		||||
	public function run(task:()->Void):Void {
 | 
			
		||||
		if(_isShutdown)
 | 
			
		||||
			throw new ThreadPoolException('Task is rejected. Thread pool is shut down.');
 | 
			
		||||
		if(task == null)
 | 
			
		||||
			throw new ThreadPoolException('Task to run must not be null.');
 | 
			
		||||
		queue.add(task);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Initiates a shutdown.
 | 
			
		||||
		All previousely submitted tasks will be executed, but no new tasks will
 | 
			
		||||
		be accepted.
 | 
			
		||||
 | 
			
		||||
		Multiple calls to this method have no effect.
 | 
			
		||||
	**/
 | 
			
		||||
	public function shutdown():Void {
 | 
			
		||||
		if(_isShutdown) return;
 | 
			
		||||
		_isShutdown = true;
 | 
			
		||||
		for(_ in pool) {
 | 
			
		||||
			queue.add(shutdownTask);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static function shutdownTask():Void {
 | 
			
		||||
		throw new ShutdownException('');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private class ShutdownException extends Exception {}
 | 
			
		||||
 | 
			
		||||
private class Worker {
 | 
			
		||||
	var thread:Thread;
 | 
			
		||||
	final queue:Deque<Null<()->Void>>;
 | 
			
		||||
 | 
			
		||||
	public function new(queue:Deque<Null<()->Void>>) {
 | 
			
		||||
		this.queue = queue;
 | 
			
		||||
		thread = Thread.create(loop);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function loop() {
 | 
			
		||||
		try {
 | 
			
		||||
			while(true) {
 | 
			
		||||
				var task = queue.pop(true);
 | 
			
		||||
				task();
 | 
			
		||||
			}
 | 
			
		||||
		} catch(_:ShutdownException) {
 | 
			
		||||
		} catch(e) {
 | 
			
		||||
			thread = Thread.create(loop);
 | 
			
		||||
			throw e;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								Kha/Tools/macos/std/sys/thread/IThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Kha/Tools/macos/std/sys/thread/IThreadPool.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	A thread pool interface.
 | 
			
		||||
**/
 | 
			
		||||
interface IThreadPool {
 | 
			
		||||
 | 
			
		||||
	/** Amount of alive threads in this pool. */
 | 
			
		||||
	var threadsCount(get,never):Int;
 | 
			
		||||
 | 
			
		||||
	/** Indicates if `shutdown` method of this pool has been called. */
 | 
			
		||||
	var isShutdown(get,never):Bool;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Submit a task to run in a thread.
 | 
			
		||||
 | 
			
		||||
		Throws an exception if the pool is shut down.
 | 
			
		||||
	**/
 | 
			
		||||
	function run(task:()->Void):Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Initiates a shutdown.
 | 
			
		||||
		All previousely submitted tasks will be executed, but no new tasks will
 | 
			
		||||
		be accepted.
 | 
			
		||||
 | 
			
		||||
		Multiple calls to this method have no effect.
 | 
			
		||||
	**/
 | 
			
		||||
	function shutdown():Void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								Kha/Tools/macos/std/sys/thread/Lock.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								Kha/Tools/macos/std/sys/thread/Lock.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	A Lock allows blocking execution until it has been unlocked. It keeps track
 | 
			
		||||
	of how often `release` has been called, and blocks exactly as many `wait`
 | 
			
		||||
	calls.
 | 
			
		||||
 | 
			
		||||
	The order of the `release` and `wait` calls is irrelevant. That is, a Lock
 | 
			
		||||
	can be released before anyone waits for it. In that case, the `wait` call
 | 
			
		||||
	will execute immediately.
 | 
			
		||||
 | 
			
		||||
	Usage example:
 | 
			
		||||
 | 
			
		||||
	```haxe
 | 
			
		||||
	var lock = new Lock();
 | 
			
		||||
	var elements = [1, 2, 3];
 | 
			
		||||
	for (element in elements) {
 | 
			
		||||
		// Create one thread per element
 | 
			
		||||
		new Thread(function() {
 | 
			
		||||
			trace(element);
 | 
			
		||||
			Sys.sleep(1);
 | 
			
		||||
			// Release once per thread = 3 times
 | 
			
		||||
			lock.release();
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	for (_ in elements) {
 | 
			
		||||
		// Wait 3 times
 | 
			
		||||
		lock.wait();
 | 
			
		||||
	}
 | 
			
		||||
	trace("All threads finished");
 | 
			
		||||
	```
 | 
			
		||||
**/
 | 
			
		||||
extern class Lock {
 | 
			
		||||
	/**
 | 
			
		||||
		Creates a new Lock which is initially locked.
 | 
			
		||||
	**/
 | 
			
		||||
	function new():Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Waits for the lock to be released, or `timeout` (in seconds)
 | 
			
		||||
		to expire. Returns `true` if the lock is released and `false`
 | 
			
		||||
		if a time-out occurs.
 | 
			
		||||
	**/
 | 
			
		||||
	function wait(?timeout:Float):Bool;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Releases the lock once.
 | 
			
		||||
 | 
			
		||||
		The thread does not need to own the lock in order to release
 | 
			
		||||
		it. Each call to `release` allows exactly one call to `wait`
 | 
			
		||||
		to execute.
 | 
			
		||||
	**/
 | 
			
		||||
	function release():Void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								Kha/Tools/macos/std/sys/thread/Mutex.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Kha/Tools/macos/std/sys/thread/Mutex.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	Creates a mutex, which can be used to acquire a temporary lock
 | 
			
		||||
	to access some ressource. The main difference with a lock is
 | 
			
		||||
	that a mutex must always be released by the owner thread.
 | 
			
		||||
**/
 | 
			
		||||
extern class Mutex {
 | 
			
		||||
	/**
 | 
			
		||||
		Creates a mutex.
 | 
			
		||||
	**/
 | 
			
		||||
	function new():Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		The current thread acquire the mutex or wait if not available.
 | 
			
		||||
		The same thread can acquire several times the same mutex but
 | 
			
		||||
		must release it as many times it has been acquired.
 | 
			
		||||
	**/
 | 
			
		||||
	function acquire():Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Try to acquire the mutex, returns true if acquire or false
 | 
			
		||||
		if it's already locked by another thread.
 | 
			
		||||
	**/
 | 
			
		||||
	function tryAcquire():Bool;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Release a mutex that has been acquired by the current thread.
 | 
			
		||||
		The behavior is undefined if the current thread does not own
 | 
			
		||||
		the mutex.
 | 
			
		||||
	**/
 | 
			
		||||
	function release():Void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								Kha/Tools/macos/std/sys/thread/NoEventLoopException.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Kha/Tools/macos/std/sys/thread/NoEventLoopException.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
import haxe.Exception;
 | 
			
		||||
 | 
			
		||||
class NoEventLoopException extends Exception {
 | 
			
		||||
	public function new(msg:String = 'Event loop is not available. Refer to sys.thread.Thread.runWithEventLoop.', ?previous:Exception) {
 | 
			
		||||
		super(msg, previous);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								Kha/Tools/macos/std/sys/thread/Thread.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								Kha/Tools/macos/std/sys/thread/Thread.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
private typedef ThreadImpl = {};
 | 
			
		||||
 | 
			
		||||
extern abstract Thread(ThreadImpl) from ThreadImpl {
 | 
			
		||||
	/**
 | 
			
		||||
		Event loop of this thread (if available).
 | 
			
		||||
 | 
			
		||||
		Note that by default event loop is only available in the main thread.
 | 
			
		||||
		To setup an event loop in other threads use `sys.thread.Thread.runWithEventLoop`
 | 
			
		||||
		or create new threads with built-in event loops using `sys.thread.Thread.createWithEventLoop`
 | 
			
		||||
	**/
 | 
			
		||||
	public var events(get,never):EventLoop;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Send a message to the thread queue. This message can be read by using `readMessage`.
 | 
			
		||||
	**/
 | 
			
		||||
	public function sendMessage(msg:Dynamic):Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Returns the current thread.
 | 
			
		||||
	**/
 | 
			
		||||
	public static function current():Thread;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Creates a new thread that will execute the `job` function, then exit.
 | 
			
		||||
 | 
			
		||||
		This function does not setup an event loop for a new thread.
 | 
			
		||||
	**/
 | 
			
		||||
	public static function create(job:()->Void):Thread;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Simply execute `job` if current thread already has an event loop.
 | 
			
		||||
 | 
			
		||||
		But if current thread does not have an event loop: setup event loop,
 | 
			
		||||
		run `job` and then destroy event loop. And in this case this function
 | 
			
		||||
		does not return until no more events left to run.
 | 
			
		||||
	**/
 | 
			
		||||
	public static function runWithEventLoop(job:()->Void):Void;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		This is logically equal to `Thread.create(() -> Thread.runWithEventLoop(job));`
 | 
			
		||||
	**/
 | 
			
		||||
	public static function createWithEventLoop(job:()->Void):Thread;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Reads a message from the thread queue. If `block` is true, the function
 | 
			
		||||
		blocks until a message is available. If `block` is false, the function
 | 
			
		||||
		returns `null` if no message is available.
 | 
			
		||||
	**/
 | 
			
		||||
	public static function readMessage(block:Bool):Dynamic;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Run event loop of the current thread
 | 
			
		||||
	**/
 | 
			
		||||
	private static function processEvents():Void;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								Kha/Tools/macos/std/sys/thread/ThreadPoolException.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Kha/Tools/macos/std/sys/thread/ThreadPoolException.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
import haxe.Exception;
 | 
			
		||||
 | 
			
		||||
class ThreadPoolException extends Exception {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								Kha/Tools/macos/std/sys/thread/Tls.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Kha/Tools/macos/std/sys/thread/Tls.hx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C)2005-2019 Haxe Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
 * copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
 * to deal in the Software without restriction, including without limitation
 | 
			
		||||
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
 * and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
 * Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
 * DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package sys.thread;
 | 
			
		||||
 | 
			
		||||
#if (!target.threaded)
 | 
			
		||||
#error "This class is not available on this target"
 | 
			
		||||
#end
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
	Creates thread local storage.
 | 
			
		||||
 | 
			
		||||
	(hl) Warning: At the moment `Tls` does not protect the value from being
 | 
			
		||||
	garbage collected. Keep the value reachable to avoid crashes.
 | 
			
		||||
**/
 | 
			
		||||
extern class Tls<T> {
 | 
			
		||||
	var value(get, set):T;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
		Creates thread local storage. This is placeholder that can store
 | 
			
		||||
		a value that will be different depending on the local thread.
 | 
			
		||||
		Set the tls value to `null` before exiting the thread
 | 
			
		||||
		or the memory will never be collected.
 | 
			
		||||
	**/
 | 
			
		||||
	function new():Void;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user