From 7e466f08575ee52b0c26cce0d86b7599cf0e5dc4 Mon Sep 17 00:00:00 2001 From: Marty Schoch Date: Sun, 6 Mar 2016 10:51:33 -0500 Subject: [PATCH] change implementation of log callbacks to work in go 1.6 Change-Id: I443f01419608e9b1dd88bc0593855ed1d812f148 Reviewed-on: http://review.couchbase.org/60992 Reviewed-by: Steve Yen Tested-by: Marty Schoch --- forestdb.go | 19 ++++++++++++++----- log.go | 7 +++++-- log.h | 5 +++++ log_test.go | 9 ++++++++- 4 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 log.h diff --git a/forestdb.go b/forestdb.go index 962785e..06c159d 100644 --- a/forestdb.go +++ b/forestdb.go @@ -11,6 +11,7 @@ package forestdb //#include //#include +//#include "log.h" //extern void LogCallbackInternal(int, char*, char*); //void log_callback(int errcode, char *msg, void *ctx) { // LogCallbackInternal(errcode, msg, ctx); @@ -169,12 +170,20 @@ type logContext struct { userCtx interface{} } +// Hold references to log callbacks and contexts. +var logCallbacks []LogCallback +var logContexts []interface{} + +func registerLogCallback(cb LogCallback, ctx interface{}) int { + logCallbacks = append(logCallbacks, cb) + logContexts = append(logContexts, ctx) + return len(logCallbacks) - 1 +} + func (k *KVStore) SetLogCallback(l LogCallback, userCtx interface{}) { - ctx := logContext{ - callback: &l, - name: k.name, - userCtx: userCtx, - } + var ctx C.log_context + ctx.offset = C.int(registerLogCallback(l, userCtx)) + ctx.name = C.CString(k.name) C.fdb_set_log_callback(k.db, C.fdb_log_callback(C.log_callback), unsafe.Pointer(&ctx)) } diff --git a/log.go b/log.go index 8a6c195..b2ce19e 100644 --- a/log.go +++ b/log.go @@ -1,5 +1,6 @@ package forestdb +//#include "log.h" import "C" import ( "log" @@ -8,8 +9,10 @@ import ( //export LogCallbackInternal func LogCallbackInternal(errCode C.int, msg *C.char, ctx *C.char) { - context := (*logContext)(unsafe.Pointer(ctx)) - (*context.callback)(context.name, int(errCode), C.GoString(msg), context.userCtx) + context := (*C.log_context)(unsafe.Pointer(ctx)) + cb := logCallbacks[context.offset] + userCtx := logContexts[context.offset] + cb(C.GoString(context.name), int(errCode), C.GoString(msg), userCtx) } //export FatalErrorCallbackInternal diff --git a/log.h b/log.h new file mode 100644 index 0000000..1563fb5 --- /dev/null +++ b/log.h @@ -0,0 +1,5 @@ +struct log_context { + int offset; + char *name; +}; +typedef struct log_context log_context; diff --git a/log_test.go b/log_test.go index c6d5a18..316d890 100644 --- a/log_test.go +++ b/log_test.go @@ -57,8 +57,15 @@ func TestLogCallback(t *testing.T) { if errCode != -10 { t.Errorf("expected error code -10, got %d", errCode) } + if ctx, ok := ctx.(map[string]interface{}); ok { + if ctx["customKey"] != "customVal" { + t.Errorf("expected to see my custom context") + } + } else { + t.Errorf("expected custom context to be the type i passed in") + } // don't check the message as it could change - }, nil) + }, map[string]interface{}{"customKey": "customVal"}) err = kvstore.SetKV([]byte("key"), []byte("value")) if err == nil { t.Fatalf("expected error, got nil")