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 hooks2021import "sync"2223type Event int2425const (26 // EventShutdown is triggered when the server process is about to stop.27 EventShutdown Event = iota2829 // EventReload is triggered when the server process receives the SIGUSR230 // signal (on POSIX platforms) and indicates the request to reload the31 // server configuration from persistent storage.32 //33 // Since it is by design problematic to reload the modules configuration,34 // this event only applies to secondary files such as aliases mapping and35 // TLS certificates.36 EventReload3738 // EventLogRotate is triggered when the server process receives the SIGUSR139 // signal (on POSIX platforms) and indicates the request to reopen used log40 // files since they might have rotated.41 EventLogRotate42)4344var (45 hooks = make(map[Event][]func())46 hooksLck sync.Mutex47)4849func hooksToRun(eventName Event) []func() {50 hooksLck.Lock()51 defer hooksLck.Unlock()52 hooksEv := hooks[eventName]53 if hooksEv == nil {54 return nil55 }5657 // The slice is copied so hooks can be run without holding the lock what58 // might be important since they are likely to do a lot of I/O.59 hooksEvCpy := make([]func(), 0, len(hooksEv))60 hooksEvCpy = append(hooksEvCpy, hooksEv...)6162 return hooksEvCpy63}6465// RunHooks runs the hooks installed for the specified eventName in the reverse66// order.67func RunHooks(eventName Event) {68 hooks := hooksToRun(eventName)69 for i := len(hooks) - 1; i >= 0; i-- {70 hooks[i]()71 }72}7374// AddHook installs the hook to be executed when certain event occurs.75func AddHook(eventName Event, f func()) {76 hooksLck.Lock()77 defer hooksLck.Unlock()7879 hooks[eventName] = append(hooks[eventName], f)80}