1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package limiters2021import "context"2223// Semaphore is a convenience wrapper for a channel that implements24// semaphore-kind synchronization.25//26// If the argument given to the NewSemaphore is negative or zero,27// all methods are no-op.28type Semaphore struct {29 c chan struct{}30}3132func NewSemaphore(max int) Semaphore {33 return Semaphore{c: make(chan struct{}, max)}34}3536func (s Semaphore) Take() bool {37 if cap(s.c) <= 0 {38 return true39 }40 s.c <- struct{}{}41 return true42}4344func (s Semaphore) TakeContext(ctx context.Context) error {45 if cap(s.c) <= 0 {46 return nil47 }48 select {49 case s.c <- struct{}{}:50 return nil51 case <-ctx.Done():52 return ctx.Err()53 }54}5556func (s Semaphore) Release() {57 if cap(s.c) <= 0 {58 return59 }60 select {61 case <-s.c:62 default:63 panic("limiters: mismatched Release call")64 }65}6667func (s Semaphore) Close() {68}