The former is a public API and registers a callback that will be called whenever the other side of a stream calls virStreamSkip. The latter is a wrapper that actually calls the callback. It is not made public as it is intended to be used purely internally. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- include/libvirt/libvirt-stream.h | 21 ++++++++++++ src/datatypes.h | 6 ++++ src/libvirt-stream.c | 70 ++++++++++++++++++++++++++++++++++++++++ src/libvirt_internal.h | 4 +++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 1 + 6 files changed, 103 insertions(+) diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h index f12d695..1a5286a 100644 --- a/include/libvirt/libvirt-stream.h +++ b/include/libvirt/libvirt-stream.h @@ -45,6 +45,27 @@ int virStreamRecv(virStreamPtr st, char *data, size_t nbytes); +/** + * virStreamSkipFunc: + * @stream: stream + * @offset: size of hole in bytes + * @opaque: optional application provided data + * + * This callback is called whenever the other side of @stream is + * willing to skip a hole in the stream. The @offset argument + * then contains the size of hole in bytes. + * + * Returns 0 on success, + * -1 otherwise. + */ +typedef int (*virStreamSkipFunc)(virStreamPtr stream, + unsigned long long offset, + void *opaque); + +int virStreamRegisterSkip(virStreamPtr stream, + virStreamSkipFunc skipCb, + void *opaque); + int virStreamSkip(virStreamPtr st, unsigned long long offset); diff --git a/src/datatypes.h b/src/datatypes.h index 92e6863..169fc46 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -568,6 +568,12 @@ struct _virStream { virStreamDriverPtr driver; void *privateData; + + /* Unfortunately, this can't go into virStreamDriver because + * when register function for skipCb is called, @driver + * is not populated yet. */ + virStreamSkipFunc skipCb; + void *skipCbOpaque; }; /** diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c index 1c9a12b..58665f1 100644 --- a/src/libvirt-stream.c +++ b/src/libvirt-stream.c @@ -286,6 +286,76 @@ virStreamRecv(virStreamPtr stream, /** + * virStreamRegisterSkip: + * @stream: stream + * @skipCb: callback function + * @opaque: optional application provided data + * + * This function registers callback that will be called whenever + * the other side of the @stream is willing to skip a hole in the + * stream. + * + * Returns 0 on success, + * -1 otherwise. + */ +int +virStreamRegisterSkip(virStreamPtr stream, + virStreamSkipFunc skipCb, + void *opaque) +{ + VIR_DEBUG("stream=%p, skipCb=%p opaque=%p", stream, skipCb, opaque); + + virResetLastError(); + + virCheckStreamReturn(stream, -1); + virCheckNonNullArgReturn(skipCb, -1); + + if (stream->skipCb) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("A skip callback is already registered")); + return -1; + } + + stream->skipCb = skipCb; + stream->skipCbOpaque = opaque; + return 0; +} + + +/** + * virStreamSkipCallback: + * @stream: stream + * @offset: stream offset + * + * Call previously registered skip callback. + * + * Returns 0 on success, + * -1 otherwise. + */ +int +virStreamSkipCallback(virStreamPtr stream, + unsigned long long offset) +{ + VIR_DEBUG("stream=%p, offset=%llu", stream, offset); + + virCheckStreamReturn(stream, -1); + + if (stream->skipCb) { + int ret; + ret = (stream->skipCb)(stream, offset, stream->skipCbOpaque); + if (ret < 0) + goto error; + return 0; + } + + virReportUnsupportedError(); + error: + virDispatchError(stream->conn); + return -1; +} + + +/** * virStreamSkip: * @stream: pointer to the stream object * @offset: number of bytes to skip diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h index 96439d8..7a75491 100644 --- a/src/libvirt_internal.h +++ b/src/libvirt_internal.h @@ -294,4 +294,8 @@ virTypedParameterValidateSet(virConnectPtr conn, virTypedParameterPtr params, int nparams); +int +virStreamSkipCallback(virStreamPtr stream, + unsigned long long offset); + #endif diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5030ec3..e83d5d6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1015,6 +1015,7 @@ virStateCleanup; virStateInitialize; virStateReload; virStateStop; +virStreamSkipCallback; # locking/domain_lock.h diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b4c693a..0b80d27 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -735,6 +735,7 @@ LIBVIRT_1.3.3 { LIBVIRT_1.3.5 { global: virStreamSkip; + virStreamRegisterSkip; } LIBVIRT_1.3.3; # .... define new API here using predicted next version number .... -- 2.8.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list