haxe
haxe copied to clipboard
Eval's EventLoop works better if I delete it
I've noticed that by deleting this file, the coroutine tests for eval go from failing spectacularly to passing. This made me remember that I came across this before and asked @RealyUniqueName about it on Slack:
simn: 09:17 @realyuniquename I'm trying to look into this MainLoop business. Something that seems wrong is that the eval implementation (https://github.com/HaxeFoundation/haxe/blob/development/std/eval/_std/sys/thread/EventLoop.hx) never calls MainLoop.tick, whereas the general implementation (https://github.com/HaxeFoundation/haxe/blob/development/std/sys/thread/EventLoop.hx#L260) does. I'm now trying to understand where this should be called.
simn: 09:18 It's called in __progress, which is called from both progress and loop. And it's only called if (isMainThread), which is something the eval implementation doesn't currently have.
simn: 09:19 I'm having some trouble understanding how exactly this should interact with libuv
simn: 09:20 So any advice is appreciated!
realyuniquename: 09:31 I don't remember exactly, but EntryPoint also calls MainLoop.tick. And EntryPoint.run is inserted by the compiler somewhere near the static main call.
realyuniquename: 09:31 So maybe for eval it's not necessary to call MainLoop.tick from the eventloop
realyuniquename: 09:32 This MainLoop/EntryPoint/EventLoop relationship may be quite confusing for various targets.
simn: 09:39 Yes I have absolutely no idea who's supposed to be doing what there...
simn: 09:42 Do you mean this? https://github.com/HaxeFoundation/haxe/blob/development/std/haxe/EntryPoint.hx#L116 Because that seems to be in the #else of an #if target.threaded, so it wouldn't be active on eval.
realyuniquename: 10:21 Ah, that used to work in a different way: https://github.com/HaxeFoundation/haxe/commit/f06078a2e11895f60d21bccd793ae59bcb0632c6#diff-0fad0e326002cc0420a695052be93c4ebac0136f598f014e380c6a0246958feaL115
realyuniquename: 10:22 MainLoop used to be injected into an event loop as an ordinary event. Now it's explicitly handled in EventLoop, but Nicolas didn't add that same handling to the eval implementation
simn: 10:52 Ah I see, that explains it!
simn: 10:52 So I guess we have to add something similar to the eval implementation in both places that call Loop.run
simn: 11:04 That seems to work, but I don't know what to do with the return value of MainLoop.tick
simn: 11:09 And the failed tests from https://github.com/HaxeFoundation/haxe/issues/10682 still fail, so that must be another issue entirely
simn: 11:11 So uh, I'm kind of starting to wonder why we need an eval-specific implementation of this in the first place.
simn: 11:11 If I just delete its EventLoop.hx then everything works
realyuniquename: 12:14 We need eval-specific implementation to integrate it with libuv event loop.
simn: 13:13 How does this compare to HL? Libuv is also supported there, and it doesn't have a special implementation of EventLoop.
realyuniquename: 04:52 HL is supposed to have a separate EventLoop implementation too: https://github.com/HaxeFoundation/haxe/pull/10342/files#diff-5376e19277de8dd959899e7a7f6d044c0b263c9b057b6bb253721e66d2573979
In the coroutine tests we end up in this function:
public function progress():NextEventTime {
if (started) throw "Event loop already started";
if (handle.run(NOWAIT)) {
return AnyTime(null);
} else {
return Never;
}
}
The handle.run(NOWAIT) returns false and then the program just goes on to terminate normally. I can see in the debugger that there's something in pending, but that is never executed.
I have no idea how any of this is supposed to work so some advice would be appreciated.