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