From 0a11e8d322c27c53ee94945fe737530dc13c5159 Mon Sep 17 00:00:00 2001 From: Hazel Atkinson Date: Sun, 21 Apr 2024 18:57:36 +0100 Subject: [PATCH] [sync] fix TEvent (see https://github.com/vibe-d/eventcore/issues/238#issuecomment-2068148847) --- source/rockhopper/sync.d | 32 ++++++++++++++++++++++++++------ testscript.d | 33 +++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/source/rockhopper/sync.d b/source/rockhopper/sync.d index 13dd8c2..991fdf3 100644 --- a/source/rockhopper/sync.d +++ b/source/rockhopper/sync.d @@ -50,9 +50,11 @@ shared class TEvent import std.typecons : Tuple, tuple; import core.thread.osthread : Thread; + alias ThreadEventsTy = Tuple!(shared(EventDriver), EventID)[typeof(Thread.getThis.id)]; + shared bool triggered; // you may only await an event from the thread that created it, so we need one event per thread - shared Tuple!(shared(EventDriver), EventID)[typeof(Thread.getThis.id)] threadEvents; + shared ThreadEventsTy threadEvents; import std.stdio; @@ -63,7 +65,7 @@ shared class TEvent foreach (_, tup; threadEvents) tup[0].events.trigger(tup[1], true); - threadEvents = typeof(threadEvents).init; + threadEvents = ThreadEventsTy.init; } synchronized void reset() @@ -71,7 +73,7 @@ shared class TEvent if (triggered) { triggered = false; - threadEvents = typeof(threadEvents).init; + threadEvents = ThreadEventsTy.init; } else { @@ -86,9 +88,27 @@ shared class TEvent auto tid = Thread.getThis.id; - auto ev = eventDriver.events.create(); - // TODO: this does not compile? - threadEvents[tid] = tuple(cast(shared) eventDriver, ev); + EventID ev = void; // always assigned + + synchronized(this) + { + // while in a synchronized, you can cast away a `shared` + // -- technically you can cast shared away any time, but its safe here :) + // use a pointer else this causes a copy and that screws stuff up. + // we still have to make sure the contents of the AA are shared due to transititivy, + // but this fixes it not liking us trying to do the assignment *at all* + auto tEvs = cast(ThreadEventsTy*) &threadEvents; + + if (tid in *tEvs) + { + ev = (*tEvs)[tid][1]; + } + else + { + ev = eventDriver.events.create(); + (*tEvs)[tid] = tuple(cast(shared) eventDriver, ev); + } + } waitThreadEvent(ev); diff --git a/testscript.d b/testscript.d index 79d1657..8e62801 100755 --- a/testscript.d +++ b/testscript.d @@ -22,11 +22,32 @@ import core.thread.osthread : Thread; void main() { entrypoint({ - auto eepyTask = taskify!sleep(dur!"seconds"(5)); - auto tBefore = MonoTime.currTime; - - eepyTask.waitRes(); // void - - writeln("eeped for ", MonoTime.currTime - tBefore); + auto ev = new TEvent; + + auto thread2 = new Thread({ + entrypoint({ + ev.wait(); + writeln("yay 2!"); + }); + }).start(); + + auto thread3 = new Thread({ + entrypoint({ + ev.wait(); + writeln("yay 3!"); + }); + }).start(); + + auto thread4 = new Thread({ + entrypoint({ + writeln("helo"); + Thread.sleep(dur!"seconds"(2)); + ev.notify(); + }); + }).start(); + + thread2.join(); + thread3.join(); + thread4.join(); }); }