When the timer thread is created in windows_init(), it performs an
initialisation phase in which it uses QueryPerformanceFrequency() to determine
if there is a high resolution timer available, and sets hires_frequency and
hires_ticks_to_ps appropriately. However, since windows_init() does not wait for
this initialisation phase to complete, windows_clock_gettime() can be called
before hires_frequency and hires_ticks_to_ps have been updated. This can result
in windows_clock_gettime() temporarily returning real-time clock values even
though the platform supports a monotonic clock.

This patch addresses this issue by having windows_init() wait until the timer
thread has initialised before returning.

Signed-off-by: Simon Haggett <simon.hagg...@realvnc.com>
---
 libusb/os/windows_usb.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 63357b1..097029c 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -886,6 +886,12 @@ static int windows_init(struct libusb_context *ctx)
                }
                SetThreadAffinityMask(timer_thread, 0);
 
+               // Wait for timer thread to init before continuing.
+               if (WaitForSingleObject(timer_response, INFINITE) != 
WAIT_OBJECT_0) {
+                       usbi_err(ctx, "Failed to wait for timer thread to 
become ready - aborting");
+                       goto init_exit;
+               }
+
                // Create a hash table to store session ids. Second parameter 
is better if prime
                htab_create(ctx, HTAB_SIZE);
        }
@@ -2172,6 +2178,11 @@ unsigned __stdcall windows_clock_gettime_threaded(void* 
param)
                usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", 
hires_frequency);
        }
 
+       // Signal windows_init() that we're ready to service requests
+       if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
+               usbi_dbg("unable to release timer semaphore: %s", 
windows_error_str(0));
+       }
+
        // Main loop - wait for requests
        while (1) {
                timer_index = WaitForMultipleObjects(2, timer_request, FALSE, 
INFINITE) - WAIT_OBJECT_0;
@@ -2206,7 +2217,7 @@ unsigned __stdcall windows_clock_gettime_threaded(void* 
param)
                        nb_responses = 
InterlockedExchange((LONG*)&request_count[0], 0);
                        if ( (nb_responses)
                          && (ReleaseSemaphore(timer_response, nb_responses, 
NULL) == 0) ) {
-                               usbi_dbg("unable to release timer semaphore %d: 
%s", windows_error_str(0));
+                               usbi_dbg("unable to release timer semaphore: 
%s", windows_error_str(0));
                        }
                        continue;
                case 1: // time to quit
-- 
1.7.9.5


------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to