diff options
author | Nathan Hjelm <hjelmn@mac.com> | 2010-02-15 14:07:44 -0600 |
---|---|---|
committer | Daniel Drake <dan@reactivated.net> | 2010-02-15 14:07:44 -0600 |
commit | 2a72f38548208044dc3aa62681419d006c35732d (patch) | |
tree | 25e651d300249b060e3af67707a7d1c322df8b6a | |
parent | a4186794d87124503db2f5f51f51ce90bb95daa7 (diff) | |
download | libusb-2a72f38548208044dc3aa62681419d006c35732d.tar.gz |
Darwin: support multiple calls to libusb_init
Credit to Orin Eman for finding this bug.
-rw-r--r-- | libusb/os/darwin_usb.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index dfae564..9dc2a10 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -44,6 +44,7 @@ static mach_port_t libusb_darwin_mp = 0; /* master port */ static CFRunLoopRef libusb_darwin_acfl = NULL; /* async cf loop */ +static int initCount = 0; /* async event thread */ static pthread_t libusb_darwin_at; @@ -309,33 +310,37 @@ static void *event_thread_main (void *arg0) { static int darwin_init(struct libusb_context *ctx) { IOReturn kresult; - /* Create the master port for talking to IOKit */ - if (!libusb_darwin_mp) { - kresult = IOMasterPort (MACH_PORT_NULL, &libusb_darwin_mp); + if (!(initCount++)) { + /* Create the master port for talking to IOKit */ + if (!libusb_darwin_mp) { + kresult = IOMasterPort (MACH_PORT_NULL, &libusb_darwin_mp); - if (kresult != kIOReturnSuccess || !libusb_darwin_mp) - return darwin_to_libusb (kresult); - } + if (kresult != kIOReturnSuccess || !libusb_darwin_mp) + return darwin_to_libusb (kresult); + } - pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx); + pthread_create (&libusb_darwin_at, NULL, event_thread_main, (void *)ctx); - while (!libusb_darwin_acfl) - usleep (10); + while (!libusb_darwin_acfl) + usleep (10); + } return 0; } static void darwin_exit (void) { - void *ret; + if (!(--initCount)) { + void *ret; - /* stop the async runloop */ - CFRunLoopStop (libusb_darwin_acfl); - pthread_join (libusb_darwin_at, &ret); + /* stop the async runloop */ + CFRunLoopStop (libusb_darwin_acfl); + pthread_join (libusb_darwin_at, &ret); - if (libusb_darwin_mp) - mach_port_deallocate(mach_task_self(), libusb_darwin_mp); + if (libusb_darwin_mp) + mach_port_deallocate(mach_task_self(), libusb_darwin_mp); - libusb_darwin_mp = 0; + libusb_darwin_mp = 0; + } } static int darwin_get_device_descriptor(struct libusb_device *dev, unsigned char *buffer, int *host_endian) { |