github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/overlord/hookstate/repository.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 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 20 package hookstate 21 22 import ( 23 "regexp" 24 "sync" 25 ) 26 27 // repository stores all registered handler generators, and generates registered 28 // handlers. 29 type repository struct { 30 mutex sync.RWMutex 31 generators []patternGeneratorPair 32 } 33 34 // patternGeneratorPair contains a hook handler generator and its corresponding 35 // regex pattern for what hook name should cause it to be called. 36 type patternGeneratorPair struct { 37 pattern *regexp.Regexp 38 generator HandlerGenerator 39 } 40 41 // NewRepository creates an empty handler generator repository. 42 func newRepository() *repository { 43 return &repository{} 44 } 45 46 // AddHandler adds the provided handler generator to the repository. 47 func (r *repository) addHandlerGenerator(pattern *regexp.Regexp, generator HandlerGenerator) { 48 r.mutex.Lock() 49 defer r.mutex.Unlock() 50 51 r.generators = append(r.generators, patternGeneratorPair{ 52 pattern: pattern, 53 generator: generator, 54 }) 55 } 56 57 // GenerateHandlers calls the handler generators whose patterns match the 58 // hook name contained within the provided context, and returns the resulting 59 // handlers. 60 func (r *repository) generateHandlers(context *Context) []Handler { 61 hookName := context.HookName() 62 var handlers []Handler 63 64 r.mutex.RLock() 65 defer r.mutex.RUnlock() 66 67 for _, pair := range r.generators { 68 if pair.pattern.MatchString(hookName) { 69 handlers = append(handlers, pair.generator(context)) 70 } 71 } 72 73 return handlers 74 }