github.com/defanghe/fabric@v2.1.1+incompatible/common/semaphore/semaphore.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 // Package semaphore provides an implementation of a counting semaphore. 8 package semaphore 9 10 import ( 11 "context" 12 ) 13 14 // Semaphore is a buffered channel based implementation of a counting 15 // semaphore. 16 type Semaphore chan struct{} 17 18 // New creates a Semaphore with the specified number of permits. 19 func New(permits int) Semaphore { 20 if permits <= 0 { 21 panic("permits must be greater than 0") 22 } 23 return make(chan struct{}, permits) 24 } 25 26 // Acquire acquires a permit. This call will block until a permit is available 27 // or the provided context is completed. 28 // 29 // If the provided context is completed, the method will return the 30 // cancellation error. 31 func (s Semaphore) Acquire(ctx context.Context) error { 32 select { 33 case <-ctx.Done(): 34 return ctx.Err() 35 case s <- struct{}{}: 36 return nil 37 } 38 } 39 40 // TryAcquire acquires the semaphore without blocking. 41 // Returns true if the semaphore is acquired. 42 // Otherwise, returns false and leaves the semaphore unchanged. 43 func (s Semaphore) TryAcquire() bool { 44 select { 45 case s <- struct{}{}: 46 return true 47 default: 48 return false 49 } 50 } 51 52 // Release releases a permit. 53 func (s Semaphore) Release() { 54 select { 55 case <-s: 56 default: 57 panic("semaphore buffer is empty") 58 } 59 }