From ce2f2d668e56f0aaca3550a28118eaba5ce861c5 Mon Sep 17 00:00:00 2001 From: James Zern Date: Thu, 27 Oct 2022 13:43:32 -0700 Subject: [PATCH] SharpYuvConvert: fix a race on SharpYuvGetCPUInfo Rather than make a copy, requiring an additional lock/unlock only to set the pointer to itself, pass the address of SharpYuvGetCPUInfo and use it as a sentinel to avoid updating the pointer. Change-Id: I22fb467f1659c16805c0d3bc7aaeba6a1bb16dbb --- sharpyuv/sharpyuv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sharpyuv/sharpyuv.c b/sharpyuv/sharpyuv.c index 6585041e..38153cce 100644 --- a/sharpyuv/sharpyuv.c +++ b/sharpyuv/sharpyuv.c @@ -439,7 +439,11 @@ void SharpYuvInit(VP8CPUInfo cpu_info_func) { static volatile VP8CPUInfo sharpyuv_last_cpuinfo_used = (VP8CPUInfo)&sharpyuv_last_cpuinfo_used; LOCK_ACCESS; - SharpYuvGetCPUInfo = cpu_info_func; + // Only update SharpYuvGetCPUInfo when called from external code to avoid a + // race on reading the value in SharpYuvConvert(). + if (cpu_info_func != (VP8CPUInfo)&SharpYuvGetCPUInfo) { + SharpYuvGetCPUInfo = cpu_info_func; + } if (sharpyuv_last_cpuinfo_used == SharpYuvGetCPUInfo) { UNLOCK_ACCESS_AND_RETURN; } @@ -484,7 +488,8 @@ int SharpYuvConvert(const void* r_ptr, const void* g_ptr, // Stride should be even for uint16_t buffers. return 0; } - SharpYuvInit(SharpYuvGetCPUInfo); + // The address of the function pointer is used to avoid a read race. + SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo); // Add scaling factor to go from rgb_bit_depth to yuv_bit_depth, to the // rgb->yuv conversion matrix.