1package libkbfs 2 3import "context" 4 5// OngoingWorkLimiter limits maximum number of routines that can work on a same 6// type of thing at the same time. For example, it can be used for limiting 7// number of ongoing rekeys. 8type OngoingWorkLimiter struct { 9 permits chan struct{} 10} 11 12// NewOngoingWorkLimiter creates a new *OngoingWorkLimiter with capacity of 13// maxNumOngoingWorks. 14func NewOngoingWorkLimiter(maxNumOngoingWorks int) *OngoingWorkLimiter { 15 return &OngoingWorkLimiter{ 16 permits: make(chan struct{}, maxNumOngoingWorks), 17 } 18} 19 20// WaitToStart blocks until the limiter would allow one more routine to start 21// working on the thing. 22func (owl *OngoingWorkLimiter) WaitToStart(ctx context.Context) error { 23 select { 24 case owl.permits <- struct{}{}: 25 return nil 26 case <-ctx.Done(): 27 return ctx.Err() 28 } 29} 30 31// Done tells the limiter that the caller is done working on the thing, and 32// somebody else is free to start work. 33func (owl *OngoingWorkLimiter) Done() { 34 <-owl.permits 35} 36