Skip to content

Commit

Permalink
output: make plugin context operations safe for concurrent use
Browse files Browse the repository at this point in the history
Signed-off-by: Zero King <[email protected]>
  • Loading branch information
l2dy committed Aug 5, 2021
1 parent 3fd1e04 commit 6c67803
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package output
*/
import "C"
import (
"sync"
"unsafe"
)

Expand Down Expand Up @@ -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
}

0 comments on commit 6c67803

Please sign in to comment.