shinyorg / shiny

.NET Framework for Backgrounding & Device Hardware Services (iOS, Android, & Catalyst)

Home Page:https://shinylib.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: Thread Safety GetCurrentPosition GPS manager extension method

JVanloofsvelt opened this issue · comments

Component/Nuget

GPS or Geofencing (Shiny.Locations)

What operating system(s) are effected?

  • iOS (13+ supported)
  • Mac Catalyst
  • Android (8+ supported)
  • Windows (.NET 7 Target - only Core is currently supported, BLE is coming)

Version(s) of Operation Systems

Any

Hosting Model

  • MAUI
  • Native/Classic Xamarin
  • Manual

Steps To Reproduce

Invoke IGpsManager.GetCurrentPosition() from two threads.

Expected Behavior

Invoking static IObservable<GpsReading> GetCurrentPosition(this IGpsManager gpsManager) yiels a location or throws an exception. It does this by possibly starting the gps listener, and then stopping the listener once finished.

Actual Behavior

Despite the use of a semaphore a race condition appears to be possible: by looking at the code it seems like it releases the semaphore before stopping the GPS manager, meaning a second thread can invoke GetCurrentPosition() as well, starting the GPS manager, only for the first thread to continue with stopping the listener.

I think the semaphore should only be released after the gps manager is stopped.

Extension method here:

public static IObservable<GpsReading> GetCurrentPosition(this IGpsManager gpsManager) => Observable.FromAsync(async ct =>

            ...
        }
        finally
        {
            currentLocSemaphore.Release();
            if (iStarted)
                await gpsManager.StopListener().ConfigureAwait(false);
        }

If I'm mistaken, I'm happy to hear why.

Exception or Log output

No response

Code Sample

No response

Code of Conduct

  • I have supplied a reproducible sample that is NOT FROM THE SHINY SAMPLES!
  • I am a Sponsor OR I am using the LATEST stable/beta version from nuget (v3.0 stable - ALPHAS are not taking issues - Sponsors can still send v2 issues)
  • I am Sponsor OR My GitHub account is 30+ days old
  • I understand that if I am checking these boxes and I am not actually following what they are saying, I will be removed from this repository!

This will be part of the next release. Honestly though, I wouldn't be hammering this method in any case. You are better to turn the listener on when you need it