| 927 | } |
| 928 | |
| 929 | static void *read_thread(void *param) |
| 930 | { |
| 931 | hid_device *dev = (hid_device*) param; |
| 932 | SInt32 code; |
| 933 | |
| 934 | /* Move the device's run loop to this thread. */ |
| 935 | IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); |
| 936 | |
| 937 | /* Create the RunLoopSource which is used to signal the |
| 938 | event loop to stop when hid_close() is called. */ |
| 939 | CFRunLoopSourceContext ctx; |
| 940 | memset(&ctx, 0, sizeof(ctx)); |
| 941 | ctx.version = 0; |
| 942 | ctx.info = dev; |
| 943 | ctx.perform = &perform_signal_callback; |
| 944 | dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx); |
| 945 | CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode); |
| 946 | |
| 947 | /* Store off the Run Loop so it can be stopped from hid_close() |
| 948 | and on device disconnection. */ |
| 949 | dev->run_loop = CFRunLoopGetCurrent(); |
| 950 | |
| 951 | /* Notify the main thread that the read thread is up and running. */ |
| 952 | pthread_barrier_wait(&dev->barrier); |
| 953 | |
| 954 | /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input |
| 955 | reports into the hid_report_callback(). */ |
| 956 | while (!dev->shutdown_thread && !dev->disconnected) { |
| 957 | code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); |
| 958 | /* Return if the device has been disconnected */ |
| 959 | if (code == kCFRunLoopRunFinished || code == kCFRunLoopRunStopped) { |
| 960 | dev->disconnected = 1; |
| 961 | break; |
| 962 | } |
| 963 | |
| 964 | |
| 965 | /* Break if The Run Loop returns Finished or Stopped. */ |
| 966 | if (code != kCFRunLoopRunTimedOut && |
| 967 | code != kCFRunLoopRunHandledSource) { |
| 968 | /* There was some kind of error. Setting |
| 969 | shutdown seems to make sense, but |
| 970 | there may be something else more appropriate */ |
| 971 | dev->shutdown_thread = 1; |
| 972 | break; |
| 973 | } |
| 974 | } |
| 975 | |
| 976 | /* Now that the read thread is stopping, Wake any threads which are |
| 977 | waiting on data (in hid_read_timeout()). Do this under a mutex to |
| 978 | make sure that a thread which is about to go to sleep waiting on |
| 979 | the condition actually will go to sleep before the condition is |
| 980 | signaled. */ |
| 981 | pthread_mutex_lock(&dev->mutex); |
| 982 | pthread_cond_broadcast(&dev->condition); |
| 983 | pthread_mutex_unlock(&dev->mutex); |
| 984 | |
| 985 | /* Wait here until hid_close() is called and makes it past |
| 986 | the call to CFRunLoopWakeUp(). This thread still needs to |
nothing calls this directly
no test coverage detected