| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- package missinggo
- import "sync"
- type ongoing struct {
- // Waiters can proceed, someone finished the task.
- do sync.Mutex
- users int
- }
- type SingleFlight struct {
- mu sync.Mutex
- ongoing map[string]*ongoing
- }
- type Operation struct {
- sf *SingleFlight
- id string
- }
- func (op Operation) Unlock() {
- op.sf.Unlock(op.id)
- }
- func (me *SingleFlight) Lock(id string) Operation {
- me.mu.Lock()
- on, ok := me.ongoing[id]
- if !ok {
- on = new(ongoing)
- if me.ongoing == nil {
- me.ongoing = make(map[string]*ongoing)
- }
- me.ongoing[id] = on
- }
- on.users++
- me.mu.Unlock()
- on.do.Lock()
- return Operation{me, id}
- }
- func (me *SingleFlight) Unlock(id string) {
- me.mu.Lock()
- on := me.ongoing[id]
- on.do.Unlock()
- on.users--
- if on.users == 0 {
- delete(me.ongoing, id)
- }
- me.mu.Unlock()
- }
|