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// MultiLimit wraps multiple L implementations into a single one, locking them24// in the specified order.25//26// It does not implement any deadlock detection or avoidance algorithms.27type MultiLimit struct {28 Wrapped []L29}3031func (ml *MultiLimit) Take() bool {32 for i := 0; i < len(ml.Wrapped); i++ {33 if !ml.Wrapped[i].Take() {34 // Acquire failed, undo acquire for all other resources we already35 // got.36 for _, l := range ml.Wrapped[:i] {37 l.Release()38 }39 return false40 }41 }42 return true43}4445func (ml *MultiLimit) TakeContext(ctx context.Context) error {46 for i := 0; i < len(ml.Wrapped); i++ {47 if err := ml.Wrapped[i].TakeContext(ctx); err != nil {48 // Acquire failed, undo acquire for all other resources we already49 // got.50 for _, l := range ml.Wrapped[:i] {51 l.Release()52 }53 return err54 }55 }56 return nil57}5859func (ml *MultiLimit) Release() {60 for _, l := range ml.Wrapped {61 l.Release()62 }63}6465func (ml *MultiLimit) Close() {66 for _, l := range ml.Wrapped {67 l.Close()68 }69}