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(a)redhat.com>
---
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