github.com/true-sqn/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  }