From 3877711296cbfa4a0bcafc3c5560609a1ce2d079 Mon Sep 17 00:00:00 2001 From: Bryan Forbes Date: Fri, 30 Apr 2010 13:35:57 -0500 Subject: More memory leak plugging. Some code cleanup too. --- cython/afc.pxi | 6 +- cython/file_relay.pxi | 6 +- cython/imobiledevice.pyx | 55 +++++++++++------- cython/installation_proxy.pxi | 126 ++++++++++++++++++++++++++++++++-------- cython/lockdown.pxi | 29 ++++----- cython/mobile_image_mounter.pxi | 26 ++++++--- cython/mobilebackup.pxi | 6 +- cython/mobilesync.pxi | 6 +- cython/notification_proxy.pxi | 6 +- cython/sbservices.pxi | 14 ++--- cython/screenshotr.pxi | 20 ++++--- 11 files changed, 193 insertions(+), 107 deletions(-) (limited to 'cython') diff --git a/cython/afc.pxi b/cython/afc.pxi index 9200067..c33dbfd 100644 --- a/cython/afc.pxi +++ b/cython/afc.pxi @@ -154,11 +154,7 @@ cdef class AfcClient(BaseService): cdef afc_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - afc_error_t err - err = afc_client_new(dev._c_dev, port, &(self._c_client)) - self.handle_error(err) + self.handle_error(afc_client_new(device._c_dev, port, &(self._c_client))) def __dealloc__(self): cdef afc_error_t err diff --git a/cython/file_relay.pxi b/cython/file_relay.pxi index fd7b67e..beb429b 100644 --- a/cython/file_relay.pxi +++ b/cython/file_relay.pxi @@ -38,11 +38,7 @@ cdef class FileRelayClient(PropertyListService): cdef file_relay_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - file_relay_error_t err - err = file_relay_client_new(dev._c_dev, port, &self._c_client) - self.handle_error(err) + self.handle_error(file_relay_client_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): cdef file_relay_error_t err diff --git a/cython/imobiledevice.pyx b/cython/imobiledevice.pyx index bde43d0..7898290 100644 --- a/cython/imobiledevice.pyx +++ b/cython/imobiledevice.pyx @@ -102,13 +102,16 @@ def event_unsubscribe(): def get_device_list(): cdef: - char** devices + char** devices = NULL int count list result bytes device iDeviceError err = iDeviceError(idevice_get_device_list(&devices, &count)) - if err: raise err + if err: + if devices != NULL: + idevice_device_list_free(devices) + raise err result = [] for i from 0 <= i < count: @@ -131,15 +134,16 @@ cdef class iDeviceConnection(Base): cdef inline BaseError _error(self, int16_t ret): return iDeviceError(ret) +cimport stdlib + cdef class iDevice(Base): - def __cinit__(self, uuid=None, *args, **kwargs): - cdef: - char* c_uuid = NULL - idevice_error_t err - if uuid is not None: - c_uuid = uuid - err = idevice_new(&self._c_dev, c_uuid) - self.handle_error(err) + def __cinit__(self, object uuid=None, *args, **kwargs): + cdef char* c_uuid = NULL + if isinstance(uuid, basestring): + c_uuid = uuid + elif uuid is not None: + raise TypeError("iDevice's constructor takes a string or None as the uuid argument") + self.handle_error(idevice_new(&self._c_dev, c_uuid)) def __dealloc__(self): if self._c_dev is not NULL: @@ -151,10 +155,19 @@ cdef class iDevice(Base): cpdef iDeviceConnection connect(self, uint16_t port): cdef: idevice_error_t err - iDeviceConnection conn = iDeviceConnection.__new__(iDeviceConnection) - err = idevice_connect(self._c_dev, port, &conn._c_connection) - self.handle_error(err) - return conn + idevice_connection_t c_conn = NULL + iDeviceConnection conn + err = idevice_connect(self._c_dev, port, &c_conn) + try: + self.handle_error(err) + + conn = iDeviceConnection.__new__(iDeviceConnection) + conn._c_connection = c_conn + + return conn + except Exception, e: + if c_conn != NULL: + idevice_disconnect(c_conn) property uuid: def __get__(self): @@ -162,8 +175,12 @@ cdef class iDevice(Base): char* uuid idevice_error_t err err = idevice_get_uuid(self._c_dev, &uuid) - self.handle_error(err) - return uuid + try: + self.handle_error(err) + return uuid + except Exception, e: + if uuid != NULL: + stdlib.free(uuid) property handle: def __get__(self): cdef uint32_t handle @@ -173,8 +190,6 @@ cdef class iDevice(Base): cdef extern from *: ctypedef char* const_char_ptr "const char*" -cimport stdlib - cdef class BaseService(Base): __service_name__ = None @@ -189,13 +204,13 @@ cdef class PropertyListService(BaseService): err = self._receive(&c_node) try: self.handle_error(err) + + return plist.plist_t_to_node(c_node) except BaseError, e: if c_node != NULL: plist.plist_free(c_node) raise - return plist.plist_t_to_node(c_node) - cdef inline int16_t _send(self, plist.plist_t node): raise NotImplementedError("send is not implemented") diff --git a/cython/installation_proxy.pxi b/cython/installation_proxy.pxi index cf6662f..3dfb0b1 100644 --- a/cython/installation_proxy.pxi +++ b/cython/installation_proxy.pxi @@ -64,71 +64,109 @@ cdef class InstallationProxyClient(PropertyListService): plist.Node options plist.plist_t c_options plist.plist_t c_result = NULL + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) err = instproxy_browse(self._c_client, c_options, &c_result) - self.handle_error(err) - return plist.plist_t_to_node(c_result) + + try: + self.handle_error(err) + return plist.plist_t_to_node(c_result) + except Exception, e: + if c_result != NULL: + plist.plist_free(c_result) + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef install(self, bytes pkg_path, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) if callback is None: - err = instproxy_install(self._c_client, pkg_path, options._c_node, NULL, NULL) + err = instproxy_install(self._c_client, pkg_path, c_options, NULL, NULL) else: - err = instproxy_install(self._c_client, pkg_path, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_install(self._c_client, pkg_path, c_options, instproxy_notify_cb, callback) + + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef upgrade(self, bytes pkg_path, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) if callback is None: - err = instproxy_upgrade(self._c_client, pkg_path, options._c_node, NULL, NULL) + err = instproxy_upgrade(self._c_client, pkg_path, c_options, NULL, NULL) else: - err = instproxy_upgrade(self._c_client, pkg_path, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_upgrade(self._c_client, pkg_path, c_options, instproxy_notify_cb, callback) + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef uninstall(self, bytes appid, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options instproxy_error_t err + bint free_options = False if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) + if callback is None: - err = instproxy_uninstall(self._c_client, appid, options._c_node, NULL, NULL) + err = instproxy_uninstall(self._c_client, appid, c_options, NULL, NULL) else: - err = instproxy_uninstall(self._c_client, appid, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_uninstall(self._c_client, appid, c_options, instproxy_notify_cb, callback) + + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef plist.Node lookup_archives(self, object client_options): cdef: @@ -136,70 +174,112 @@ cdef class InstallationProxyClient(PropertyListService): plist.plist_t c_options plist.plist_t c_node = NULL instproxy_error_t err + bint free_options = False if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) - err = instproxy_lookup_archives(self._c_client, options._c_node, &c_node) - self.handle_error(err) - return plist.plist_t_to_node(c_node) + + err = instproxy_lookup_archives(self._c_client, c_options, &c_node) + + try: + self.handle_error(err) + return plist.plist_t_to_node(c_node) + except Exception, e: + if c_node != NULL: + plist.plist_free(c_node) + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef archive(self, bytes appid, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) + if callback is None: - err = instproxy_archive(self._c_client, appid, options._c_node, NULL, NULL) + err = instproxy_archive(self._c_client, appid, c_options, NULL, NULL) else: - err = instproxy_archive(self._c_client, appid, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_archive(self._c_client, appid, c_options, instproxy_notify_cb, callback) + + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef restore(self, bytes appid, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) + if callback is None: - err = instproxy_restore(self._c_client, appid, options._c_node, NULL, NULL) + err = instproxy_restore(self._c_client, appid, c_options, NULL, NULL) else: - err = instproxy_restore(self._c_client, appid, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_restore(self._c_client, appid, c_options, instproxy_notify_cb, callback) + + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cpdef remove_archive(self, bytes appid, object client_options, object callback=None): cdef: plist.Node options plist.plist_t c_options + bint free_options = False instproxy_error_t err if isinstance(client_options, plist.Dict): options = client_options c_options = options._c_node elif isinstance(client_options, dict): c_options = plist.native_to_plist_t(client_options) + free_options = True else: raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) + if callback is None: - err = instproxy_remove_archive(self._c_client, appid, options._c_node, NULL, NULL) + err = instproxy_remove_archive(self._c_client, appid, c_options, NULL, NULL) else: - err = instproxy_remove_archive(self._c_client, appid, options._c_node, instproxy_notify_cb, callback) - self.handle_error(err) + err = instproxy_remove_archive(self._c_client, appid, c_options, instproxy_notify_cb, callback) + + try: + self.handle_error(err) + except Exception, e: + raise + finally: + if free_options: + plist.plist_free(c_options) cdef inline BaseError _error(self, int16_t ret): return InstallationProxyError(ret) diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi index be9d25f..a904d12 100644 --- a/cython/lockdown.pxi +++ b/cython/lockdown.pxi @@ -90,18 +90,17 @@ cdef class LockdownPairRecord: cdef class LockdownClient(PropertyListService): def __cinit__(self, iDevice device not None, bytes label="", bool handshake=True, *args, **kwargs): cdef: - iDevice dev = device lockdownd_error_t err char* c_label = NULL if label: c_label = label if handshake: - err = lockdownd_client_new_with_handshake(dev._c_dev, &self._c_client, c_label) + err = lockdownd_client_new_with_handshake(device._c_dev, &self._c_client, c_label) else: - err = lockdownd_client_new(dev._c_dev, &self._c_client, c_label) + err = lockdownd_client_new(device._c_dev, &self._c_client, c_label) self.handle_error(err) - self.device = dev + self.device = device def __dealloc__(self): cdef lockdownd_error_t err @@ -117,15 +116,15 @@ cdef class LockdownClient(PropertyListService): err = lockdownd_query_type(self._c_client, &c_type) try: self.handle_error(err) + result = c_type + + return result except BaseError, e: raise finally: if c_type != NULL: - result = c_type stdlib.free(c_type) - return result - cpdef plist.Node get_value(self, bytes domain=None, bytes key=None): cdef: lockdownd_error_t err @@ -136,16 +135,18 @@ cdef class LockdownClient(PropertyListService): c_domain = domain if key is not None: c_key = key + err = lockdownd_get_value(self._c_client, c_domain, c_key, &c_node) + try: self.handle_error(err) + + return plist.plist_t_to_node(c_node) except BaseError, e: if c_node != NULL: plist.plist_free(c_node) raise - return plist.plist_t_to_node(c_node) - cpdef set_value(self, bytes domain, bytes key, object value): cdef plist.plist_t c_node = plist.native_to_plist_t(value) try: @@ -175,11 +176,11 @@ cdef class LockdownClient(PropertyListService): try: self.handle_error(lockdownd_start_service(self._c_client, c_service_name, &port)) + + return port except BaseError, e: raise - return port - cpdef object get_service_client(self, object service_class): cdef: uint16_t port = 0 @@ -202,15 +203,15 @@ cdef class LockdownClient(PropertyListService): err = lockdownd_start_session(self._c_client, host_id, &c_session_id, &ssl_enabled) try: self.handle_error(err) + + session_id = c_session_id + return (session_id, ssl_enabled) except BaseError, e: raise finally: if c_session_id != NULL: - session_id = c_session_id stdlib.free(c_session_id) - return (session_id, ssl_enabled) - cpdef stop_session(self, bytes session_id): self.handle_error(lockdownd_stop_session(self._c_client, session_id)) diff --git a/cython/mobile_image_mounter.pxi b/cython/mobile_image_mounter.pxi index e70cff7..bf304d4 100644 --- a/cython/mobile_image_mounter.pxi +++ b/cython/mobile_image_mounter.pxi @@ -32,11 +32,7 @@ cdef class MobileImageMounterClient(PropertyListService): cdef mobile_image_mounter_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - mobile_image_mounter_error_t err - err = mobile_image_mounter_new(dev._c_dev, port, &self._c_client) - self.handle_error(err) + self.handle_error(mobile_image_mounter_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): cdef mobile_image_mounter_error_t err @@ -52,8 +48,14 @@ cdef class MobileImageMounterClient(PropertyListService): plist.plist_t c_node = NULL mobile_image_mounter_error_t err err = mobile_image_mounter_lookup_image(self._c_client, image_type, &c_node) - self.handle_error(err) - return plist.plist_t_to_node(c_node) + + try: + self.handle_error(err) + + return plist.plist_t_to_node(c_node) + except Exception, e: + if c_node != NULL: + plist.plist_free(c_node) cpdef plist.Node mount_image(self, bytes image_path, bytes image_signature, bytes image_type): cdef: @@ -61,8 +63,14 @@ cdef class MobileImageMounterClient(PropertyListService): mobile_image_mounter_error_t err err = mobile_image_mounter_mount_image(self._c_client, image_path, image_signature, len(image_signature), image_type, &c_node) - self.handle_error(err) - return plist.plist_t_to_node(c_node) + + try: + self.handle_error(err) + + return plist.plist_t_to_node(c_node) + except Exception, e: + if c_node != NULL: + plist.plist_free(c_node) cpdef hangup(self): cdef mobile_image_mounter_error_t err diff --git a/cython/mobilebackup.pxi b/cython/mobilebackup.pxi index cb5276e..4f07683 100644 --- a/cython/mobilebackup.pxi +++ b/cython/mobilebackup.pxi @@ -33,11 +33,7 @@ cdef class MobileBackupClient(PropertyListService): cdef mobilebackup_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - mobilebackup_error_t err - err = mobilebackup_client_new(dev._c_dev, port, &self._c_client) - self.handle_error(err) + self.handle_error(mobilebackup_client_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): cdef mobilebackup_error_t err diff --git a/cython/mobilesync.pxi b/cython/mobilesync.pxi index 1b36ba7..00b511f 100644 --- a/cython/mobilesync.pxi +++ b/cython/mobilesync.pxi @@ -33,11 +33,7 @@ cdef class MobileSyncClient(DeviceLinkService): cdef mobilesync_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - mobilesync_error_t err - err = mobilesync_client_new(dev._c_dev, port, &(self._c_client)) - self.handle_error(err) + self.handle_error(mobilesync_client_new(device._c_dev, port, &(self._c_client))) def __dealloc__(self): cdef mobilesync_error_t err diff --git a/cython/notification_proxy.pxi b/cython/notification_proxy.pxi index ccc30f8..07a72d9 100644 --- a/cython/notification_proxy.pxi +++ b/cython/notification_proxy.pxi @@ -89,11 +89,7 @@ cdef class NotificationProxyClient(PropertyListService): cdef np_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - np_error_t err - err = np_client_new(dev._c_dev, port, &self._c_client) - self.handle_error(err) + self.handle_error(np_client_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): cdef np_error_t err diff --git a/cython/sbservices.pxi b/cython/sbservices.pxi index 55c94a5..4d09b71 100644 --- a/cython/sbservices.pxi +++ b/cython/sbservices.pxi @@ -30,14 +30,12 @@ cdef class SpringboardServicesClient(PropertyListService): cdef sbservices_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - self.handle_error(sbservices_client_new(dev._c_dev, port, &self._c_client)) + self.handle_error(sbservices_client_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): if self._c_client is not NULL: - err = SpringboardServicesError(sbservices_client_free(self._c_client)) - if err: raise err + err = sbservices_client_free(self._c_client) + self.handle_error(err) cdef inline BaseError _error(self, int16_t ret): return SpringboardServicesError(ret) @@ -50,11 +48,12 @@ cdef class SpringboardServicesClient(PropertyListService): err = sbservices_get_icon_state(self._c_client, &c_node) try: self.handle_error(err) + + return plist.plist_t_to_node(c_node) except BaseError, e: if c_node != NULL: plist.plist_free(c_node) raise - return plist.plist_t_to_node(c_node) def __set__(self, plist.Node newstate not None): self.handle_error(sbservices_set_icon_state(self._c_client, newstate._c_node)) @@ -66,7 +65,8 @@ cdef class SpringboardServicesClient(PropertyListService): err = sbservices_get_icon_pngdata(self._c_client, bundleId, &pngdata, &pngsize) try: self.handle_error(err) + + return pngdata[:pngsize] except BaseError, e: stdlib.free(pngdata) raise - return pngdata[:pngsize] diff --git a/cython/screenshotr.pxi b/cython/screenshotr.pxi index d7dfc57..9213b64 100644 --- a/cython/screenshotr.pxi +++ b/cython/screenshotr.pxi @@ -32,11 +32,7 @@ cdef class ScreenshotrClient(DeviceLinkService): cdef screenshotr_client_t _c_client def __cinit__(self, iDevice device not None, int port, *args, **kwargs): - cdef: - iDevice dev = device - screenshotr_error_t err - err = screenshotr_client_new(dev._c_dev, port, &self._c_client) - self.handle_error(err) + self.handle_error(screenshotr_client_new(device._c_dev, port, &self._c_client)) def __dealloc__(self): cdef screenshotr_error_t err @@ -46,15 +42,21 @@ cdef class ScreenshotrClient(DeviceLinkService): cpdef bytes take_screenshot(self): cdef: - char* c_data + char* c_data = NULL uint64_t data_size bytes result screenshotr_error_t err err = screenshotr_take_screenshot(self._c_client, &c_data, &data_size) - self.handle_error(err) - result = c_data[:data_size] - return result + try: + self.handle_error(err) + + result = c_data[:data_size] + return result + except Exception, e: + if c_data != NULL: + stdlib.free(c_data) + raise cdef inline BaseError _error(self, int16_t ret): return ScreenshotrError(ret) -- cgit v1.1-32-gdbae