Commit fc6d6228 authored by Tw's avatar Tw Committed by Matt Holt

make eventHooks thread safe (Go 1.9) (#2009)

Signed-off-by: default avatarTw <tw19881113@gmail.com>
parent e2997ac9
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
"log" "log"
"net" "net"
"sort" "sort"
"sync"
"github.com/mholt/caddy/caddyfile" "github.com/mholt/caddy/caddyfile"
) )
...@@ -38,7 +39,7 @@ var ( ...@@ -38,7 +39,7 @@ var (
// eventHooks is a map of hook name to Hook. All hooks plugins // eventHooks is a map of hook name to Hook. All hooks plugins
// must have a name. // must have a name.
eventHooks = make(map[string]EventHook) eventHooks = sync.Map{}
// parsingCallbacks maps server type to map of directive // parsingCallbacks maps server type to map of directive
// to list of callback functions. These aren't really // to list of callback functions. These aren't really
...@@ -67,12 +68,15 @@ func DescribePlugins() string { ...@@ -67,12 +68,15 @@ func DescribePlugins() string {
str += " " + defaultCaddyfileLoader.name + "\n" str += " " + defaultCaddyfileLoader.name + "\n"
} }
if len(eventHooks) > 0 { // List the event hook plugins
// List the event hook plugins hooks := ""
eventHooks.Range(func(k, _ interface{}) bool {
hooks += " hook." + k.(string) + "\n"
return true
})
if hooks != "" {
str += "\nEvent hook plugins:\n" str += "\nEvent hook plugins:\n"
for hookPlugin := range eventHooks { str += hooks
str += " hook." + hookPlugin + "\n"
}
} }
// Let's alphabetize the rest of these... // Let's alphabetize the rest of these...
...@@ -248,23 +252,23 @@ func RegisterEventHook(name string, hook EventHook) { ...@@ -248,23 +252,23 @@ func RegisterEventHook(name string, hook EventHook) {
if name == "" { if name == "" {
panic("event hook must have a name") panic("event hook must have a name")
} }
if _, dup := eventHooks[name]; dup { _, dup := eventHooks.LoadOrStore(name, hook)
if dup {
panic("hook named " + name + " already registered") panic("hook named " + name + " already registered")
} }
eventHooks[name] = hook
} }
// EmitEvent executes the different hooks passing the EventType as an // EmitEvent executes the different hooks passing the EventType as an
// argument. This is a blocking function. Hook developers should // argument. This is a blocking function. Hook developers should
// use 'go' keyword if they don't want to block Caddy. // use 'go' keyword if they don't want to block Caddy.
func EmitEvent(event EventName, info interface{}) { func EmitEvent(event EventName, info interface{}) {
for name, hook := range eventHooks { eventHooks.Range(func(k, v interface{}) bool {
err := hook(event, info) err := v.(EventHook)(event, info)
if err != nil { if err != nil {
log.Printf("error on '%s' hook: %v", name, err) log.Printf("error on '%s' hook: %v", k.(string), err)
} }
} return true
})
} }
// ParsingCallback is a function that is called after // ParsingCallback is a function that is called after
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment