mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-03-15 07:29:15 +01:00
Merged in skarlsso/librepilot/skarlsso/LP-155_gcs_osx_hid_crash (pull request #92)
Skarlsso/lp 155_gcs_osx_hid_crash
This commit is contained in:
commit
084ba62e4f
@ -118,6 +118,8 @@ struct hid_device_ {
|
|||||||
pthread_barrier_t barrier; /* Ensures correct startup sequence */
|
pthread_barrier_t barrier; /* Ensures correct startup sequence */
|
||||||
pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */
|
pthread_barrier_t shutdown_barrier; /* Ensures correct shutdown sequence */
|
||||||
int shutdown_thread;
|
int shutdown_thread;
|
||||||
|
|
||||||
|
bool run_loop_stopped;
|
||||||
};
|
};
|
||||||
|
|
||||||
static hid_device *new_hid_device(void)
|
static hid_device *new_hid_device(void)
|
||||||
@ -133,6 +135,7 @@ static hid_device *new_hid_device(void)
|
|||||||
dev->input_report_buf = NULL;
|
dev->input_report_buf = NULL;
|
||||||
dev->input_reports = NULL;
|
dev->input_reports = NULL;
|
||||||
dev->shutdown_thread = 0;
|
dev->shutdown_thread = 0;
|
||||||
|
dev->run_loop_stopped = 0;
|
||||||
|
|
||||||
/* Thread objects */
|
/* Thread objects */
|
||||||
pthread_mutex_init(&dev->mutex, NULL);
|
pthread_mutex_init(&dev->mutex, NULL);
|
||||||
@ -173,7 +176,13 @@ static void free_hid_device(hid_device *dev)
|
|||||||
pthread_mutex_destroy(&dev->mutex);
|
pthread_mutex_destroy(&dev->mutex);
|
||||||
|
|
||||||
/* Free the structure itself. */
|
/* Free the structure itself. */
|
||||||
free(dev);
|
// Note: We can't delete the dev struct, since we might get
|
||||||
|
// an asynchronous call to hid_device_removal_callback, which
|
||||||
|
// gets the dev passed as an argument.
|
||||||
|
//
|
||||||
|
// See stop_run_loop for an explanation why this happens.
|
||||||
|
//
|
||||||
|
// free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IOHIDManagerRef hid_mgr = 0x0;
|
static IOHIDManagerRef hid_mgr = 0x0;
|
||||||
@ -548,6 +557,38 @@ hid_device * HID_API_EXPORT hid_open(unsigned short vendor_id, unsigned short pr
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use a shared mutex for all devices.
|
||||||
|
static pthread_mutex_t stop_run_loop_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static void stop_run_loop(hid_device* dev)
|
||||||
|
{
|
||||||
|
bool stop_run_loop;
|
||||||
|
|
||||||
|
// There seems to be a bug in IOHIDDeviceRegisterRemovalCallback,
|
||||||
|
// which causes de-registration of the removal callback
|
||||||
|
// (hid_device_removal_callbacl) to fail.
|
||||||
|
//
|
||||||
|
// Because of this, hid_device_removal_callback will be called after
|
||||||
|
// the read_thread has executed perform_signal_callback, which also
|
||||||
|
// calls CFRunLoopStop. This second call to CFRunLoopStop is executed
|
||||||
|
// in another thread, sometimes after the read_thread has executed, and
|
||||||
|
// this causes crashes.
|
||||||
|
//
|
||||||
|
// Because of this asynchronous call to hid_device_removal_callback,
|
||||||
|
// the dev structs are leaked, for now.
|
||||||
|
|
||||||
|
pthread_mutex_lock(&stop_run_loop_mutex);
|
||||||
|
stop_run_loop = !dev->run_loop_stopped;
|
||||||
|
if (stop_run_loop) {
|
||||||
|
dev->run_loop_stopped = 1;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&stop_run_loop_mutex);
|
||||||
|
|
||||||
|
if (stop_run_loop) {
|
||||||
|
CFRunLoopStop(dev->run_loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void hid_device_removal_callback(void *context, IOReturn result,
|
static void hid_device_removal_callback(void *context, IOReturn result,
|
||||||
void *sender)
|
void *sender)
|
||||||
{
|
{
|
||||||
@ -555,7 +596,8 @@ static void hid_device_removal_callback(void *context, IOReturn result,
|
|||||||
hid_device *d = context;
|
hid_device *d = context;
|
||||||
|
|
||||||
d->disconnected = 1;
|
d->disconnected = 1;
|
||||||
CFRunLoopStop(d->run_loop);
|
|
||||||
|
stop_run_loop(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Run Loop calls this function for each input report received.
|
/* The Run Loop calls this function for each input report received.
|
||||||
@ -614,7 +656,8 @@ static void hid_report_callback(void *context, IOReturn result, void *sender,
|
|||||||
static void perform_signal_callback(void *context)
|
static void perform_signal_callback(void *context)
|
||||||
{
|
{
|
||||||
hid_device *dev = context;
|
hid_device *dev = context;
|
||||||
CFRunLoopStop(dev->run_loop); /*TODO: CFRunLoopGetCurrent()*/
|
|
||||||
|
stop_run_loop(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *read_thread(void *param)
|
static void *read_thread(void *param)
|
||||||
|
@ -163,7 +163,7 @@ int opHID_hidapi::open(int max, int vid, int pid, int usage_page, int usage)
|
|||||||
devices_found = false;
|
devices_found = false;
|
||||||
} else {
|
} else {
|
||||||
OPHID_DEBUG("HID Device Found");
|
OPHID_DEBUG("HID Device Found");
|
||||||
OPHID_DEBUG(" type:............VID(%04hx).PID(%04hx)", vid, pid);
|
OPHID_DEBUG(" type:............VID(%04hx).PID(%04hx)", (unsigned short)vid, (unsigned short)pid);
|
||||||
devices_found = true;
|
devices_found = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user