[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [libvirt-perl][PATCH 4/7] Introduce Stream::sparse_recv_all()



Signed-off-by: Michal Privoznik <mprivozn redhat com>
---
 Changes                |  1 +
 Virt.xs                | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/Sys/Virt/Stream.pm | 14 ++++++++++
 t/030-api-coverage.t   |  1 +
 4 files changed, 86 insertions(+)

diff --git a/Changes b/Changes
index c92c271..4c1e071 100644
--- a/Changes
+++ b/Changes
@@ -7,6 +7,7 @@ Revision history for perl module Sys::Virt
  - Introduce flags to Stream::recv() and
    register RECV_STOP_AT_HOLE constant
  - Introduce Stream::recvHole() and Stream::sendHole()
+ - Introduce Stream::sparse_recv_all()
 
 3.3.0 2017-05-08
 
diff --git a/Virt.xs b/Virt.xs
index d112708..002bd6a 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -2008,6 +2008,48 @@ _stream_recv_all_sink(virStreamPtr st,
 }
 
 
+static int
+_stream_sparse_recv_holeHandler(virStreamPtr st,
+                                long long offset,
+                                void *opaque)
+{
+    AV *av = opaque;
+    SV **self;
+    SV **holeHandler;
+    int rv;
+    int ret;
+    dSP;
+
+    self = av_fetch(av, 0, 0);
+    holeHandler = av_fetch(av, 2, 0);
+
+    SvREFCNT_inc(*self);
+
+    ENTER;
+    SAVETMPS;
+
+    PUSHMARK(SP);
+    XPUSHs(*self);
+    XPUSHs(sv_2mortal(virt_newSVll(offset)));
+    PUTBACK;
+
+    rv = call_sv((SV*)*holeHandler, G_SCALAR);
+
+    SPAGAIN;
+
+    if (rv == 1) {
+        ret = POPi;
+    } else {
+        ret = -1;
+    }
+
+    FREETMPS;
+    LEAVE;
+
+    return ret;
+}
+
+
 MODULE = Sys::Virt  PACKAGE = Sys::Virt
 
 PROTOTYPES: ENABLE
@@ -7972,6 +8014,34 @@ recv_all(stref, handler)
       SvREFCNT_dec(opaque);
 
 
+void
+sparse_recv_all(stref, handler, holeHandler)
+      SV *stref;
+      SV *handler;
+      SV *holeHandler;
+ PREINIT:
+      AV *opaque;
+      virStreamPtr st;
+    CODE:
+      st = (virStreamPtr)SvIV((SV*)SvRV(stref));
+
+      opaque = newAV();
+      SvREFCNT_inc(stref);
+      SvREFCNT_inc(handler);
+      SvREFCNT_inc(holeHandler);
+      av_push(opaque, stref);
+      av_push(opaque, handler);
+      av_push(opaque, holeHandler);
+
+      if (virStreamSparseRecvAll(st,
+                                 _stream_recv_all_sink,
+                                 _stream_sparse_recv_holeHandler,
+                                 opaque) < 0)
+          _croak_error();
+
+      SvREFCNT_dec(opaque);
+
+
 void
 add_callback(stref, events, cb)
       SV* stref;
diff --git a/lib/Sys/Virt/Stream.pm b/lib/Sys/Virt/Stream.pm
index 5984fb6..c32b957 100644
--- a/lib/Sys/Virt/Stream.pm
+++ b/lib/Sys/Virt/Stream.pm
@@ -130,6 +130,20 @@ data byte count desired. The function should return
 the number of bytes filled, 0 on end of file, or
 -1 upon error
 
+=item $st->sparse_recv_all($handler, $holeHandler)
+
+Receive all data available from the sparse stream, invoking
+C<$handler> to process the data. The C<$handler> parameter must
+be a function which expects three arguments, the C<$st> stream
+object, a scalar containing the data received and a data byte
+count. The function should return the number of bytes processed,
+or -1 upon error. The second argument C<$holeHandler> is a
+function which expects two arguments: the C<$st> stream and a
+scalar, number describing the size of the hole in the stream (in
+bytes). The C<$holeHandler> is expected to return a non-negative
+number on success (usually 0) and a negative number (usually -1)
+otherwise.
+
 =item $st->add_callback($events, $coderef)
 
 Register a callback to be invoked whenever the stream has
diff --git a/t/030-api-coverage.t b/t/030-api-coverage.t
index 3049713..6a281ba 100644
--- a/t/030-api-coverage.t
+++ b/t/030-api-coverage.t
@@ -114,6 +114,7 @@ virEventUpdateTimeoutFunc
 
 virStreamEventCallback
 virStreamSinkFunc
+virStreamSinkHoleFunc
 virStreamSourceFunc
 
 virConnectCloseFunc
-- 
2.13.0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]