From 6c67803f4691e8e962ddf713ffdbf2a6f0c8d31e Mon Sep 17 00:00:00 2001 From: Zero King Date: Thu, 5 Aug 2021 14:04:38 +0000 Subject: [PATCH] output: make plugin context operations safe for concurrent use Signed-off-by: Zero King --- output/output.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/output/output.go b/output/output.go index fefcca0..c2a9833 100644 --- a/output/output.go +++ b/output/output.go @@ -24,6 +24,7 @@ package output */ import "C" import ( + "sync" "unsafe" ) @@ -69,22 +70,24 @@ func FLBPluginConfigKey(plugin unsafe.Pointer, key string) string { return value } -var contexts = make(map[uintptr]interface{}) +var contexts sync.Map +// FLBPluginSetContext sets the context for the plugin to ctx. +// +// Limit FLBPluginSetContext calls to once per plugin instance for best performance. func FLBPluginSetContext(plugin unsafe.Pointer, ctx interface{}) { // Allocate a byte of memory in the C heap and fill it with '\0', // then convert its pointer into the C type void*, represented by unsafe.Pointer. // The C string is not managed by Go GC, so it will not be freed automatically. i := unsafe.Pointer(C.CString("")) - // uintptr(i) produces the memory address of i, and malloc() guarantees uniqueness of it. - // - // FLBPluginSetContext must not be called concurrently with itself or FLBPluginGetContext. - // A sync.RWMutex must be added if this might happen. - contexts[uintptr(i)] = ctx + // uintptr(i) returns the memory address of i, which is unique in the heap. + contexts.Store(uintptr(i), ctx) p := (*FLBOutPlugin)(plugin) p.context.remote_context = i } -func FLBPluginGetContext(i unsafe.Pointer) interface{} { - return contexts[uintptr(i)] +// FLBPluginGetContext reads the context set by FLBPluginSetContext for this plugin. +func FLBPluginGetContext(proxyCtx unsafe.Pointer) interface{} { + v, _ := contexts.Load(uintptr(proxyCtx)) + return v }