mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Make lambdas safer for multithreading
This commit is contained in:
parent
20cb84189e
commit
e5a2221eac
@ -68,7 +68,7 @@ namespace
|
||||
volatile bool finished = false;
|
||||
volatile Platform::Exception^ exception = nullptr;
|
||||
volatile T result;
|
||||
func().then([&](concurrency::task<T> t) {
|
||||
func().then([&finished, &exception, &result](concurrency::task<T> t) {
|
||||
try
|
||||
{
|
||||
result = t.get();
|
||||
@ -240,7 +240,7 @@ namespace
|
||||
if (*(path->End() - 1) == '\\')
|
||||
{
|
||||
/* Ends with a slash, so it's definitely a directory */
|
||||
return RunAsyncAndCatchErrors<StorageFolder^>([&]() {
|
||||
return RunAsyncAndCatchErrors<StorageFolder^>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(path));
|
||||
}, nullptr);
|
||||
}
|
||||
@ -248,12 +248,12 @@ namespace
|
||||
{
|
||||
/* No final slash - probably a file (since RetroArch usually slash-terminates dirs), but there is still a chance it's a directory */
|
||||
IStorageItem^ item;
|
||||
item = RunAsyncAndCatchErrors<StorageFile^>([&]() {
|
||||
item = RunAsyncAndCatchErrors<StorageFile^>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFile>(path));
|
||||
}, nullptr);
|
||||
if (!item)
|
||||
{
|
||||
item = RunAsyncAndCatchErrors<StorageFolder^>([&]() {
|
||||
item = RunAsyncAndCatchErrors<StorageFolder^>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(path));
|
||||
}, nullptr);
|
||||
}
|
||||
@ -306,18 +306,18 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uns
|
||||
|
||||
retro_assert(!dirpath_str->IsEmpty() && !filename_str->IsEmpty());
|
||||
|
||||
return RunAsyncAndCatchErrors<libretro_vfs_implementation_file*>([&]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(dirpath_str)).then([&](StorageFolder^ dir) {
|
||||
return RunAsyncAndCatchErrors<libretro_vfs_implementation_file*>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(dirpath_str)).then([=](StorageFolder^ dir) {
|
||||
if (mode == RETRO_VFS_FILE_ACCESS_READ)
|
||||
return dir->GetFileAsync(filename_str);
|
||||
else
|
||||
return dir->CreateFileAsync(filename_str, (mode & RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING) != 0 ?
|
||||
CreationCollisionOption::OpenIfExists : CreationCollisionOption::ReplaceExisting);
|
||||
}).then([&](StorageFile^ file) {
|
||||
}).then([=](StorageFile^ file) {
|
||||
FileAccessMode accessMode = mode == RETRO_VFS_FILE_ACCESS_READ ?
|
||||
FileAccessMode::Read : FileAccessMode::ReadWrite;
|
||||
return file->OpenAsync(accessMode);
|
||||
}).then([&](IRandomAccessStream^ fpstream) {
|
||||
}).then([=](IRandomAccessStream^ fpstream) {
|
||||
libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*stream));
|
||||
if (!stream)
|
||||
return (libretro_vfs_implementation_file*)NULL;
|
||||
@ -462,8 +462,8 @@ int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void
|
||||
return -1;
|
||||
|
||||
IBuffer^ buffer = CreateNativeBuffer(s, len, 0);
|
||||
return RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->ReadAsync(buffer, buffer->Capacity, InputStreamOptions::None)).then([&](IBuffer^ buf) {
|
||||
return RunAsyncAndCatchErrors<int64_t>([=]() {
|
||||
return concurrency::create_task(stream->fp->ReadAsync(buffer, buffer->Capacity, InputStreamOptions::None)).then([=](IBuffer^ buf) {
|
||||
retro_assert(buf == buffer);
|
||||
return (int64_t)buffer->Length;
|
||||
});
|
||||
@ -476,8 +476,8 @@ int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, cons
|
||||
return -1;
|
||||
|
||||
IBuffer^ buffer = CreateNativeBuffer(const_cast<void*>(s), len, len);
|
||||
return RunAsyncAndCatchErrors<int64_t>([&]() {
|
||||
return concurrency::create_task(stream->fp->WriteAsync(buffer)).then([&](unsigned int written) {
|
||||
return RunAsyncAndCatchErrors<int64_t>([=]() {
|
||||
return concurrency::create_task(stream->fp->WriteAsync(buffer)).then([=](unsigned int written) {
|
||||
return (int64_t)written;
|
||||
});
|
||||
}, -1);
|
||||
@ -488,8 +488,8 @@ int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream)
|
||||
if (!stream || !stream->fp)
|
||||
return -1;
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return concurrency::create_task(stream->fp->FlushAsync()).then([&](bool this_value_is_not_even_documented_wtf) {
|
||||
return RunAsyncAndCatchErrors<int>([=]() {
|
||||
return concurrency::create_task(stream->fp->FlushAsync()).then([=](bool this_value_is_not_even_documented_wtf) {
|
||||
/* The bool value may be reporting an error or something, but just leave it alone for now */
|
||||
/* https://github.com/MicrosoftDocs/winrt-api/issues/841 */
|
||||
return 0;
|
||||
@ -507,10 +507,10 @@ int retro_vfs_file_remove_impl(const char *path)
|
||||
Platform::String^ path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFile>(path_str)).then([&](StorageFile^ file) {
|
||||
return RunAsyncAndCatchErrors<int>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFile>(path_str)).then([=](StorageFile^ file) {
|
||||
return file->DeleteAsync(StorageDeleteOption::PermanentDelete);
|
||||
}).then([&]() {
|
||||
}).then([=]() {
|
||||
return 0;
|
||||
});
|
||||
}, -1);
|
||||
@ -543,19 +543,19 @@ int retro_vfs_file_rename_impl(const char *old_path, const char *new_path)
|
||||
|
||||
retro_assert(!old_path_str->IsEmpty() && !new_dir_path_str->IsEmpty() && !new_file_name_str->IsEmpty());
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return RunAsyncAndCatchErrors<int>([=]() {
|
||||
concurrency::task<StorageFile^> old_file_task = concurrency::create_task(LocateStorageItem<StorageFile>(old_path_str));
|
||||
concurrency::task<StorageFolder^> new_dir_task = concurrency::create_task(LocateStorageItem<StorageFolder>(new_dir_path_str));
|
||||
return concurrency::create_task([&] {
|
||||
return concurrency::create_task([=] {
|
||||
/* Run these two tasks in parallel */
|
||||
/* TODO: There may be some cleaner way to express this */
|
||||
concurrency::task_group group;
|
||||
group.run([&] { return old_file_task; });
|
||||
group.run([&] { return new_dir_task; });
|
||||
group.run([=] { return old_file_task; });
|
||||
group.run([=] { return new_dir_task; });
|
||||
group.wait();
|
||||
}).then([&]() {
|
||||
}).then([=]() {
|
||||
return old_file_task.get()->MoveAsync(new_dir_task.get(), new_file_name_str, NameCollisionOption::ReplaceExisting);
|
||||
}).then([&]() {
|
||||
}).then([=]() {
|
||||
return 0;
|
||||
});
|
||||
}, -1);
|
||||
@ -583,8 +583,8 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
|
||||
if (!item)
|
||||
return 0;
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return concurrency::create_task(item->GetBasicPropertiesAsync()).then([&](BasicProperties^ properties) {
|
||||
return RunAsyncAndCatchErrors<int>([=]() {
|
||||
return concurrency::create_task(item->GetBasicPropertiesAsync()).then([=](BasicProperties^ properties) {
|
||||
if (size)
|
||||
*size = properties->Size;
|
||||
return item->IsOfType(StorageItemTypes::Folder) ? RETRO_VFS_STAT_IS_VALID | RETRO_VFS_STAT_IS_DIRECTORY : RETRO_VFS_STAT_IS_VALID;
|
||||
@ -622,10 +622,10 @@ int retro_vfs_mkdir_impl(const char *dir)
|
||||
|
||||
free(dir_local);
|
||||
|
||||
return RunAsyncAndCatchErrors<int>([&]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(parent_path_str)).then([&](StorageFolder^ parent) {
|
||||
return RunAsyncAndCatchErrors<int>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(parent_path_str)).then([=](StorageFolder^ parent) {
|
||||
return parent->CreateFolderAsync(dir_name_str);
|
||||
}).then([&](concurrency::task<StorageFolder^> new_dir) {
|
||||
}).then([=](concurrency::task<StorageFolder^> new_dir) {
|
||||
try
|
||||
{
|
||||
new_dir.get();
|
||||
@ -668,8 +668,8 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *name, bool i
|
||||
Platform::String^ name_str = ref new Platform::String(name_wide);
|
||||
free(name_wide);
|
||||
|
||||
rdir->directory = RunAsyncAndCatchErrors<IVectorView<IStorageItem^>^>([&]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(name_str)).then([&](StorageFolder^ folder) {
|
||||
rdir->directory = RunAsyncAndCatchErrors<IVectorView<IStorageItem^>^>([=]() {
|
||||
return concurrency::create_task(LocateStorageItem<StorageFolder>(name_str)).then([=](StorageFolder^ folder) {
|
||||
return folder->GetItemsAsync();
|
||||
});
|
||||
}, nullptr);
|
||||
@ -741,7 +741,7 @@ bool uwp_drive_exists(const char *path)
|
||||
Platform::String^ path_str = ref new Platform::String(path_wide);
|
||||
free(path_wide);
|
||||
|
||||
return RunAsyncAndCatchErrors<bool>([&]() {
|
||||
return RunAsyncAndCatchErrors<bool>([=]() {
|
||||
return concurrency::create_task(StorageFolder::GetFolderFromPathAsync(path_str)).then([](StorageFolder^ properties) {
|
||||
return true;
|
||||
});
|
||||
@ -750,7 +750,7 @@ bool uwp_drive_exists(const char *path)
|
||||
|
||||
char* uwp_trigger_picker(void)
|
||||
{
|
||||
return RunAsyncAndCatchErrors<char*>([&]() {
|
||||
return RunAsyncAndCatchErrors<char*>([=]() {
|
||||
return TriggerPickerAddDialog().then([](Platform::String^ path) {
|
||||
return utf16_to_utf8_string_alloc(path->Data());
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user