Haxe 5 defaults to 1.15, but we're currently still bundling an older version. So we need to specify hl-ver or it won't work properly because Haxe 5 will produce code that older HashLink isn't compatible with.
If hl-ver is already specified, or if a custom HL_PATH is defined, does not set hl-ver because that may be undesirable.
Tested on macOS, Linux, and Windows. Works better with Haxe 5 than HashLink 1.12 did. This upgrade is easier than 1.14 and presumably 1.15, which we can still do later.
* Store the job's thread in `JobData`.
Since we're storing more and more in `JobData`, and the background thread only needs three bits of that data, I added those to `ThreadEvent` so we don't have to pass the full object. This may improve performance in HTML5 specifically, where passing a class instance incurs an overhead.
* Allow a single `ThreadPool` to run jobs in both modes.
* Remove unnecessary `@:forward.new`.
* Improve check for whether to call `Thread.returnMessage()`.
Now that thread pools can manage both types of job at once, we can't rely on `mode` to determine whether we're on a background thread. Honestly, I shouldn't have relied on it in the first place.
* Improve `ThreadPool.isMainThread()`.
No need to set `__mainThread` based on `isWorker()` when `isWorker()` already gives the information we're after.
* Correct and clarify documentation.
* Start new jobs immediately when a slot opens up.
For single-threaded jobs, this means a pool can now handle multiple per frame. For multi-threaded jobs, this only slightly reduces the delay between jobs.
* Fix missing function call.
* Add missing import.
Forgot this when overriding the "send" functions.
* Simplify comment.
It's a private variable, so all it really needs to do is mention the location it gets used.
* Don't count the main thread in `currentThreads`.
Plus, alphabetize the variables.
In 8.2.0, a single-threaded pool would report `currentThreads == 1` when running a job, meaning it counted the main thread. But in retrospect, this was both redundant (with `activeJobs`) and unexpected, so I'm counting it as a bug.
* Update documentation.
* Remove redundant check.
All the jobs in `__multiThreadedJobs` are already known to be running in multi-threaded mode. This is left over from when pools were locked to a single mode.
* Handle error case differently.
We still need to throw an error when `mode` is `MULTI_THREADED`, but this can now vary per job, so the check must happen during `run()`.
Also, the old error message was out of date. You can't pass a function to the `ThreadPool` constructor.
* Remove unnecessary `#if`s.
On other targets, it will return `true`, which will be inlined and optimized out. The conditional compilation just added clutter.
* Rewrite `ThreadPool` to use `Deque` on native targets.
Using the flag `lime_threads_deque` to distinguish between this and the old approach. Hopefully someday we can remove this flag, once we implement something akin to `Deque` in HTML5.
That aside, the hardest part is keeping track of the state of each thread. That's why there's so much more complexity: whenever the main thread sends a message to a worker, it needs to wait for confirmation, but also not send any more messages while waiting. And the code that tracks all this needs to work in both modes (with and without `Deque`).
* Bug fix: `firstLoop = false` can get skipped.
* Fix misplaced `#if`.
* Add missing `#if`.
* Make sure all events are received before removing the update listener.
After all jobs are done, threads will send `EXIT` events. These must be processed before removing `__update`, otherwise they'll linger in the queue until the next job starts.
* Keep better track of how many threads are idle.
Previously, while a thread was exiting, `ThreadPool` could think it was still idle. This would cause it not to spin up a new thread for the next job, leading to a pending job with no threads available to handle it.
* Remove redundant code.
* Fix null pointer error.
* Fix bugs in `cancel()` and `cancelJob()`.
* Don't shut down a `ThreadPool` while work events are queued.
Co-authored-by: Barış Yıldırım <25794892+barisyild@users.noreply.github.com>
* Add missing `#if`.
---------
Co-authored-by: Barış Yıldırım <25794892+barisyild@users.noreply.github.com>
Previously, it seemed that only Windows HashLink would hang when opening a FileDialog, but I was able to reproduce #1946 on Windows CPP too. Not sure why I couldn't before because I don't see any obvious changes to FileDialog or ThreadPool that would cause it to happen now, but not when it was affecting HashLink previously.
Does not seem to affect other operating systems.
We might consider going back to BackgroundWorker instead, which we used in Lime 8.1 and older.
openal-soft assumes that aligned_alloc is available with c++17. Newer
android ndks set c++17 by default, however they do not expose
aligned_alloc without setting min sdk version to 28.
We can avoid this issue by forcing openal to be compiled with c++11.
Also note, we have HXCPP_CPP11 defined, however, hxcpp ignores this for
the android toolchain. This means we must set it explicitly
See:
f5e0eef34d/common/almalloc.cpp (L15)
Hxcpp doesn't respect HXCPP_CPP11 for android. We can avoid this issue just by adding -std=c++11 here. This resolves a conflict with openal soft 1.20.1 for android builds. This works because the library assumes c++17 and invokes a function that isn't available in android sdk below 28.
clang: warning: include path for libstdc++ headers not found; pass '-stdlib=libc++' on the command line to use the libc++ standard library instead [-Wstdlibcxx-not-found]
This change moves away from purely hard coding the minimum sdk version for android and also correctly sets the PLATFORM_NUMBER define. The gcc toolchain is no longer compatible in lime 8.3.x+ so, we shouldn't have to worry about the PLATFORM define at all.
It might be wise to enforce a baseline minimum version and complain if users try to use something lower than the default.
If the text is invalid, then readNextChar returns -1 and does not
progress to the next character. This previously meant that we got stuck
and looped indefinitely.
Previously, the first for loop would reach the end of the characters, so
no further characters were read in the second loop. This meant that the
array remained filled with 0 values.