github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/integration/messagebus/glue/backend/closer/closer.go (about) 1 /* 2 * Glue - Robust Go and Javascript Socket Library 3 * Copyright (C) 2015 Roland Singer <roland.singer[at]desertbit.com> 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 // Emit a close function only once, also if called multiple times. 20 // This implementation is thread-safe. 21 package closer 22 23 import ( 24 "sync" 25 ) 26 27 type Closer struct { 28 // Channel which is closed if the closer is closed. 29 IsClosedChan chan struct{} 30 31 f func() 32 mutex sync.Mutex 33 } 34 35 // New creates a new closer. 36 // The passed function is emitted only once, as soon close is called. 37 func New(f func()) *Closer { 38 return &Closer{ 39 IsClosedChan: make(chan struct{}), 40 f: f, 41 } 42 } 43 44 // Close calls the function and sets the IsClosed boolean. 45 func (c *Closer) Close() { 46 // Lock the mutex 47 c.mutex.Lock() 48 defer c.mutex.Unlock() 49 50 // Just return if already closed. 51 if c.IsClosed() { 52 return 53 } 54 55 // Close the channel. 56 close(c.IsClosedChan) 57 58 // Emit the function. 59 c.f() 60 } 61 62 // IsClosed returns a boolean whenever this closer is already closed. 63 func (c *Closer) IsClosed() bool { 64 select { 65 case <-c.IsClosedChan: 66 return true 67 default: 68 return false 69 } 70 }