rbd: simplify callback mechanism in diff_iterate and watchers

Previously, the code that set up the callbacks was doing a pretty
direct translation of go-function to c-function. It turns out this
is not needed due to the way we set up the "dynamic" go callbacks
via an integer based callback "registry". Instead, we can stay within
the C layer entirely for the C callback, passing it only the index
value and then return to the go layer through a static C function
that only needs the index value.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
John Mulligan 2020-07-22 10:32:56 -04:00 committed by John Mulligan
parent 4a58616b96
commit aa29fad715
4 changed files with 12 additions and 42 deletions

View File

@ -1,13 +0,0 @@
package rbd
/*
#include <rbd/librbd.h>
extern int diffIterateCallback(uint64_t ofs, size_t len, int exists, int index);
int callDiffIterateCallback(uint64_t ofs, size_t len, int exists, int index) {
return diffIterateCallback(ofs, len, exists, index);
}
*/
import "C"

View File

@ -1,15 +0,0 @@
// +build !luminous
package rbd
/*
#include <rbd/librbd.h>
extern void imageWatchCallback(int index);
void callWatchCallback(int index) {
imageWatchCallback(index);
}
*/
import "C"

View File

@ -7,7 +7,7 @@ package rbd
#include <stdlib.h>
#include <rbd/librbd.h>
extern int callDiffIterateCallback(uint64_t ofs, size_t len, int exists, int index);
extern int diffIterateCallback(uint64_t, size_t, int, void *);
// cgo is having trouble converting the callback from the librbd header
// to a unsafe.Pointer. This shim exists solely to help it along.
@ -16,9 +16,8 @@ static inline int wrap_rbd_diff_iterate2(
const char *fromsnapname,
uint64_t ofs, uint64_t len,
uint8_t include_parent, uint8_t whole_object,
void *cb,
uintptr_t arg) {
return rbd_diff_iterate2(image, fromsnapname, ofs, len, include_parent, whole_object, cb, (void*)arg);
uintptr_t index) {
return rbd_diff_iterate2(image, fromsnapname, ofs, len, include_parent, whole_object, diffIterateCallback, (void*)index);
}
*/
import "C"
@ -118,7 +117,6 @@ func (image *Image) DiffIterate(config DiffIterateConfig) error {
C.uint64_t(config.Length),
C.uint8_t(config.IncludeParent),
C.uint8_t(config.WholeObject),
C.callDiffIterateCallback,
C.uintptr_t(cbIndex))
return getError(ret)
@ -126,9 +124,9 @@ func (image *Image) DiffIterate(config DiffIterateConfig) error {
//export diffIterateCallback
func diffIterateCallback(
offset C.uint64_t, length C.size_t, exists, index C.int) C.int {
offset C.uint64_t, length C.size_t, exists C.int, index unsafe.Pointer) C.int {
v := diffIterateCallbacks.Lookup(int(index))
v := diffIterateCallbacks.Lookup(int(uintptr(index)))
config := v.(DiffIterateConfig)
return C.int(config.Callback(
uint64(offset), uint64(length), int(exists), config.Data))

View File

@ -8,7 +8,7 @@ package rbd
#cgo LDFLAGS: -lrbd
#include <rbd/librbd.h>
extern int callWatchCallback(int index);
extern void imageWatchCallback(void *);
// cgo has trouble converting the types of the callback and data arg defined in
// librbd header. It wants the callback function to be a byte pointer and
@ -18,14 +18,15 @@ extern int callWatchCallback(int index);
static inline int wrap_rbd_update_watch(
rbd_image_t image,
uint64_t *handle,
void *watch_cb,
uintptr_t arg) {
return rbd_update_watch(image, handle, watch_cb, (void*)arg);
uintptr_t index) {
return rbd_update_watch(image, handle, imageWatchCallback, (void*)index);
}
*/
import "C"
import (
"unsafe"
"github.com/ceph/go-ceph/internal/callbacks"
"github.com/ceph/go-ceph/internal/retry"
)
@ -120,7 +121,6 @@ func (image *Image) UpdateWatch(cb WatchCallback, data interface{}) (*Watch, err
ret := C.wrap_rbd_update_watch(
image.image,
&w.handle,
C.callWatchCallback,
C.uintptr_t(w.cbIndex))
if ret != 0 {
return nil, getError(ret)
@ -145,8 +145,8 @@ func (w *Watch) Unwatch() error {
}
//export imageWatchCallback
func imageWatchCallback(index C.int) {
v := watchCallbacks.Lookup(int(index))
func imageWatchCallback(index unsafe.Pointer) {
v := watchCallbacks.Lookup(int(uintptr(index)))
wi := v.(watchInstance)
wi.callback(wi.data)
}