From: Krzysztof Opasiak Date: Mon, 29 Jun 2015 17:06:25 +0000 (+0200) Subject: Introduce device reference counting X-Git-Tag: submit/tizen_common/20160317.155115~60 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=205c3d45ee4191d1653a633318ea81a2bb52cd3b;p=platform%2Fcore%2Fapi%2Fusb-host.git Introduce device reference counting We should not free() usb devices explicity in libhusb_free_devices() but just decrement their refcount and free only if it is realy necessary. Change-Id: I8474942e0305c25b8f41abb4dd018ce5bc05c9ec Signed-off-by: Krzysztof Opasiak --- diff --git a/include/libhusb.h b/include/libhusb.h index fa26362..868cee1 100644 --- a/include/libhusb.h +++ b/include/libhusb.h @@ -130,6 +130,10 @@ ssize_t libhusb_get_devices(libhusb_context *ctx, libhusb_device ***devs); void libhusb_free_devices(libhusb_device **list, int unref_devices); +libhusb_device *libhusb_ref_device(libhusb_device *dev); + +void libhusb_unref_device(libhusb_device *dev); + int libhusb_get_max_packet_size(libhusb_device *dev, uint8_t endpoint); uint8_t libhusb_get_bus_number(libhusb_device *dev); diff --git a/src/libhusb.c b/src/libhusb.c index 02ca338..415f8b1 100644 --- a/src/libhusb.c +++ b/src/libhusb.c @@ -23,14 +23,24 @@ #include #include +#include "libhusb.h" +#include "uref.h" +#include "common.h" + struct libhusb_context { libusb_context *lusb_ctx; }; struct libhusb_device { + struct uref ref; libusb_device *lusb_dev; }; +static inline struct libhusb_device *to_libhusb_device(struct uref *_uref) +{ + return container_of(_uref, struct libhusb_device, ref); +} + struct libhusb_device_handle { struct libusb_device_handle *lusb_dev_handle; }; @@ -105,6 +115,30 @@ int libhusb_get_port_numbers(libhusb_device *dev, uint8_t* port_numbers, int por return port_num; } +static void free_device(struct uref *uref) +{ + struct libhusb_device *dev = to_libhusb_device(uref); + + libusb_unref_device(dev->lusb_dev); + free(dev); +} + +static struct libhusb_device *alloc_device(libusb_device *lusb_dev) +{ + struct libhusb_device *dev; + + dev = malloc(sizeof(*dev)); + if (!dev) + goto out; + + uref_init(&dev->ref, free_device); + + libusb_ref_device(lusb_dev); + dev->lusb_dev = lusb_dev; +out: + return dev; +} + ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs) { ssize_t len; @@ -121,27 +155,43 @@ ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs) return -1; list = calloc(len + 1, sizeof(*list)); - if (!list) { - libusb_free_device_list(lusb_list, 1); - return -99; /* TODO replace with propper error*/ - } + if (!list) + goto free_lusb_list; list[len] = NULL; for (i = 0; i < len; i++) { - rdevice = malloc(sizeof(*rdevice)); - if (!rdevice) { - libusb_free_device_list(lusb_list, 1); - return -99; /* TODO replace with propper error*/ - } + rdevice = alloc_device(lusb_list[i]); + if (!rdevice) + goto free_dev_list; + list[i] = rdevice; - list[i]->lusb_dev = lusb_list[i]; } *devs = list; - libusb_free_device_list(lusb_list, 0); + libusb_free_device_list(lusb_list, 1); return len; + +free_dev_list: + while (--i <= 0) + libhusb_unref_device(list[i]); + free(list); +free_lusb_list: + libusb_free_device_list(lusb_list, 1); + + return -99; /* TODO replace with propper error*/ +} + +libhusb_device *libhusb_ref_device(libhusb_device *dev) +{ + uref_get(&dev->ref); + return dev; +} + +void libhusb_unref_device(libhusb_device *dev) +{ + uref_put(&dev->ref); } void libhusb_free_devices(libhusb_device **list, int unref_devices) @@ -151,14 +201,9 @@ void libhusb_free_devices(libhusb_device **list, int unref_devices) if (!list) return; - for (i = 0; list[i] != NULL; i++) { - if (unref_devices) { - struct libusb_device *devp = list[i]->lusb_dev; - assert(devp); - libusb_unref_device(devp); - } - free(list[i]); - } + for (i = 0; list[i] != NULL; i++) + if (unref_devices) + libhusb_unref_device(list[i]); free(list); } @@ -171,7 +216,7 @@ int libhusb_get_max_packet_size(libhusb_device *dev, uint8_t endpoint) ret = libusb_get_max_iso_packet_size(dev->lusb_dev, endpoint); if (ret < 0) - ret = usb_device_get_error_num(ret); + ret = -99; return ret; }