Skip to content

Commit

Permalink
change implementation of log callbacks to work in go 1.6
Browse files Browse the repository at this point in the history
Change-Id: I443f01419608e9b1dd88bc0593855ed1d812f148
Reviewed-on: http://review.couchbase.org/60992
Reviewed-by: Steve Yen <steve.yen@gmail.com>
Tested-by: Marty Schoch <marty.schoch@gmail.com>
  • Loading branch information
mschoch committed Mar 6, 2016
1 parent 01b8ef0 commit 7e466f0
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 8 deletions.
19 changes: 14 additions & 5 deletions forestdb.go
Expand Up @@ -11,6 +11,7 @@ package forestdb

//#include <stdlib.h>
//#include <libforestdb/forestdb.h>
//#include "log.h"
//extern void LogCallbackInternal(int, char*, char*);
//void log_callback(int errcode, char *msg, void *ctx) {
// LogCallbackInternal(errcode, msg, ctx);
Expand Down Expand Up @@ -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))
}

Expand Down
7 changes: 5 additions & 2 deletions log.go
@@ -1,5 +1,6 @@
package forestdb

//#include "log.h"
import "C"
import (
"log"
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions log.h
@@ -0,0 +1,5 @@
struct log_context {
int offset;
char *name;
};
typedef struct log_context log_context;
9 changes: 8 additions & 1 deletion log_test.go
Expand Up @@ -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")
Expand Down

0 comments on commit 7e466f0

Please sign in to comment.