-
Notifications
You must be signed in to change notification settings - Fork 1
/
win-or-waiter.go
34 lines (29 loc) · 1.13 KB
/
win-or-waiter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
© 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
// WinOrWaiter picks a winner thread to carry out some task used by many threads.
// - threads arriving to an idle WinorWaiter are winners that complete the task
// - After a winning thread completes the task, it invokes WinnerDone
// - threads arriving to a WinOrWait in progress are held waiting until WinnerDone
// - the task is completed on demand, but only by the first thread requesting it
type WinOrWaiter struct {
WinOrWaiterCore
}
// WinOrWaiter returns a semaphore used for completing an on-demand task by
// the first thread requesting it, and that result shared by subsequent threads held
// waiting for the result.
func NewWinOrWaiter(mustBeLater bool, g0 GoGen) (winOrWaiter *WinOrWaiter) {
w := WinOrWaiter{WinOrWaiterCore: *NewWinOrWaiterCore(mustBeLater, g0.Go())}
go w.contextThread()
return &w
}
func (ww *WinOrWaiter) contextThread() {
g0 := ww.WinOrWaiterCore.g0
var err error
defer g0.Done(&err)
defer Recover(Annotation(), &err, NoOnError)
<-g0.Context().Done()
ww.Broadcast()
}