diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2024-08-15 16:28:34 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2024-08-15 16:28:34 -0400 |
| commit | 088ab5372f609a2489163844ac58d8b842cedb13 (patch) | |
| tree | 42536640c111700deab27357315ed63c8b01a8d3 /share.go | |
| parent | fb44cf37696fa5491dd393336404ee40fe047ccb (diff) | |
| download | gui-088ab5372f609a2489163844ac58d8b842cedb13.zip | |
rename server to sharedVal
Diffstat (limited to 'share.go')
| -rw-r--r-- | share.go | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/share.go b/share.go new file mode 100644 index 0000000..b370e5a --- /dev/null +++ b/share.go @@ -0,0 +1,52 @@ +package gui + +// sharedVal is a concurrent interface to a piece of shared data. +// +// A client can read the data by sending a channel via request, and the stored value will +// be sent back via the channel. The client is responsible for closing the channel. +// +// The stored value can be changed by sending the new value via set. Requests block until +// the first value is received on set. +// +// A sharedVal should be closed after use. +type sharedVal[T any] struct { + request chan<- chan T + set chan<- T +} + +func newSharedVal[T any]() sharedVal[T] { + request := make(chan chan T) + set := make(chan T) + go func() { + val := <-set // wait for initial value + for { + select { + case v, ok := <-set: + if !ok { // closed + return + } + val = v + case req, ok := <-request: + if !ok { // closed + return + } + go func() { // don't wait for client to receive + req <- val + }() + } + } + }() + return sharedVal[T]{request, set} +} + +// get makes a synchronous request and returns the stored value. +func (sv sharedVal[T]) get() T { + c := make(chan T) + sv.request <- c + return <-c +} + +func (sv sharedVal[T]) close() { + close(sv.request) + close(sv.set) +} |