github.com/andy2046/gopie@v0.7.0/pkg/semaphore/semaphore.go (about) 1 // Package semaphore provides a semaphore implementation. 2 package semaphore 3 4 import ( 5 "context" 6 ) 7 8 type ( 9 // Semaphore is the semaphore implementation. 10 Semaphore struct { 11 cur chan struct{} 12 } 13 14 // ISemaphore is the semaphore interface. 15 ISemaphore interface { 16 Acquire(context.Context) error 17 Release(context.Context) error 18 } 19 ) 20 21 // Acquire acquires the semaphore. 22 func (s *Semaphore) Acquire(ctx context.Context) error { 23 select { 24 case s.cur <- struct{}{}: 25 return nil 26 case <-ctx.Done(): 27 return ctx.Err() 28 } 29 } 30 31 // Release releases the semaphore. 32 func (s *Semaphore) Release(ctx context.Context) error { 33 select { 34 case _ = <-s.cur: 35 return nil 36 case <-ctx.Done(): 37 return ctx.Err() 38 } 39 } 40 41 // New creates a new semaphore with given maximum concurrent access. 42 func New(n int) ISemaphore { 43 if n <= 0 { 44 panic("the number of max concurrent access must be positive int") 45 } 46 return &Semaphore{ 47 cur: make(chan struct{}, n), 48 } 49 }