Skip to content
Snippets Groups Projects
waiting_room.go 809 B
Newer Older
package core

import "sync"

// Synchronization aid that lets goroutines wait for some
// job to finish. Similar to sync.Once.
type waitingroom struct {
	initer   sync.Once
	cond     *sync.Cond
	released bool
}

// Wait for anyone to call Release.
func (wr *waitingroom) Wait() {
	wr.initialize()

	wr.cond.L.Lock()
	defer wr.cond.L.Unlock()

	for !wr.released {
		wr.cond.Wait()
	}
}

// Release all goroutines currently stuck in Wait. Also
// results in all later calls to Wait to simply not wait
// at all.
func (wr *waitingroom) Release() {
	wr.initialize()

	wr.cond.L.Lock()
	defer wr.cond.L.Unlock()

	wr.released = true
	wr.cond.Broadcast()
}

// Initialize if necessary.
func (wr *waitingroom) initialize() {
	wr.initer.Do(func() {
		wr.cond = sync.NewCond(&sync.Mutex{})
		wr.released = false
	})
}