diff --git a/client/crash_report_database_mac.mm b/client/crash_report_database_mac.mm index c24b4a5d..e72838a0 100644 --- a/client/crash_report_database_mac.mm +++ b/client/crash_report_database_mac.mm @@ -43,6 +43,10 @@ #include "util/misc/initialization_state_dcheck.h" #include "util/misc/metrics.h" +#if BUILDFLAG(IS_IOS) +#include "util/ios/scoped_background_task.h" +#endif // BUILDFLAG(IS_IOS) + namespace crashpad { namespace { @@ -182,6 +186,10 @@ class CrashReportDatabaseMac : public CrashReportDatabase { //! \brief Stores the flock of the file for the duration of //! GetReportForUploading() and RecordUploadAttempt(). base::ScopedFD lock_fd; +#if BUILDFLAG(IS_IOS) + //! \brief Obtain a background task assertion while a flock is in use. + internal::ScopedBackgroundTask ios_background_task{"UploadReportMac"}; +#endif // BUILDFLAG(IS_IOS) }; //! \brief Locates a crash report in the database by UUID. diff --git a/client/settings.cc b/client/settings.cc index 966481d6..8fe578f9 100644 --- a/client/settings.cc +++ b/client/settings.cc @@ -71,6 +71,30 @@ void Settings::ScopedLockedFileHandle::Destroy() { #else // BUILDFLAG(IS_FUCHSIA) +#if BUILDFLAG(IS_IOS) + +Settings::ScopedLockedFileHandle::ScopedLockedFileHandle( + const FileHandle& value) + : ScopedGeneric(value) { + ios_background_task_ = std::make_unique( + "ScopedLockedFileHandle"); +} + +Settings::ScopedLockedFileHandle::ScopedLockedFileHandle( + Settings::ScopedLockedFileHandle&& rvalue) { + ios_background_task_.reset(rvalue.ios_background_task_.release()); + reset(rvalue.release()); +} + +Settings::ScopedLockedFileHandle& Settings::ScopedLockedFileHandle::operator=( + Settings::ScopedLockedFileHandle&& rvalue) { + ios_background_task_.reset(rvalue.ios_background_task_.release()); + reset(rvalue.release()); + return *this; +} + +#endif // BUILDFLAG(IS_IOS) + namespace internal { // static @@ -207,6 +231,10 @@ Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( } return ScopedLockedFileHandle(scoped.release(), base::FilePath()); #else + // It's important to create the ScopedLockedFileHandle before calling + // LoggingLockFile on iOS, so a ScopedBackgroundTask is created *before* + // the LoggingLockFile call below. + ScopedLockedFileHandle handle(kInvalidFileHandle); if (scoped.is_valid()) { if (LoggingLockFile( scoped.get(), locking, FileLockingBlocking::kBlocking) != @@ -214,7 +242,8 @@ Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( scoped.reset(); } } - return ScopedLockedFileHandle(scoped.release()); + handle.reset(scoped.release()); + return handle; #endif } diff --git a/client/settings.h b/client/settings.h index e476c60c..aedf30cd 100644 --- a/client/settings.h +++ b/client/settings.h @@ -24,6 +24,10 @@ #include "util/misc/initialization_state.h" #include "util/misc/uuid.h" +#if BUILDFLAG(IS_IOS) +#include "util/ios/scoped_background_task.h" +#endif // BUILDFLAG(IS_IOS) + namespace crashpad { namespace internal { @@ -153,7 +157,24 @@ class Settings { FileHandle handle_; base::FilePath lockfile_path_; }; -#else // BUILDFLAG(IS_FUCHSIA) +#elif BUILDFLAG(IS_IOS) + // iOS needs to use ScopedBackgroundTask anytime a file lock is used. + class ScopedLockedFileHandle + : public base::ScopedGeneric { + public: + using base::ScopedGeneric< + FileHandle, + internal::ScopedLockedFileHandleTraits>::ScopedGeneric; + + ScopedLockedFileHandle(const FileHandle& value); + ScopedLockedFileHandle(ScopedLockedFileHandle&& rvalue); + ScopedLockedFileHandle& operator=(ScopedLockedFileHandle&& rvalue); + + private: + std::unique_ptr ios_background_task_; + }; +#else using ScopedLockedFileHandle = base::ScopedGeneric; #endif // BUILDFLAG(IS_FUCHSIA)