vegardit / haxe-concurrent Goto Github PK
View Code? Open in Web Editor NEWA haxelib for basic platform-agnostic concurrency support
Home Page: https://vegardit.github.io/haxe-concurrent/
License: Apache License 2.0
A haxelib for basic platform-agnostic concurrency support
Home Page: https://vegardit.github.io/haxe-concurrent/
License: Apache License 2.0
Hi,
I'm trying to use the executor
but I can't find a way to wait for execution to complete, all the examples from the readme are not contained so I can't reproduce any.
Do you have a simple working example besides the test file?
Thanks
Hello,
Appologies if the issue ends up not being in your library, I'm trying to debug a memory leak in a larger program and have managed to reproduce it in a small sample, just thought I'd run it past you first.
import haxe.io.Bytes;
import hx.concurrent.executor.Executor;
function main()
{
final executor = Executor.create(4);
final futures = genFutures(executor);
while (true)
{
switch Sys.stdin().readLine()
{
case 'exit':
return;
case 'free':
for (future in futures)
{
future.cancel();
}
futures.resize(0);
trace(cpp.vm.Gc.memUsage());
cpp.vm.Gc.run(true);
trace(cpp.vm.Gc.memUsage());
case _:
//
}
}
}
function genFutures(_executor : Executor)
{
return [
for (_ in 0...10)
{
final bytes = Bytes.alloc(4096 * 4096 * 4);
_executor.submit(() -> {
trace('captured a bytes object with ${ bytes.length } bytes');
});
}
];
}
With the above program the 10 bytes objects are never collected by the GC, I've had a quick look through the threaded executor and thread pool class and it doesn't seem like they hold references to the futures after they've been ran so I'm not sure as to why the bytes objects are not collected.
My understanding is that the closure passed to the submit function will capture the bytes object, and since nothing else has a reference to it (and they won't be on the stack after the function returns) they should be eligiable for collection after the future is completed.
While the debug info and forced GC running is hxcpp specific I get the same behaviour on hashlink. I was kind of hoping writing this all out would help me understand the issue a bit more but I'm still not sure, I could just be mis-understanding how GCs work with closures. In any case it would be good to get a confirmation that the executor shouldn't be holding a reference to anything in this case.
Cheers!
Python 3.7 has marked await and async as reserved words. Threads.await (and latch) will no longer run on systems using that. await needs to be renamed either for all platforms or just python to work properly.
Created a fork with "a" fix but might not be the best.
https://github.com/azupko/haxe-concurrent
I'm sure this cropped up already, the default git settings for line endings in linux make the LICENSE.txt
an uncommited change no matter what you do.
Fix is vegardit/haxe-files#5 (comment)
There are just one statement in main:
Executor.create(1);
Lock was aquired by another thread!
Called from hx.concurrent.lock.RLock.release (hx/concurrent/lock/RLock.hx line 201)
Called from hx.concurrent.atomic._AtomicInt.AtomicIntImpl.incrementAndGet (hx/concurrent/atomic/AtomicInt.hx line 158)
Called from hx.concurrent.$ServiceBase.__constructor__ (hx/concurrent/Service.hx line 56)
Called from hx.concurrent.executor.$Executor.__constructor__ (hx/concurrent/executor/Executor.hx line 19)
Called from hx.concurrent.executor.$ThreadPoolExecutor.__constructor__ (hx/concurrent/executor/ThreadPoolExecutor.hx line 40)
Called from hx.concurrent.executor.$Executor.create (hx/concurrent/executor/Executor.hx line 31)
Called from com.test.$ClientHeaps.main (com/test/ClientHeaps.hx line 28)
Hi,
there is a problem with package naming,
In source code it is
package hx.concurrent;
import hx.concurrent.lock.RLock;
and in physical folder it is:
src/hx/concurrent
because of this none of the IDE's are able to recognize classes.
Intellij will add the imports but can't recognize the classes. [cpp]
Flash Develop can't read the lib. [OpenFl]
what i did to solve :
just moved the hx pacakge out of src folder at library path.
hx/concurrent
now the Intellij is able to recognize everything but in Flash Develop i had to add
the lib to the Global Class paths.
thanks.
I've incorporated this haxelib into a project that I'm working on which is currently targeting Java, and I was wondering how you were intending on the threads
flag to be set: whether the haxelib has some magic that handles this on its own, or if I should be manually adding the -D threads
argument in my build file (or using the hx.concurrent.internal.Macros.addDefines()
macro).
Basically, is the intention that I add the flag myself to builds that I know can handle threads, or is this something that should be handled by the haxelib - and if the latter, what's the right way to trigger this? I'm setting it manually right now and it seems to be working well.
The following error occurs during compilation of any project which includes hx.concurrent.lock.RLock
, even a minimal one.,
Error: ./src/hx/concurrent/lock/RLock.cpp: In static member function ‘static Dynamic hx::concurrent::lock::RLock_obj::__CreateEmpty()’:
./src/hx/concurrent/lock/RLock.cpp:47:49: error: invalid new-expression of abstract class type ‘hx::concurrent::lock::RLock_obj’
47 | Dynamic RLock_obj::__CreateEmpty() { return new RLock_obj; }
| ^~~~~~~~~
In file included from ./src/hx/concurrent/lock/RLock.cpp:13:
include/hx/concurrent/lock/RLock.h:21:30: note: because the following virtual functions are pure within ‘hx::concurrent::lock::RLock_obj’:
21 | class HXCPP_CLASS_ATTRIBUTES RLock_obj : public ::hx::concurrent::lock::AbstractAcquirable_obj
| ^~~~~~~~~
In file included from ./src/hx/concurrent/lock/RLock.cpp:7:
include/hx/concurrent/lock/AbstractAcquirable.h:48:30: note: ‘virtual bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)’
48 | virtual bool tryAcquire(int timeoutMS) = 0;
| ^~~~~~~~~~
./src/hx/concurrent/lock/RLock.cpp: In static member function ‘static Dynamic hx::concurrent::lock::RLock_obj::__Create(hx::DynamicArray)’:
./src/hx/concurrent/lock/RLock.cpp:53:65: error: invalid new-expression of abstract class type ‘hx::concurrent::lock::RLock_obj’
53 | ::hx::ObjectPtr< RLock_obj > _hx_result = new RLock_obj();
| ^
./src/hx/concurrent/lock/RLock.cpp: In static member function ‘static hx::ObjectPtr<hx::concurrent::lock::RLock_obj> hx::concurrent::lock::RLock_obj::__new()’:
./src/hx/concurrent/lock/RLock.cpp:211:61: error: invalid new-expression of abstract class type ‘hx::concurrent::lock::RLock_obj’
211 | ::hx::ObjectPtr< RLock_obj > __this = new RLock_obj();
| ^
./src/hx/concurrent/lock/RLock.cpp: In static member function ‘static void hx::concurrent::lock::RLock_obj::__register()’:
./src/hx/concurrent/lock/RLock.cpp:356:19: error: cannot declare variable ‘_hx_dummy’ to be of abstract type ‘hx::concurrent::lock::RLock_obj’
356 | RLock_obj _hx_dummy;
| ^~~~~~~~~
Building with HXCPP on the Linux platform.
Hello,
I’ve just opened this issue about haxe-concurent in Android. I don’t think the problem is due to a flaw in the library, but maybe you have some clues.
This issue is similar to that of #21, however after revisiting the issue recently and finding that the Travix tests function properly, I decided to perform a more thorough investigation.
As a result, I discovered the issue and have developed a minimal reproduction and provided additional logs.
The core issue is, I believe, with the lime
framework, whose purpose is to provide additional utilities for cross-platform development, such as common interfaces for functionality like rendering. This library supercedes the build tools provided by Haxe, and some of the command line arguments it adds may be causing these build problems.
I was able to reproduce my problems with the following steps:
haxelib install lime
)lime create HelloWorld
)project.xml
and add the haxelib (<haxelib name="haxe-concurrent" />
)Main.hx
to use the library (I simply added code which instantiates a RLock
and nothing else)lime build windows
)The build fails with an error relating to methods of an abstract class. I am not an expert in C++ compilation but my theory is that the issue arises from one of the build flags enforced by Lime.
I have uploaded the project where I reproduced the issue to GitHub Below are the full logs from the build process:
Executing task: lime build windows --connect 6001
C:/HaxeToolkit/Haxe425/haxe/lib/haxe-concurrent/4,0,0/src/hx/concurrent/internal/Macros.hx:35: [INFO] Setting compiler define 'threads'.
Creating D:/Programming/Haxe/Lime-HelloWorld/Export/windows/obj/obj/msvc1964-nc/__pch/haxe/hxcpp.pch...
hxcpp.cpp
Compiling group: haxe
cl.exe -Iinclude -nologo /WX- /fp:precise -DHX_WINDOWS -GR -O2(optim-std) -Zi(debug) -FdD:\Programming\Haxe\Lime-HelloWorld\Export\windows\obj\obj/msvc1964-nc/vc.pdb(debug) -Od(debug) -O2(release) -Os(optim-size) -FS -Oy- -c -EHs -GS- -IC:/HaxeToolkit/Haxe425/haxe/lib/hxcpp/4,2,1/include -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS(haxe) -DHX_SMART_STRINGS(haxe) -DHXCPP_API_LEVEL=400(haxe) -D_CRT_SECURE_NO_DEPRECATE -D_ALLOW_MSC_VER_MISMATCH -D_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH -DHX_WIN_MAIN(main) -wd4996 ... tags=[haxe,static]
- src/lime/app/_Event_lime_ui_Window_Void.cpp [haxe,release]
- src/lime/media/openal/_ALAuxiliaryEffectSlot/ALAuxiliaryEffectSlot_Impl_.cpp
- src/lime/system/SensorType.cpp
- src/sys/io/_Process/Stdout.cpp
- src/lime/_internal/backend/native/TextEventInfo.cpp
- src/lime/graphics/cairo/_CairoFontOptions/CairoFontOptions_Impl_.cpp
- src/lime/math/Rectangle.cpp [haxe,release]
- src/sys/FileSystem.cpp
- src/lime/graphics/opengl/ext/EXT_multi_draw_arrays.cpp
- src/lime/utils/_Int32Array/Int32Array_Impl_.cpp
- src/lime/media/openal/ALC.cpp [haxe,release]
- src/haxe/ValueException.cpp
- src/lime/media/openal/_ALContext/ALContext_Impl_.cpp
- src/lime/graphics/opengl/ext/EXT_debug_marker.cpp
- src/lime/system/_ThreadPool/ThreadPoolMessage.cpp
- src/lime/app/_Future/FutureWork.cpp [haxe,release]
- src/lime/_internal/backend/native/WindowEventInfo.cpp
- src/lime/graphics/opengl/ext/OES_vertex_half_float.cpp
- src/haxe/StackItem.cpp
- src/lime/app/Promise.cpp [haxe,release]
- src/lime/_internal/backend/native/MouseEventInfo.cpp
- src/lime/graphics/opengl/ext/NV_fence.cpp
- src/lime/_internal/macros/AssetsMacro.cpp
- src/lime/graphics/opengl/ext/EXT_texture_format_BGRA8888.cpp
- src/haxe/crypto/BaseCode.cpp
- src/lime/graphics/opengl/ext/OES_surfaceless_context.cpp
- src/lime/_internal/format/LZMA.cpp [haxe,release]
- src/lime/graphics/opengl/ext/APPLE_texture_format_BGRA8888.cpp
- src/lime/graphics/cairo/_CairoFontFace/CairoFontFace_Impl_.cpp
- src/lime/graphics/opengl/ext/QCOM_binning_control.cpp
- src/lime/graphics/opengl/_GLBuffer/GLBuffer_Impl_.cpp
- src/lime/app/_Event_lime_graphics_RenderContext_Void.cpp [haxe,release]
- src/lime/graphics/opengl/ext/OES_depth_texture.cpp
- src/lime/graphics/opengl/ext/OES_standard_derivatives.cpp
- src/__boot__.cpp
- src/lime/ui/_GamepadAxis/GamepadAxis_Impl_.cpp
- src/lime/system/_ThreadPool/ThreadPoolMessageType.cpp
- src/lime/graphics/opengl/ext/EXT_color_buffer_float.cpp
- src/lime/graphics/opengl/ext/DMP_shader_binary.cpp
- src/Std.cpp
- src/sys/thread/_Thread/HaxeThread.cpp
- src/lime/net/curl/CURLMultiMessage.cpp
- src/lime/graphics/opengl/ext/EXT_shader_texture_lod.cpp
- src/lime/graphics/Image.cpp [haxe,release]
- src/lime/utils/Preloader.cpp [haxe,release]
- src/lime/graphics/_OpenGLES3RenderContext/OpenGLES3RenderContext_Impl_.cpp
- src/lime/media/WebAudioContext.cpp
- src/lime/graphics/opengl/ext/APPLE_texture_max_level.cpp
- src/lime/graphics/_WebGL2RenderContext/WebGL2RenderContext_Impl_.cpp
- src/haxe/NativeStackTrace.cpp
- src/sys/thread/_EventLoop/RegularEvent.cpp
- src/lime/utils/AssetManifest.cpp [haxe,release]
- src/lime/text/GlyphMetrics.cpp [haxe,release]
- src/ValueType.cpp
- src/lime/media/FlashAudioContext.cpp
- src/lime/math/_BGRA/BGRA_Impl_.cpp
- src/lime/graphics/opengl/ext/QCOM_writeonly_rendering.cpp
- src/lime/_internal/backend/native/NativeCFFI.cpp [haxe,release]
- src/lime/math/Vector4.cpp [haxe,release]
- src/lime/graphics/opengl/ext/OES_mapbuffer.cpp
- src/lime/_internal/graphics/StackBlur.cpp
- src/haxe/Exception.cpp
- src/lime/graphics/opengl/ext/VIV_shader_binary.cpp
- src/lime/_internal/format/BMP.cpp [haxe,release]
- src/lime/_internal/backend/native/RenderEventInfo.cpp
- src/haxe/io/Input.cpp
- src/lime/system/JNIStaticField.cpp [haxe,release]
- src/lime/graphics/opengl/ext/OES_compressed_ETC1_RGB8_texture.cpp
- src/lime/system/_CFFIPointer/CFFIPointer_Impl_.cpp
- src/lime/media/vorbis/VorbisFile.cpp
- src/lime/media/openal/AL.cpp [haxe,release]
- src/lime/graphics/opengl/ext/OES_depth32.cpp
- src/lime/media/openal/_ALEffect/ALEffect_Impl_.cpp
- src/lime/graphics/opengl/ext/OES_texture_half_float_linear.cpp
- src/lime/graphics/opengl/ext/EXT_debug_label.cpp
- src/lime/utils/_Int8Array/Int8Array_Impl_.cpp
- src/lime/app/_Event_Int_lime_ui_JoystickHatPosition_Void.cpp [haxe,release]
- src/lime/ui/_ScanCode/ScanCode_Impl_.cpp
- src/lime/media/openal/_ALFilter/ALFilter_Impl_.cpp
- src/lime/utils/_Assets/LibrarySymbol.cpp [haxe,release]
- src/lime/graphics/opengl/ext/EXT_texture_filter_anisotropic.cpp
- src/Date.cpp
- src/lime/media/OpenALAudioContext.cpp [haxe,release]
- src/lime/graphics/opengl/ext/ANGLE_texture_compression_dxt5.cpp
- src/lime/app/_Event_lime_ui_GamepadButton_Void.cpp [haxe,release]
- src/lime/app/_Event_lime_ui_GamepadAxis_Float_Void.cpp [haxe,release]
- src/lime/system/JNIMethod.cpp [haxe,release]
- src/lime/media/AudioManager.cpp [haxe,release]
- src/haxe/io/Eof.cpp
- src/lime/graphics/opengl/ext/OES_EGL_image_external.cpp
- src/lime/_internal/format/PNG.cpp [haxe,release]
- src/lime/media/openal/_ALDevice/ALDevice_Impl_.cpp
- src/lime/utils/_Bytes/Bytes_Impl_.cpp
- src/lime/ui/Gamepad.cpp [haxe,release]
- src/lime/graphics/opengl/ext/EXT_multisampled_render_to_texture.cpp
- src/lime/graphics/opengl/ext/EXT_texture_type_2_10_10_10_REV.cpp
- src/lime/net/_HTTPRequest_lime_graphics_Image.cpp [haxe,release]
- src/lime/graphics/opengl/ext/ARM_rgba8.cpp
- src/haxe/ds/_List/ListNode.cpp
- src/haxe/Unserializer.cpp
- src/lime/graphics/RenderContext.cpp
- src/lime/utils/_UInt32Array/UInt32Array_Impl_.cpp
- src/lime/utils/Log.cpp [haxe,release]
- src/haxe/ds/List.cpp
- src/hx/concurrent/lock/RLock.cpp
- src/lime/app/_Event_Float_Float_lime_ui_MouseButton_Void.cpp [haxe,release]
Error: RLock.cpp
./src/hx/concurrent/lock/RLock.cpp(45): error C2259: 'hx::concurrent::lock::RLock_obj': cannot instantiate abstract class
include\hx/concurrent/lock/RLock.h(21): note: see declaration of 'hx::concurrent::lock::RLock_obj'
./src/hx/concurrent/lock/RLock.cpp(45): note: due to following members:
./src/hx/concurrent/lock/RLock.cpp(45): note: 'bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)': is abstract
include\hx/concurrent/lock/AbstractAcquirable.h(48): note: see declaration of 'hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire'
./src/hx/concurrent/lock/RLock.cpp(45): error C2259: 'hx::concurrent::lock::RLock_obj': cannot instantiate abstract class
include\hx/concurrent/lock/RLock.h(21): note: see declaration of 'hx::concurrent::lock::RLock_obj'
./src/hx/concurrent/lock/RLock.cpp(45): note: due to following members:
./src/hx/concurrent/lock/RLock.cpp(45): note: 'bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)': is abstract
include\hx/concurrent/lock/AbstractAcquirable.h(48): note: see declaration of 'hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire'
./src/hx/concurrent/lock/RLock.cpp(51): error C2259: 'hx::concurrent::lock::RLock_obj': cannot instantiate abstract class
include\hx/concurrent/lock/RLock.h(21): note: see declaration of 'hx::concurrent::lock::RLock_obj'
./src/hx/concurrent/lock/RLock.cpp(51): note: due to following members:
./src/hx/concurrent/lock/RLock.cpp(51): note: 'bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)': is abstract
include\hx/concurrent/lock/AbstractAcquirable.h(48): note: see declaration of 'hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire'
./src/hx/concurrent/lock/RLock.cpp(189): error C2259: 'hx::concurrent::lock::RLock_obj': cannot instantiate abstract class
include\hx/concurrent/lock/RLock.h(21): note: see declaration of 'hx::concurrent::lock::RLock_obj'
./src/hx/concurrent/lock/RLock.cpp(189): note: due to following members:
./src/hx/concurrent/lock/RLock.cpp(189): note: 'bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)': is abstract
include\hx/concurrent/lock/AbstractAcquirable.h(48): note: see declaration of 'hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire'
./src/hx/concurrent/lock/RLock.cpp(334): error C2259: 'hx::concurrent::lock::RLock_obj': cannot instantiate abstract class
include\hx/concurrent/lock/RLock.h(21): note: see declaration of 'hx::concurrent::lock::RLock_obj'
./src/hx/concurrent/lock/RLock.cpp(334): note: due to following members:
./src/hx/concurrent/lock/RLock.cpp(334): note: 'bool hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire(int)': is abstract
include\hx/concurrent/lock/AbstractAcquirable.h(48): note: see declaration of 'hx::concurrent::lock::AbstractAcquirable_obj::tryAcquire'
* The terminal process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command lime build windows --connect 6001" terminated with exit code: 1.
* Terminal will be reused by tasks, press any key to close it.
When I run my tests with haxe-concurrent 5.1.3 and haxe 4.3.1, I get the following error. However if I compile the same tests with haxe 4.3-rc.1, they work fine.
Unfortunately I am not able to reproduce the error by means of a simple test, but the basic execution flow is trivial: I create an instance of Executor in a static variable and, when I try to call the method submit on it from the method Test.delay, the exception ExceptionInInitializerError is thrown.
java.lang.ExceptionInInitializerError
at utest.Test.delay(test-util/utest/Test.hx:152)
at utest.Runner.runCurrent(test-util/utest/Runner.hx:129)
at utest.Runner.gotoFirstTest(test-util/utest/Runner.hx:85)
at utest.Runner$Closure_evtRun_0.invoke(test-util/utest/Runner.hx:60)
at utest.Runner$Closure_evtRun_0.invoke(test-util/utest/Runner.hx)
at hx.concurrent.lock.AbstractAcquirable.execute(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/lock/Acquirable.hx:55)
at utest.Runner.evtRun(test-util/utest/Runner.hx:55)
at utest.Runner$Closure_run_0.invoke(test-util/utest/Runner.hx:52)
at utest.Runner$Closure_run_0.invoke(test-util/utest/Runner.hx)
at hx.concurrent.lock.AbstractAcquirable.execute(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/lock/Acquirable.hx:55)
at utest.Runner.run(test-util/utest/Runner.hx:50)
at haxe.root.TestAll.main(test/TestAll.hx:93)
at haxe.root.TestAll.main(test/TestAll.hx:1)
Caused by: java.lang.ClassCastException: class hx.concurrent.thread.ThreadPool$Closure_onStart_0 cannot be cast to class java.lang.Runnable (hx.concurrent.thread.ThreadPool$Closure_onStart_0 is in unnamed module of loader 'app'; java.lang.Runnable is in module java.base of loader 'bootstrap')
at sys.thread.Thread$NativeHaxeThread.<init>(/Users/acarioni/haxe/versions/4.3.1/std/java/_std/sys/thread/Thread.hx:160)
at sys.thread.Thread$HaxeThread.create(/Users/acarioni/haxe/versions/4.3.1/std/java/_std/sys/thread/Thread.hx:104)
at hx.concurrent.thread.ThreadPool.onStart(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/thread/ThreadPool.hx:102)
at hx.concurrent.ServiceBase$Closure_start_0.invoke(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/Service.hx:65)
at hx.concurrent.ServiceBase$Closure_start_0.invoke(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/Service.hx)
at hx.concurrent.lock.AbstractAcquirable.execute(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/lock/Acquirable.hx:55)
at hx.concurrent.ServiceBase.start(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/Service.hx:58)
at hx.concurrent.thread.ThreadPool.<init>(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/thread/ThreadPool.hx:61)
at hx.concurrent.executor.ThreadPoolExecutor.<init>(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/executor/ThreadPoolExecutor.hx:41)
at hx.concurrent.executor.Executor.create(/Users/acarioni/haxe/haxe_libraries/haxe-concurrent/5.1.3/haxelib/src/hx/concurrent/executor/Executor.hx:36)
at utest.Test$Test_Fields_.<clinit>(test-util/utest/Test.hx:10)
... 13 more
Hi,
I'm just curious why you've chosen to use a spin lock on the thread pool implementation (with a short sleep). For games, a sleep of 0.001 seconds can be a very long time.
Im trying to learn the haxe-concurrent with OpenFL and it looks like I got some porting issues. The following code is self explanatory, create a bunch of threads with random as a test. On completion the code outputs the two times so I can see if working with multithreading is even worth it with my upcoming projects.
https://github.com/FlashBacks1998/haxe-concurrent-test
package;
import hx.concurrent.atomic.AtomicInt;
import hx.concurrent.Future;
import openfl.Lib;
import hx.concurrent.collection.SynchronizedArray;
import openfl.display.Sprite;
import openfl.text.TextField;
import hx.concurrent.executor.Executor;
class Main extends Sprite
{
var executor:Executor = Executor.create(16);
var label:TextField;
public function new()
{
super();
executor.start();
trace(executor.state);
var array = new SynchronizedArray<Float>();
var done = new AtomicInt();
var futures = [];
var task = function ():Void {
var start = Lib.getTimer();
var rand = Math.random() * 10000;
do {
rand = Math.random() * 10000;
} while (rand > 10);
array.add(rand);
var progress = (done.incrementAndGet()/10);
trace("task", progress, Lib.getTimer() - start, rand);
}
var start = Lib.getTimer();
trace("submitting...");
for (i in 0...1000)
{
futures.push(executor.submit(task));
trace(i);
}
trace("waiting...");
var result = executor.submit(task);
trace(result);
do {
trace(done.toString());
} while (!result.isComplete());
var endConcurrent = Lib.getTimer() - start;
trace("haxe-concurrent done", endConcurrent);
start = Lib.getTimer();
for (i in 0...1000)
task();
var endNative = Lib.getTimer() - start;
trace("native done", endNative);
// Display times in a TextField
label = new TextField();
label.text = "haxe-concurrent: " + endConcurrent + " ms\nnative: " + endNative + " ms";
label.y = 50; // Adjust the vertical position of the label
addChild(label);
trace(futures);
}
}
Ports to Windows, Linux, Neko, and HL works as intended. However when porting to HTML5 none of the tasks submitted to the executor actually work. I konw this because the done
value never increments. When porting to Flash (RUFFLE) I get this error message;
2024-02-01T18:39:50.345837Z ERROR ruffle_core::display_object::movie_clip: Got "Error: Error #1520: Mutex cannot be initialized." when constructing AVM2 side of movie clip of type boot_0453
. When using the native Flash player (v32)
Error: Error #1502: A script has executed for longer than the default timeout period of 15 seconds.
at Main()
at DocumentClass()
at ApplicationMain$/start()
at MethodInfo-99()
at lime.app::_Event_Void_Void/dispatch()
at openfl.display::Preloader/display_onUnload()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at openfl.display::DefaultPreloader/onLoaded()
at openfl.display::DefaultPreloader/this_onComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at openfl.display::Preloader/start()
at MethodInfo-98()
at lime.app::_Event_Void_Void/dispatch()
at lime.utils::Preloader/start()
at lime.utils::Preloader/updateProgress()
at lime.utils::Preloader/current_onEnter()
What is going on? Where is the code breaking?
I am using the hx.concurrent.event
package to implement a wrapper for an EventEmitter based on the Javascript EventEmitter API.
This is my implementation
class EventEmitter {
final signals:Map<String, SyncEventDispatcher<haxe.Rest<Any>>>;
final one_signals:Map<String, SyncEventDispatcher<haxe.Rest<Any>>>;
final one_listeners:Map<String, Array<(...v:Any) -> Void>>;
// static final executor:Executor = Executor.create(2);
public function new() {
signals = new Map();
one_signals = new Map();
one_listeners = new Map();
}
public function setMaxListeners(count:Int) {
// maxListeners = count;
}
public function on(name:String, callback:(...v:Any) -> Void) {
var asyncDispatcher = new SyncEventDispatcher<haxe.Rest<Any>>();
if (signals.exists(name)) {
signals.get(name).subscribe(callback);
} else {
asyncDispatcher.subscribe(callback);
signals.set(name, asyncDispatcher);
}
}
public function once(name:String, callback:(...v:Any) -> Void) {
var asyncDispatcher = new SyncEventDispatcher<haxe.Rest<Any>>();
asyncDispatcher.subscribe(callback);
if (one_signals.exists(name)) {
var s = one_signals.get(name);
s.subscribe(callback);
} else {
asyncDispatcher.subscribe(callback);
one_signals.set(name, asyncDispatcher);
}
if(one_listeners.exists(name)){
var l = one_listeners.get(name);
l.push(callback);
} else {
one_listeners.set(name, [callback]);
}
}
public function emit(name:String, ...v:Any) {
if (signals.exists(name)) {
final signal = signals.get(name);
signal.fire(...v);
}
if(one_signals.exists(name)){
final one_signal = one_signals.get(name);
var s = one_signal.fire(...v);
s.onResult = (result:FutureResult<Int>)->{
switch result {
case SUCCESS(result, time, future):{
one_signal.unsubscribe(one_listeners[name][result-1]);
one_signals.remove(name);
}
case FAILURE(ex, _): trace('Event could not be delivered because of: $ex');
case _:
}
};
}
}
}
when I use eventEmitter.once
function, an older listener still fires in another call. How do I ensure that a listener can only be fired one?
Hi, just found this library and it seems great. Was just wondering if there are plans to implement a Concurrent Map?
When working with the ThreadPool
on Hashlink the error below gets raised. This happens after the submitted tasks are executed.
src/gc.c(232) : FATAL ERROR : Can't lock GC in unregistered thread
OS: MacOS Catalina
Haxe version: 4.2.1+bf9ff69
Hashlink version: 1.12.0 (Github master)
Any ideas? Thanks in advance!
haxe-concurrent prints some logs when it starts up (e.g. hx/concurrent/Service.hx:56: [hx.concurrent.executor.TimerExecutor#1] instantiated). Since I include haxe-concurrent in a library of mine, which I then give to customers, they get worried when they see some unexpected messages on the console.
Is it possible to avoid these logs?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.