When the timer thread is created in wince_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 wince_init() does not wait for this initialisation
phase to complete, wince_clock_gettime() can be called before hires_frequency
and hires_ticks_to_ps have been updated. This can result in
wince_clock_gettime() temporarily returning real-time clock values even though
the platform supports a monotonic clock.

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

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

diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c
index e4a6633..90c129b 100644
--- a/libusb/os/wince_usb.c
+++ b/libusb/os/wince_usb.c
@@ -234,6 +234,12 @@ static int wince_init(struct libusb_context *ctx)
                        usbi_err(ctx, "Unable to create timer thread - 
aborting");
                        goto init_exit;
                }
+
+               // 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;
+               }
        }
        // At this stage, either we went through full init successfully, or 
didn't need to
        r = LIBUSB_SUCCESS;
@@ -877,6 +883,11 @@ unsigned __stdcall wince_clock_gettime_threaded(void* 
param)
                usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", 
hires_frequency);
        }
 
+       // Signal wince_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;
@@ -911,7 +922,7 @@ unsigned __stdcall wince_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