#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <libkern/OSAtomic.h>
#include <mach/clock.h>
#include <mach/clock_types.h>
static pthread_mutex_t libusb_darwin_at_mutex;
static pthread_cond_t libusb_darwin_at_cond;
+static clock_serv_t clock_realtime;
+static clock_serv_t clock_monotonic;
+
static CFRunLoopRef libusb_darwin_acfl = NULL; /* async cf loop */
-static int initCount = 0;
+static volatile int32_t initCount = 0;
/* async event thread */
static pthread_t libusb_darwin_at;
struct libusb_context *ctx = (struct libusb_context *)arg0;
CFRunLoopRef runloop;
+ /* Set this thread's name, so it can be seen in the debugger
+ and crash reports. */
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+ pthread_setname_np ("org.libusb.device-detach");
+#endif
+
/* Tell the Objective-C garbage collector about this thread.
This is required because, unlike NSThreads, pthreads are
not automatically registered. Although we don't use
/* add the notification port to the run loop */
libusb_notification_port = IONotificationPortCreate (kIOMasterPortDefault);
libusb_notification_cfsource = IONotificationPortGetRunLoopSource (libusb_notification_port);
- CFRunLoopAddSource(CFRunLoopGetCurrent (), libusb_notification_cfsource, kCFRunLoopDefaultMode);
+ CFRunLoopAddSource(runloop, libusb_notification_cfsource, kCFRunLoopDefaultMode);
/* create notifications for removed devices */
kresult = IOServiceAddMatchingNotification (libusb_notification_port, kIOTerminatedNotification,
usbi_info (ctx, "thread ready to receive events");
- /* let the main thread know about the async runloop */
- libusb_darwin_acfl = CFRunLoopGetCurrent ();
-
/* signal the main thread */
pthread_mutex_lock (&libusb_darwin_at_mutex);
+ libusb_darwin_acfl = runloop;
pthread_cond_signal (&libusb_darwin_at_cond);
pthread_mutex_unlock (&libusb_darwin_at_mutex);
usbi_info (ctx, "thread exiting");
/* delete notification port */
- CFRunLoopSourceInvalidate (libusb_notification_cfsource);
IONotificationPortDestroy (libusb_notification_port);
IOObjectRelease (libusb_rem_device_iterator);
}
static int darwin_init(struct libusb_context *ctx) {
- if (!(initCount++)) {
+ host_name_port_t host_self;
+
+ if (OSAtomicIncrement32Barrier(&initCount) == 1) {
+ /* create the clocks that will be used */
+
+ host_self = mach_host_self();
+ host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime);
+ host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic);
+ mach_port_deallocate(mach_task_self(), host_self);
+
pthread_mutex_init (&libusb_darwin_at_mutex, NULL);
pthread_cond_init (&libusb_darwin_at_cond, NULL);
}
static void darwin_exit (void) {
- if (!(--initCount)) {
+ if (OSAtomicDecrement32Barrier(&initCount) == 0) {
+ mach_port_deallocate(mach_task_self(), clock_realtime);
+ mach_port_deallocate(mach_task_self(), clock_monotonic);
/* stop the async runloop */
CFRunLoopStop (libusb_darwin_acfl);
/* attaching/detaching kernel drivers is not currently supported (maybe in the future?) */
static int darwin_attach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
+ (void)dev_handle;
+ (void)interface;
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static int darwin_detach_kernel_driver (struct libusb_device_handle *dev_handle, int interface) {
+ (void)dev_handle;
+ (void)interface;
return LIBUSB_ERROR_NOT_SUPPORTED;
}
static void darwin_destroy_device(struct libusb_device *dev) {
+ (void)dev;
}
static int submit_bulk_transfer(struct usbi_transfer *itransfer) {
struct usbi_transfer *itransfer;
UInt32 io_size;
IOReturn kresult;
- int i = 0, ret;
+ POLL_NFDS_TYPE i = 0;
+ ssize_t ret;
UInt32 message;
usbi_mutex_lock(&ctx->open_devs_lock);
if (!(pollfd->revents & POLLERR)) {
ret = read (hpriv->fds[0], &message, sizeof (message));
- if (ret < sizeof (message))
+ if (ret < (ssize_t)sizeof (message))
continue;
} else
/* could not poll the device-- response is to delete the device (this seems a little heavy-handed) */
switch (clk_id) {
case USBI_CLOCK_REALTIME:
/* CLOCK_REALTIME represents time since the epoch */
- host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &clock_ref);
+ clock_ref = clock_realtime;
break;
case USBI_CLOCK_MONOTONIC:
/* use system boot time as reference for the monotonic clock */
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &clock_ref);
+ clock_ref = clock_monotonic;
break;
default:
return LIBUSB_ERROR_INVALID_PARAM;