[libvirt] [PATCH 05/10] python: Implement virStreamSend/RecvAll helpers

Daniel Veillard veillard at redhat.com
Thu Jun 16 14:45:03 UTC 2011


On Wed, Jun 15, 2011 at 09:23:14PM -0400, Cole Robinson wrote:
> Pure python implementation. The handler callbacks have been altered
> a bit compared to the C API: RecvAll doesn't pass length of the data read
> since that can be trivially obtained from python string objects, and SendAll
> requires the handler to return the string data to send rather than
> store the data in a string pointer.
> 
> Signed-off-by: Cole Robinson <crobinso at redhat.com>
> ---
>  python/generator.py                  |    4 +-
>  python/libvirt-override-virStream.py |   64 ++++++++++++++++++++++++++++++++++
>  2 files changed, 66 insertions(+), 2 deletions(-)
> 
> diff --git a/python/generator.py b/python/generator.py
> index fdc2068..b73dc57 100755
> --- a/python/generator.py
> +++ b/python/generator.py
> @@ -391,8 +391,8 @@ skip_function = (
>      'virSaveLastError', # We have our own python error wrapper
>      'virFreeError', # Only needed if we use virSaveLastError
>  
> -    'virStreamRecvAll', # XXX: Can be written in pure python?
> -    'virStreamSendAll', # XXX: Can be written in pure python?
> +    'virStreamRecvAll', # Pure python libvirt-override-virStream.py
> +    'virStreamSendAll', # Pure python libvirt-override-virStream.py
>      'virStreamRecv', # overridden in libvirt-override-virStream.py
>      'virStreamSend', # overridden in libvirt-override-virStream.py
>  
> diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py
> index f8a1d0b..82e1648 100644
> --- a/python/libvirt-override-virStream.py
> +++ b/python/libvirt-override-virStream.py
> @@ -25,6 +25,70 @@
>          ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData)
>          if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed')
>  
> +    def recvAll(self, handler, opaque):
> +        """Receive the entire data stream, sending the data to the
> +        requested data sink. This is simply a convenient alternative
> +        to virStreamRecv, for apps that do blocking-I/o.
> +
> +        A hypothetical handler function looks like:
> +
> +            def handler(stream, # virStream instance
> +                        buf,    # string containing received data
> +                        opaque): # extra data passed to recvAll as opaque
> +                fd = opaque
> +                return os.write(fd, buf)
> +        """
> +        while True:
> +            got = self.recv(1024*64)
> +            if got == -2:
> +                raise libvirtError("cannot use recvAll with "
> +                                   "nonblocking stream")
> +            if len(got) == 0:
> +                break
> +
> +            try:
> +                ret = handler(self, got, opaque)
> +                if type(ret) is int and ret < 0:
> +                    raise RuntimeError("recvAll handler returned %d" % ret)
> +            except Exception, e:
> +                try:
> +                    self.abort()
> +                except:
> +                    pass
> +                raise e
> +
> +    def sendAll(self, handler, opaque):
> +        """
> +        Send the entire data stream, reading the data from the
> +        requested data source. This is simply a convenient alternative
> +        to virStreamSend, for apps that do blocking-I/o.
> +
> +        A hypothetical handler function looks like:
> +
> +            def handler(stream, # virStream instance
> +                        nbytes, # int amt of data to read
> +                        opaque): # extra data passed to recvAll as opaque
> +                fd = opaque
> +                return os.read(fd, nbytes)
> +        """
> +        while True:
> +            try:
> +                got = handler(self, 1024*64, opaque)
> +            except:
> +                try:
> +                    self.abort()
> +                except:
> +                    pass
> +                raise e
> +
> +            if got == "":
> +                break
> +
> +            ret = self.send(got)
> +            if ret == -2:
> +                raise libvirtError("cannot use recvAll with "
> +                                   "nonblocking stream")
> +
>      def recv(self, nbytes):
>          """Write a series of bytes to the stream. This method may
>          block the calling application for an arbitrary amount

ACK

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list