github.com/tirogen/go-ethereum@v1.10.12-0.20221226051715-250cfede41b6/internal/syncx/mutex.go (about) 1 // Copyright 2021 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package syncx contains exotic synchronization primitives. 18 package syncx 19 20 // ClosableMutex is a mutex that can also be closed. 21 // Once closed, it can never be taken again. 22 type ClosableMutex struct { 23 ch chan struct{} 24 } 25 26 func NewClosableMutex() *ClosableMutex { 27 ch := make(chan struct{}, 1) 28 ch <- struct{}{} 29 return &ClosableMutex{ch} 30 } 31 32 // TryLock attempts to lock cm. 33 // If the mutex is closed, TryLock returns false. 34 func (cm *ClosableMutex) TryLock() bool { 35 _, ok := <-cm.ch 36 return ok 37 } 38 39 // MustLock locks cm. 40 // If the mutex is closed, MustLock panics. 41 func (cm *ClosableMutex) MustLock() { 42 _, ok := <-cm.ch 43 if !ok { 44 panic("mutex closed") 45 } 46 } 47 48 // Unlock unlocks cm. 49 func (cm *ClosableMutex) Unlock() { 50 select { 51 case cm.ch <- struct{}{}: 52 default: 53 panic("Unlock of already-unlocked ClosableMutex") 54 } 55 } 56 57 // Close locks the mutex, then closes it. 58 func (cm *ClosableMutex) Close() { 59 _, ok := <-cm.ch 60 if !ok { 61 panic("Close of already-closed ClosableMutex") 62 } 63 close(cm.ch) 64 }