Is the issue that the E_b from Jan's original message might produce multiple values and you are supposed to take the value that's available only after something syncs on the E_m?
That is, I thought you could just create a separate thread that sync's on E_b and then whenever you get a value from it, then the E_m would just continue to produce that all the time. But I think you're saying that wouldn't work? I guess I'm not getting it. Thanks for more explanation. Robby On Thu, Jan 29, 2015 at 1:55 PM, Matthew Flatt <mfl...@cs.utah.edu> wrote: > Hi Jan, > > Interesting problem! > > I think I see what you mean: There's no way to combine the completion > of an event plus saving its value as an atomic operation, except by > putting the synchronization in its own thread. But if you put the > synchronization in its own thread, then there's no way to prevent that > thread's synchronization when a consumer synchronization (i.e., one > that is waiting for the thread's result) picks a different event than > the one represented by the thread. > > It's easy to make a complete+save combination atomic if it's built into > the scheduler. So, I can easily imagine adding a simpler primitive, > `once-evt`. The event OE created by `(once-evt E)` could save the first > result produced by E, but not attempt to have only a single wait on E. > That is, if OE1 is synchronized in multiple threads, then it would be > like synchronizing E in multiple threads, but only the first result > from E will be saved. > > Unfortunately, `once-evt` isn't enough to implement `memoize-evt`. The > troublesome case is then thread T1 is synchronizing on OE1, T1 gets > suspended, and T2 starts waiting on OE1. In that case, you'd like T2 to > take over the wait, even if it means restarting E. You can detect that > T1 is suspended and have T2 start waiting on E, but there's no way to > cancel the wait of E in T1. > > Building `memoize-evt` into the core doesn't the avoid the need to, at > some level, cancel T1's wait on E. I'll keep thinking about it, but it > looks like that would require deep changes to the scheduler. > > Would the simpler `once-evt` work in your situation, or do you need the > guarantee that only one wait of E happens at a time? > > Matthew > > At Wed, 28 Jan 2015 13:49:51 +0100, Jan Dvořák wrote: >> Hi, >> >> I would like to ask for another extension of the Racket's event handling >> system. A `memoize-evt` constructor with following semantics: >> >> Given a base event E_b, memoize-evt will produce a memoizing event E_m. >> Synchronizing on E_m from any number of threads will block until a >> single value is produced by E_b. This value is then stored inside the >> E_m. From that moment on, E_m will always be immediately ready for >> synchronization and produce the stored value in all waiting threads. >> >> The single-threaded implementation is a trivial guard-evt + replace-evt >> + (wrap-evt always-evt) combo, but for thread-safety a temporary thread >> would be needed to wait for the base event and the solution would have >> different semantics then rest of the event system. >> >> A lower-level approach would also be possible; create something along >> the lines of a dynamic-wind-evt that would, with some cleverness, allow >> for generic thread-safe events via locking. Or create a locked-wrap-evt >> constructor that will not be ready until it's handler finishes. >> >> Hoping that I am not being too bothersome, >> from Prague with thanks, >> Jan Dvorak > > > _________________________ > Racket Developers list: > http://lists.racket-lang.org/dev _________________________ Racket Developers list: http://lists.racket-lang.org/dev