semaphore/semaphore.go
func (t *Semaphore) Release() {
	t.waitIfResizing()

	// we need a read lock to ensure we do not resize whilst resizing
	t.readMutex.RLock()
	defer t.readMutex.RUnlock()

	// make sure we have not called Release without Lock
	if len(t.s) == 0 {
		return
	}
	<-t.s
}
func (t *Semaphore) Release() {
	t.waitIfResizing()

	// we need a read lock to ensure we do not resize whilst resizing
	t.readMutex.RLock()
	defer t.readMutex.RUnlock()

	// make sure we have not called Release without Lock
	if len(t.s) == 0 {
		return
	}
	<-t.s
}
// Release unlocks the semaphore and allows new lock instances to be called without
// blocking if the number of locks currently equal the capacity.
// It is important to call Release at the end of any operation which aquires a lock.