[CoreFoundation] Ensure that we are thread safe. (#7397)

CFBundleGetAllBundles as per Apple docs is not thread safe, this means
that when we loop over the bundles, and use a property, the value is
updated by a different thread. This means that in some weird cases we
get an IndexOutOfBounds exception. We now store the count and use it in
the loop.

Fixes: https://github.com/xamarin/maccore/issues/940
This commit is contained in:
monojenkins 2019-11-09 06:45:01 +01:00 коммит произвёл Manuel de la Pena
Родитель c62f1e5186
Коммит d7b2c14982
1 изменённых файлов: 11 добавлений и 2 удалений

Просмотреть файл

@ -120,9 +120,18 @@ namespace CoreFoundation {
public static CFBundle[] GetAll ()
{
// as per apple documentation:
// CFBundleGetAllBundles
//
// 'This function is potentially expensive and not thread-safe'
//
// This means, that we should not trust the size of the array, since is a get and
// might be modified by a diff thread. We just use the size returned by the first
// count to avoid a System.IndexOutOfRangeException when looping
using (var cfBundles = new CFArray (CFBundleGetAllBundles ())) {
var managedBundles = new CFBundle [cfBundles.Count];
for (int index = 0; index < cfBundles.Count; index++) {
var bundleCount = cfBundles.Count;
var managedBundles = new CFBundle [bundleCount];
for (int index = 0; index < bundleCount; index++) {
// follow the get rule, we do not own the object
managedBundles [index] = new CFBundle (cfBundles.GetValue (index), false);
}