FU Logo
  • Startseite
  • Kontakt
  • Impressum
  • Home
  • Listenauswahl
  • Anleitungen

[linux-minidisc] [PATCH 03/14] Export methods to release resources.

<-- thread -->
<-- date -->
  • From: Vincent Pelletier <plr.vincent@gmail.com>
  • To: <linux-minidisc@lists.fu-berlin.de>
  • Date: Thu, 11 Feb 2010 21:47:36 -0000
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:in-reply-to:references:from:date:subject:to:mime-version :content-type:x-length:x-uid; b=EuYbZ4texlKY/JrtYHY7p18QEnqbifHTbZevUjeK2eCY/CGkvZxCvzF1PsxfD4snlj emokREhS3g+DAsfQk5R11x3PS2NGPAUJY5GoGhC2zjrX1R45bClmz9EKeH/SCL0z2mBv 594a3iEz8M8meAOpCSrt3VMe58HseDnB2zssQ=
  • Subject: [linux-minidisc] [PATCH 03/14] Export methods to release resources.

This allows user to work-around race conditions in interpreter shutdown,
where context might be freed before handle - for example.
---
 netmd/usb1.py |  243 ++-------------------------------------------------------
 1 files changed, 6 insertions(+), 237 deletions(-)

diff --git a/netmd/usb1.py b/netmd/usb1.py
index cd0711b..d22f52a 100644
--- a/netmd/usb1.py
+++ b/netmd/usb1.py
@@ -1,6 +1,6 @@
 # pyusb compatibility layer for libus-1.0
 import libusb1
-from ctypes import byref, create_string_buffer, c_int, sizeof, POINTER
+from ctypes import byref, create_string_buffer, c_int
 from cStringIO import StringIO
 
 __all__ = ['LibUSBContext']
@@ -8,136 +8,10 @@ __all__ = ['LibUSBContext']
 # Default string length
 STRING_LENGTH = 256
 
-EVENT_CALLBACK_SET = frozenset((
-  libusb1.LIBUSB_TRANSFER_COMPLETED,
-  libusb1.LIBUSB_TRANSFER_ERROR,
-  libusb1.LIBUSB_TRANSFER_TIMED_OUT,
-  libusb1.LIBUSB_TRANSFER_CANCELLED,
-  libusb1.LIBUSB_TRANSFER_STALL,
-  libusb1.LIBUSB_TRANSFER_NO_DEVICE,
-  libusb1.LIBUSB_TRANSFER_OVERFLOW,
-))
-
-DEFAULT_ASYNC_TRANSFER_ERROR_CALLBACK = lambda x, y: False
-
-class USBAsyncReaderBase(object):
-    _handle = None
-    _submited = False
-
-    def __init__(self, handle, endpoint, size, user_data=None, timeout=0):
-        data = create_string_buffer(size)
-        self._data = data
-        self._transfer = self._getTransfer(
-          handle,
-          endpoint,
-          data,
-          self._callbackDispatcher,
-          user_data,
-          timeout,
-        )
-        # XXX: set _handle *after* _transfer, so __del__ doesn't get an
-        # exception if called during constructor execution.
-        self._handle = handle
-        self._event_callback_dict = {}
-        self._errorCallback = DEFAULT_ASYNC_TRANSFER_ERROR_CALLBACK
-
-    def submit(self):
-        self._submited = True
-        self._handle.submitTransfer(self._transfer)
-
-    def cancel(self):
-        self._handle.cancelTransfer(self._transfer)
-        self._submited = False
-
-    def setEventCallback(self, event, callback):
-        if event not in EVENT_CALLBACK_SET:
-            raise ValueError, 'Unknown event %r.' % (event, )
-        self._event_callback_dict[event] = callback
-
-    def setDefaultCallback(self, callback):
-        self._errorCallback = callback
-
-    def getEventCallback(self, event, default=None):
-        return self._event_callback_dict.get(event, default)
-
-    def _callbackDispatcher(self, transfer_p):
-        transfer = self._transfer.contents #transfer_p.contents
-        if self.getEventCallback(transfer.status, self._errorCallback)(
-            transfer, self._data):
-            self.submit()
-        else:
-            self._submited = False
-
-    def isSubmited(self):
-        return self._submited
-
-    def __del__(self):
-        if self._handle is not None:
-            try:
-                self.cancel()
-            except libusb1.USBError, exception:
-                if exception.value != libusb1.LIBUSB_ERROR_NOT_FOUND:
-                    raise
-
-class USBAsyncBulkReader(USBAsyncReaderBase):
-    def _getTransfer(self, handle, *args, **kw):
-        return handle.getBulkTransfer(*args, **kw)
-
-class USBAsyncInterruptReader(USBAsyncReaderBase):
-    def _getTransfer(self, handle, *args, **kw):
-        return handle.getInterruptTransfer(*args, **kw)
-
-class USBPoller(object):
-    def __init__(self, context, poller):
-        self.context = context
-        self.poller = poller
-        fd_set = set()
-        self.fd_set = fd_set
-        context.setPollFDNotifiers(self._registerFD, self._unregisterFD)
-        for fd, events in context.getPollFDList():
-            self._registerFD(fd, events)
-
-    def poll(self, timeout=None):
-        fd_set = self.fd_set
-        next_usb_timeout = self.context.getNextTimeout()
-        if next_usb_timeout == 0:
-            next_usb_timeout = None
-        if timeout is None:
-            usb_timeout = next_usb_timeout
-        else:
-            usb_timeout = min(next_usb_timeout or timeout, timeout)
-        event_list = self.poller.poll(usb_timeout)
-        event_list_len = len(event_list)
-        if event_list_len:
-            result = [(x, y) for x, y in event_list if x not in fd_set]
-            if len(result) != event_list_len:
-                self.context.handleEventsTimeout()
-        else:
-            result = event_list
-            self.context.handleEventsTimeout()
-        return result
-
-    def register(self, fd, events):
-        self.poller.register(fd, events)
-
-    def unregister(self, fd):
-        self.poller.unregister(fd)
-
-    def _registerFD(self, fd, events, user_data=None):
-        self.fd_set.add(fd)
-        self.register(fd, events)
-
-    def _unregisterFD(self, fd, user_data=None):
-        self.unregister(fd)
-        self.sd_set.discard(fd)
-
 class USBDeviceHandle(object):
     handle = None
 
-    def __init__(self, context, handle):
-        # XXX Context parameter is just here as a hint for garbage collector:
-        # It must collect USBDeviceHandle instance before their LibUSBContext.
-        self.context = context
+    def __init__(self, handle):
         self.handle = handle
 
     def __del__(self):
@@ -288,78 +162,11 @@ class USBDeviceHandle(object):
         transferred = self._interruptTransfer(endpoint, data, length, timeout)
         return data.raw[:transferred]
 
-    def _getTransfer(self, iso_packets=0):
-        result = libusb1.libusb_alloc_transfer(iso_packets)
-        if not result:
-            raise libusb1.USBError, 'Unable to get a transfer object'
-        return result
-
-    def fillBulkTransfer(self, transfer, endpoint, string_buffer,
-                         callback, user_data, timeout):
-        libusb1.libusb_fill_bulk_transfer(transfer, self.handle,
-            endpoint, string_buffer, sizeof(string_buffer),
-            libusb1.libusb_transfer_cb_fn_p(callback), user_data,
-            timeout)
-
-    def getBulkTransfer(self, endpoint, string_buffer, callback,
-                        user_data=None, timeout=0):
-        result = self._getTransfer()
-        self.fillBulkTransfer(result, endpoint, string_buffer, callback,
-            user_data, timeout)
-        return result
-
-    def fillInterruptTransfer(self, transfer, endpoint, string_buffer,
-                              callback, user_data, timeout):
-        libusb1.libusb_fill_interrupt_transfer(transfer, self.handle,
-            endpoint, string_buffer,  sizeof(string_buffer),
-            libusb1.libusb_transfer_cb_fn_p(callback), user_data,
-            timeout)
-
-    def getInterruptTransfer(self, endpoint, string_buffer, callback,
-                             user_data=None, timeout=0):
-        result = self._getTransfer()
-        self.fillInterruptTransfer(result, endpoint, string_buffer,
-            callback, user_data, timeout)
-        return result
-
-    def fillControlSetup(self, string_buffer, request_type, request, value,
-                         index, length):
-        libusb1.libusb_fill_control_setup(string_buffer, request_type,
-            request, value, index, length)
-
-    def fillControlTransfer(self, transfer, setup, callback,
-                            user_data, timeout):
-        libusb1.libusb_fill_control_transfer(transfer, self.handle,
-            setup, libusb1.libusb_transfer_cb_fn_p(callback), user_data,
-            timeout)
-
-    def getControlTransfer(self, setup, callback, user_data=None, timeout=0):
-        result = self._getTransfer()
-        self.fillControlTransfer(result, setup, callback, user_data, timeout)
-        return result
-
-    def fillISOTransfer(self, *args, **kw):
-        raise NotImplementedError
-
-    def getISOTransfer(self, *args, **kw):
-        raise NotImplementedError
-
-    def submitTransfer(self, transfer):
-        result = libusb1.libusb_submit_transfer(transfer)
-        if result:
-            raise libusb1.USBError, result
-
-    def cancelTransfer(self, transfer):
-        result = libusb1.libusb_cancel_transfer(transfer)
-        if result:
-            raise libusb1.USBError, result
-
 class USBDevice(object):
 
     configuration_descriptor_list = None
 
-    def __init__(self, context, device_p):
-        self.context = context
+    def __init__(self, device_p):
         libusb1.libusb_ref_device(device_p)
         self.device_p = device_p
         # Fetch device descriptor
@@ -500,7 +307,7 @@ class USBDevice(object):
         result = libusb1.libusb_open(self.device_p, byref(handle))
         if result:
             raise libusb1.USBError, result
-        return USBDeviceHandle(self.context, handle)
+        return USBDeviceHandle(handle)
 
 class LibUSBContext(object):
 
@@ -526,7 +333,7 @@ class LibUSBContext(object):
         device_p_p = libusb1.libusb_device_p_p()
         device_list_len = libusb1.libusb_get_device_list(self.context_p,
                                                          byref(device_p_p))
-        result = [USBDevice(self, x) for x in device_p_p[:device_list_len]]
+        result = [USBDevice(x) for x in device_p_p[:device_list_len]]
         # XXX: causes problems, why ?
         #libusb1.libusb_free_device_list(device_p_p, 1)
         return result
@@ -535,46 +342,8 @@ class LibUSBContext(object):
         handle_p = libusb1.libusb_open_device_with_vid_pid(self.context_p,
             vendor_id, product_id)
         if handle_p:
-            result = USBDeviceHandle(self, handle_p)
+            result = USBDeviceHandle(handle_p)
         else:
             result = None
         return result
 
-    def getPollFDList(self):
-        pollfd_p_p = libusb1.libusb_get_pollfds(self.context_p)
-        result = []
-        append = result.append
-        fd_index = 0
-        while pollfd_p_p[fd_index]:
-            append((pollfd_p_p[fd_index].contents.fd,
-                    pollfd_p_p[fd_index].contents.events))
-            fd_index += 1
-        return result
-
-    def handleEvents(self):
-        result = libusb1.libusb_handle_events(self.context_p)
-        if result:
-            raise libusb1.USBError, result
-
-    def handleEventsTimeout(self, tv=None):
-        assert tv is None, 'tv parameter is not supported yet'
-        tv = libusb1.timeval(0, 0)
-        result = libusb1.libusb_handle_events_timeout(self.context_p, byref(tv))
-        if result:
-            raise libusb1.USBError, result
-
-    def setPollFDNotifiers(self, added_cb=None, removed_cb=None, user_data=None):
-        if added_cb is None:
-          added_cb = POINTER(None)
-        else:
-          added_cb = libusb1.libusb_pollfd_added_cb_p(added_cb)
-        if removed_cb is None:
-          removed_cb = POINTER(None)
-        else:
-          removed_cb = libusb1.libusb_pollfd_removed_cb_p(removed_cb)
-        libusb1.libusb_set_pollfd_notifiers(self.context_p, added_cb,
-                                            removed_cb, user_data)
-
-    def getNextTimeout(self):
-        return libusb1.libusb_get_next_timeout(self.context_p, None)
-
<-- thread -->
<-- date -->
  • References:
    • [linux-minidisc] [PATCH 01/14] Make some function accepting opaque data pointer accept a py_object.
      • From: Vincent Pelletier <plr.vincent@gmail.com>
  • linux-minidisc - February 2010 - Archives indexes sorted by:
    [ thread ] [ subject ] [ author ] [ date ]
  • Complete archive of the linux-minidisc mailing list
  • More info on this list...

Hilfe

  • FAQ
  • Dienstbeschreibung
  • ZEDAT Beratung
  • postmaster@lists.fu-berlin.de

Service-Navigation

  • Startseite
  • Listenauswahl

Einrichtung Mailingliste

  • ZEDAT-Portal
  • Mailinglisten Portal