Changeset 279601 in webkit


Ignore:
Timestamp:
Jul 6, 2021, 12:01:27 PM (4 years ago)
Author:
Chris Dumez
Message:

[iOS] Have ProcessAssertion take the RunningBoard assertion asynchronously by default
https://bugs.webkit.org/show_bug.cgi?id=225324
<rdar://76972252>

Reviewed by Geoffrey Garen.

Have ProcessAssertion take the RunningBoard assertion asynchronously (on a background thread) by
default as we have evidence that doing so on the main thread is bad for performance and may
negatively impact launch time.

When constructing a ProcessAssertion, the caller can now indicate if it wants the assertion to be
taken asynchronously (default) or not. Bug 227552 is an example of a case where we still want to
take the assertion synchronously (because we're not on the main thread and we need to make sure
we have the assertion before proceeding).

The caller can also provide a completion handler that will get called once the RunningBoard is
taken. Note that the RunningBoard async API ([RBSAssertion acquireWithInvalidationHandler]) does
not provide a way for us to know when the assertion is taken. For this reason, ProcessAssertion
keeps using the RunningBoard sync API ([RBSAssertion acquireWithError:]) but calls in on a
background queue.

For the UIProcess's background task though, we don't need to know when the assertion is taken
so we can use the RunningBoard async API.

Note that the previous iteration of this patch had a bug where the ProcessThrottler would release
its previous assertion before the new one is taken (asynchronously) when changing the assertion
type (e.g. foreground to background). This is addressed in this patch. ProcessThrottler now passes
an acquisition handler when constructing the ProcessAssertion and only releases its previous
assertion once the acquisition handler for the new one is taken.

  • NetworkProcess/Downloads/DownloadMap.cpp:

(WebKit::DownloadMap::add):

  • NetworkProcess/Downloads/DownloadMap.h:
  • Platform/IPC/cocoa/ConnectionCocoa.mm:

(IPC::ConnectionTerminationWatchdog::ConnectionTerminationWatchdog):

  • UIProcess/Downloads/DownloadProxyMap.cpp:

(WebKit::DownloadProxyMap::createDownloadProxy):

  • UIProcess/Downloads/DownloadProxyMap.h:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::setWebProcessHasUploads):

  • UIProcess/Network/NetworkProcessProxy.h:
  • UIProcess/ProcessAssertion.cpp:

(WebKit::ProcessAssertion::ProcessAssertion):

  • UIProcess/ProcessAssertion.h:

(WebKit::ProcessAssertion::create):

  • UIProcess/ProcessThrottler.cpp:

(WebKit::ProcessThrottler::setAssertionType):

  • UIProcess/ProcessThrottler.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::updateAudibleMediaAssertions):

  • UIProcess/WebProcessPool.h:
  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::updateAudibleMediaAssertions):

  • UIProcess/WebProcessProxy.h:
  • UIProcess/ios/ProcessAssertionIOS.mm:

(assertionsWorkQueue):
(-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]):
(-[WKProcessAssertionBackgroundTaskManager assertion:didInvalidateWithError:]):
(WebKit::ProcessAssertion::ProcessAssertion):
(WebKit::ProcessAssertion::acquireAsync):
(WebKit::ProcessAssertion::acquireSync):
(WebKit::ProcessAssertion::~ProcessAssertion):
(WebKit::ProcessAssertion::processAssertionWasInvalidated):
(WebKit::ProcessAssertion::isValid const):

Location:
trunk/Source/WebKit
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r279600 r279601  
     12021-07-06  Chris Dumez  <cdumez@apple.com>
     2
     3        [iOS] Have ProcessAssertion take the RunningBoard assertion asynchronously by default
     4        https://bugs.webkit.org/show_bug.cgi?id=225324
     5        <rdar://76972252>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Have ProcessAssertion take the RunningBoard assertion asynchronously (on a background thread) by
     10        default as we have evidence that doing so on the main thread is bad for performance and may
     11        negatively impact launch time.
     12
     13        When constructing a ProcessAssertion, the caller can now indicate if it wants the assertion to be
     14        taken asynchronously (default) or not. Bug 227552 is an example of a case where we still want to
     15        take the assertion synchronously (because we're not on the main thread and we need to make sure
     16        we have the assertion before proceeding).
     17
     18        The caller can also provide a completion handler that will get called once the RunningBoard is
     19        taken. Note that the RunningBoard async API ([RBSAssertion acquireWithInvalidationHandler]) does
     20        not provide a way for us to know when the assertion is taken. For this reason, ProcessAssertion
     21        keeps using the RunningBoard sync API ([RBSAssertion acquireWithError:]) but calls in on a
     22        background queue.
     23
     24        For the UIProcess's background task though, we don't need to know when the assertion is taken
     25        so we can use the RunningBoard async API.
     26
     27        Note that the previous iteration of this patch had a bug where the ProcessThrottler would release
     28        its previous assertion before the new one is taken (asynchronously) when changing the assertion
     29        type (e.g. foreground to background). This is addressed in this patch. ProcessThrottler now passes
     30        an acquisition handler when constructing the ProcessAssertion and only releases its previous
     31        assertion once the acquisition handler for the new one is taken.
     32
     33        * NetworkProcess/Downloads/DownloadMap.cpp:
     34        (WebKit::DownloadMap::add):
     35        * NetworkProcess/Downloads/DownloadMap.h:
     36        * Platform/IPC/cocoa/ConnectionCocoa.mm:
     37        (IPC::ConnectionTerminationWatchdog::ConnectionTerminationWatchdog):
     38        * UIProcess/Downloads/DownloadProxyMap.cpp:
     39        (WebKit::DownloadProxyMap::createDownloadProxy):
     40        * UIProcess/Downloads/DownloadProxyMap.h:
     41        * UIProcess/Network/NetworkProcessProxy.cpp:
     42        (WebKit::NetworkProcessProxy::setWebProcessHasUploads):
     43        * UIProcess/Network/NetworkProcessProxy.h:
     44        * UIProcess/ProcessAssertion.cpp:
     45        (WebKit::ProcessAssertion::ProcessAssertion):
     46        * UIProcess/ProcessAssertion.h:
     47        (WebKit::ProcessAssertion::create):
     48        * UIProcess/ProcessThrottler.cpp:
     49        (WebKit::ProcessThrottler::setAssertionType):
     50        * UIProcess/ProcessThrottler.h:
     51        * UIProcess/WebProcessPool.cpp:
     52        (WebKit::WebProcessPool::updateAudibleMediaAssertions):
     53        * UIProcess/WebProcessPool.h:
     54        * UIProcess/WebProcessProxy.cpp:
     55        (WebKit::WebProcessProxy::updateAudibleMediaAssertions):
     56        * UIProcess/WebProcessProxy.h:
     57        * UIProcess/ios/ProcessAssertionIOS.mm:
     58        (assertionsWorkQueue):
     59        (-[WKProcessAssertionBackgroundTaskManager _updateBackgroundTask]):
     60        (-[WKProcessAssertionBackgroundTaskManager assertion:didInvalidateWithError:]):
     61        (WebKit::ProcessAssertion::ProcessAssertion):
     62        (WebKit::ProcessAssertion::acquireAsync):
     63        (WebKit::ProcessAssertion::acquireSync):
     64        (WebKit::ProcessAssertion::~ProcessAssertion):
     65        (WebKit::ProcessAssertion::processAssertionWasInvalidated):
     66        (WebKit::ProcessAssertion::isValid const):
     67
    1682021-07-06  Sihui Liu  <sihui_liu@apple.com>
    269
  • trunk/Source/WebKit/NetworkProcess/Downloads/DownloadMap.cpp

    r268017 r279601  
    6262    if (m_downloads.size() == 1) {
    6363        ASSERT(!m_downloadAssertion);
    64         m_downloadAssertion = makeUnique<ProcessAssertion>(getpid(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
     64        m_downloadAssertion = ProcessAssertion::create(getpid(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
    6565        RELEASE_LOG(ProcessSuspension, "Took 'WebKit downloads' assertion in NetworkProcess");
    6666    }
  • trunk/Source/WebKit/NetworkProcess/Downloads/DownloadMap.h

    r243110 r279601  
    5454private:
    5555    DownloadMapType m_downloads;
    56     std::unique_ptr<ProcessAssertion> m_downloadAssertion;
     56    RefPtr<ProcessAssertion> m_downloadAssertion;
    5757};
    5858
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r279514 r279601  
    578578#if PLATFORM(IOS_FAMILY)
    579579    WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
    580     std::unique_ptr<ProcessAssertion> m_holdingLockedFileAssertion;
     580    RefPtr<ProcessAssertion> m_holdingLockedFileAssertion;
    581581#endif
    582582
  • trunk/Source/WebKit/NetworkProcess/ios/NetworkProcessIOS.mm

    r279526 r279601  
    113113    // We synchronously take a process assertion when beginning a SQLite transaction so that we don't get suspended
    114114    // while holding a locked file. We would get killed if suspended while holding locked files.
    115     m_holdingLockedFileAssertion = makeUnique<ProcessAssertion>(getCurrentProcessID(), "Network Process is holding locked files"_s, ProcessAssertionType::FinishTaskUninterruptable);
     115    m_holdingLockedFileAssertion = ProcessAssertion::create(getCurrentProcessID(), "Network Process is holding locked files"_s, ProcessAssertionType::FinishTaskUninterruptable, ProcessAssertion::Mode::Sync);
    116116}
    117117
  • trunk/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm

    r278338 r279601  
    9090        , m_watchdogTimer(RunLoop::main(), this, &ConnectionTerminationWatchdog::watchdogTimerFired)
    9191#if PLATFORM(IOS_FAMILY)
    92         , m_assertion(makeUnique<WebKit::ProcessAndUIAssertion>(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::ProcessAssertionType::Background))
     92        , m_assertion(WebKit::ProcessAndUIAssertion::create(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::ProcessAssertionType::Background))
    9393#endif
    9494    {
     
    105105    RunLoop::Timer<ConnectionTerminationWatchdog> m_watchdogTimer;
    106106#if PLATFORM(IOS_FAMILY)
    107     std::unique_ptr<WebKit::ProcessAndUIAssertion> m_assertion;
     107    Ref<WebKit::ProcessAndUIAssertion> m_assertion;
    108108#endif
    109109};
  • trunk/Source/WebKit/Platform/spi/ios/RunningBoardServicesSPI.h

    r279412 r279601  
    5656@end
    5757
     58@class RBSAssertion;
    5859@protocol RBSAssertionObserving;
     60typedef void (^RBSAssertionInvalidationHandler)(RBSAssertion *assertion, NSError *error);
    5961
    6062@interface RBSAssertion : NSObject
    6163- (instancetype)initWithExplanation:(NSString *)explanation target:(RBSTarget *)target attributes:(NSArray <RBSAttribute *> *)attributes;
    6264- (BOOL)acquireWithError:(NSError **)error;
     65- (void)acquireWithInvalidationHandler:(nullable RBSAssertionInvalidationHandler)handler;
    6366- (void)invalidate;
    6467- (void)addObserver:(id <RBSAssertionObserving>)observer;
  • trunk/Source/WebKit/UIProcess/Downloads/DownloadProxyMap.cpp

    r268485 r279601  
    9191    if (m_downloads.size() == 1 && m_shouldTakeAssertion) {
    9292        ASSERT(!m_downloadUIAssertion);
    93         m_downloadUIAssertion = makeUnique<ProcessAssertion>(getCurrentProcessID(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
     93        m_downloadUIAssertion = ProcessAssertion::create(getCurrentProcessID(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
    9494
    9595        ASSERT(!m_downloadNetworkingAssertion);
    96         m_downloadNetworkingAssertion = makeUnique<ProcessAssertion>(m_process.processIdentifier(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
     96        m_downloadNetworkingAssertion = ProcessAssertion::create(m_process.processIdentifier(), "WebKit downloads"_s, ProcessAssertionType::UnboundedNetworking);
    9797
    9898        RELEASE_LOG(ProcessSuspension, "UIProcess took 'WebKit downloads' assertions for UIProcess and NetworkProcess");
  • trunk/Source/WebKit/UIProcess/Downloads/DownloadProxyMap.h

    r267763 r279601  
    7676
    7777    bool m_shouldTakeAssertion { false };
    78     std::unique_ptr<ProcessAssertion> m_downloadUIAssertion;
    79     std::unique_ptr<ProcessAssertion> m_downloadNetworkingAssertion;
     78    RefPtr<ProcessAssertion> m_downloadUIAssertion;
     79    RefPtr<ProcessAssertion> m_downloadNetworkingAssertion;
    8080
    8181#if PLATFORM(IOS_FAMILY)
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r279514 r279601  
    14431443        RELEASE_LOG(ProcessSuspension, "NetworkProcessProxy::setWebProcessHasUploads: The number of uploads in progress is now greater than 0. Taking Networking and UI process assertions.");
    14441444        m_uploadActivity = UploadActivity {
    1445             makeUnique<ProcessAssertion>(getCurrentProcessID(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
    1446             makeUnique<ProcessAssertion>(processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
    1447             HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>>()
     1445            ProcessAssertion::create(getCurrentProcessID(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
     1446            ProcessAssertion::create(processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking),
     1447            HashMap<WebCore::ProcessIdentifier, RefPtr<ProcessAssertion>>()
    14481448        };
    14491449    }
     
    14511451    m_uploadActivity->webProcessAssertions.ensure(processID, [&] {
    14521452        RELEASE_LOG(ProcessSuspension, "NetworkProcessProxy::setWebProcessHasUploads: Taking upload assertion on behalf of WebProcess with PID %d", process->processIdentifier());
    1453         return makeUnique<ProcessAssertion>(process->processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking);
     1453        return ProcessAssertion::create(process->processIdentifier(), "WebKit uploads"_s, ProcessAssertionType::UnboundedNetworking);
    14541454    });
    14551455}
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h

    r279514 r279601  
    345345
    346346    struct UploadActivity {
    347         std::unique_ptr<ProcessAssertion> uiAssertion;
    348         std::unique_ptr<ProcessAssertion> networkAssertion;
    349         HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>> webProcessAssertions;
     347        RefPtr<ProcessAssertion> uiAssertion;
     348        RefPtr<ProcessAssertion> networkAssertion;
     349        HashMap<WebCore::ProcessIdentifier, RefPtr<ProcessAssertion>> webProcessAssertions;
    350350    };
    351351    std::optional<UploadActivity> m_uploadActivity;
  • trunk/Source/WebKit/UIProcess/ProcessAssertion.cpp

    r279514 r279601  
    4747}
    4848
     49void ProcessAssertion::acquireAsync(CompletionHandler<void()>&& completionHandler)
     50{
     51    if (completionHandler)
     52        RunLoop::main().dispatch(WTFMove(completionHandler));
     53}
     54
     55void ProcessAssertion::acquireSync()
     56{
     57}
     58
    4959ProcessAndUIAssertion::ProcessAndUIAssertion(ProcessID pid, const String& reason, ProcessAssertionType assertionType)
    5060    : ProcessAssertion(pid, reason, assertionType)
  • trunk/Source/WebKit/UIProcess/ProcessAssertion.h

    r279514 r279601  
    2626#pragma once
    2727
     28#include <wtf/CompletionHandler.h>
    2829#include <wtf/Function.h>
    2930#include <wtf/ProcessID.h>
     31#include <wtf/ThreadSafeRefCounted.h>
    3032#include <wtf/WeakPtr.h>
    3133#include <wtf/text/WTFString.h>
     
    5355};
    5456
    55 class ProcessAssertion : public CanMakeWeakPtr<ProcessAssertion> {
     57class ProcessAssertion : public ThreadSafeRefCounted<ProcessAssertion>, public CanMakeWeakPtr<ProcessAssertion> {
    5658    WTF_MAKE_FAST_ALLOCATED;
    5759public:
    58     ProcessAssertion(ProcessID, const String& reason, ProcessAssertionType);
     60    enum class Mode : bool { Sync, Async };
     61    static Ref<ProcessAssertion> create(ProcessID pid, const String& reason, ProcessAssertionType type, Mode mode = Mode::Async, CompletionHandler<void()>&& acquisisionHandler = nullptr)
     62    {
     63        auto assertion = adoptRef(*new ProcessAssertion(pid, reason, type));
     64        if (mode == Mode::Async)
     65            assertion->acquireAsync(WTFMove(acquisisionHandler));
     66        else {
     67            assertion->acquireSync();
     68            if (acquisisionHandler)
     69                acquisisionHandler();
     70        }
     71        return assertion;
     72    }
    5973    virtual ~ProcessAssertion();
    6074
     
    6680    bool isValid() const;
    6781
     82protected:
     83    ProcessAssertion(ProcessID, const String& reason, ProcessAssertionType);
     84
     85    void acquireAsync(CompletionHandler<void()>&&);
     86    void acquireSync();
     87
    6888#if PLATFORM(IOS_FAMILY)
    69 protected:
    7089    virtual void processAssertionWasInvalidated();
    7190#endif
     
    7897    RetainPtr<RBSAssertion> m_rbsAssertion;
    7998    RetainPtr<WKRBSAssertionDelegate> m_delegate;
     99    bool m_wasInvalidated { false };
    80100#endif
    81101    Function<void()> m_invalidationHandler;
     
    84104class ProcessAndUIAssertion final : public ProcessAssertion {
    85105public:
    86     ProcessAndUIAssertion(ProcessID, const String& reason, ProcessAssertionType);
     106    static Ref<ProcessAndUIAssertion> create(ProcessID pid, const String& reason, ProcessAssertionType type, Mode mode = Mode::Async, CompletionHandler<void()>&& acquisisionHandler = nullptr)
     107    {
     108        auto assertion = adoptRef(*new ProcessAndUIAssertion(pid, reason, type));
     109        if (mode == Mode::Async)
     110            assertion->acquireAsync(WTFMove(acquisisionHandler));
     111        else {
     112            assertion->acquireSync();
     113            if (acquisisionHandler)
     114                acquisisionHandler();
     115        }
     116        return assertion;
     117    }
    87118    ~ProcessAndUIAssertion();
    88119
     
    92123
    93124private:
     125    ProcessAndUIAssertion(ProcessID, const String& reason, ProcessAssertionType);
     126
    94127#if PLATFORM(IOS_FAMILY)
    95128    void processAssertionWasInvalidated() final;
  • trunk/Source/WebKit/UIProcess/ProcessThrottler.cpp

    r279514 r279601  
    130130    PROCESSTHROTTLER_RELEASE_LOG("setAssertionType: Updating process assertion type to %u (foregroundActivities=%u, backgroundActivities=%u)", newType, m_foregroundActivities.size(), m_backgroundActivities.size());
    131131
    132     // Keep the previous assertion around until after the new one has been created so that we always hold
    133     // a process assertion for the process.
     132    // Keep the previous assertion active until the new assertion is taken asynchronously.
    134133    auto previousAssertion = std::exchange(m_assertion, nullptr);
    135134    if (m_shouldTakeUIBackgroundAssertion) {
    136         auto assertion = makeUnique<ProcessAndUIAssertion>(m_processIdentifier, assertionName(newType), newType);
    137         assertion->setUIAssertionExpirationHandler([this] {
    138             uiAssertionWillExpireImminently();
     135        auto assertion = ProcessAndUIAssertion::create(m_processIdentifier, assertionName(newType), newType, ProcessAssertion::Mode::Async, [previousAssertion = WTFMove(previousAssertion)] { });
     136        assertion->setUIAssertionExpirationHandler([weakThis = makeWeakPtr(*this)] {
     137            if (weakThis)
     138                weakThis->uiAssertionWillExpireImminently();
    139139        });
    140140        m_assertion = WTFMove(assertion);
    141141    } else
    142         m_assertion = makeUnique<ProcessAssertion>(m_processIdentifier, assertionName(newType), newType);
    143 
    144     m_assertion->setInvalidationHandler([this] {
    145         assertionWasInvalidated();
     142        m_assertion = ProcessAssertion::create(m_processIdentifier, assertionName(newType), newType, ProcessAssertion::Mode::Async, [previousAssertion = WTFMove(previousAssertion)] { });
     143
     144    m_assertion->setInvalidationHandler([weakThis = makeWeakPtr(*this)] {
     145        if (weakThis)
     146            weakThis->assertionWasInvalidated();
    146147    });
    147148    m_process.didSetAssertionType(newType);
  • trunk/Source/WebKit/UIProcess/ProcessThrottler.h

    r278253 r279601  
    150150    ProcessThrottlerClient& m_process;
    151151    ProcessID m_processIdentifier { 0 };
    152     std::unique_ptr<ProcessAssertion> m_assertion;
     152    RefPtr<ProcessAssertion> m_assertion;
    153153    RunLoop::Timer<ProcessThrottler> m_prepareToSuspendTimeoutTimer;
    154154    HashSet<ForegroundActivity*> m_foregroundActivities;
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r279591 r279601  
    20332033    WEBPROCESSPOOL_RELEASE_LOG(ProcessSuspension, "updateAudibleMediaAssertions: The number of processes playing audible media is now greater than zero. Taking UI process assertion.");
    20342034    m_audibleMediaActivity = AudibleMediaActivity {
    2035         makeUniqueRef<ProcessAssertion>(getCurrentProcessID(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback)
     2035        ProcessAssertion::create(getCurrentProcessID(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback)
    20362036#if ENABLE(GPU_PROCESS)
    2037         , gpuProcess() ? makeUnique<ProcessAssertion>(gpuProcess()->processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback) : nullptr
     2037        , gpuProcess() ? RefPtr<ProcessAssertion> { ProcessAssertion::create(gpuProcess()->processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback) } : nullptr
    20382038#endif
    20392039    };
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r279591 r279601  
    772772
    773773    struct AudibleMediaActivity {
    774         UniqueRef<ProcessAssertion> uiProcessMediaPlaybackAssertion;
     774        Ref<ProcessAssertion> uiProcessMediaPlaybackAssertion;
    775775#if ENABLE(GPU_PROCESS)
    776         std::unique_ptr<ProcessAssertion> gpuProcessMediaPlaybackAssertion;
     776        RefPtr<ProcessAssertion> gpuProcessMediaPlaybackAssertion;
    777777#endif
    778778    };
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r279583 r279601  
    14891489        WEBPROCESSPROXY_RELEASE_LOG(ProcessSuspension, "updateAudibleMediaAssertions: Taking MediaPlayback assertion for WebProcess");
    14901490        m_audibleMediaActivity = AudibleMediaActivity {
    1491             makeUniqueRef<ProcessAssertion>(processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback),
     1491            ProcessAssertion::create(processIdentifier(), "WebKit Media Playback"_s, ProcessAssertionType::MediaPlayback),
    14921492            processPool().webProcessWithAudibleMediaToken()
    14931493        };
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r279583 r279601  
    637637
    638638    struct AudibleMediaActivity {
    639         UniqueRef<ProcessAssertion> assertion;
     639        Ref<ProcessAssertion> assertion;
    640640        WebProcessWithAudibleMediaToken token;
    641641    };
  • trunk/Source/WebKit/UIProcess/ios/ProcessAssertionIOS.mm

    r279514 r279601  
    4242using WebKit::ProcessAndUIAssertion;
    4343
     44static WorkQueue& assertionsWorkQueue()
     45{
     46    static NeverDestroyed<Ref<WorkQueue>> workQueue(WorkQueue::create("ProcessAssertion Queue"));
     47    return workQueue.get();
     48}
     49
    4450// This gives some time to our child processes to process the ProcessWillSuspendImminently IPC but makes sure we release
    4551// the background task before the UIKit timeout (We get killed if we do not release the background task within 5 seconds
     
    6571{
    6672    RetainPtr<RBSAssertion> _backgroundTask;
     73    std::atomic<bool> _backgroundTaskWasInvalidated;
    6774    WeakHashSet<ProcessAndUIAssertion> _assertionsNeedingBackgroundTask;
    6875    dispatch_block_t _pendingTaskReleaseTask;
     
    161168- (void)_updateBackgroundTask
    162169{
    163     if (!_assertionsNeedingBackgroundTask.computesEmpty() && ![self _hasBackgroundTask]) {
     170    if (!_assertionsNeedingBackgroundTask.computesEmpty() && (![self _hasBackgroundTask] || _backgroundTaskWasInvalidated)) {
    164171        if (processHasActiveRunTimeLimitation()) {
    165172            RELEASE_LOG(ProcessSuspension, "%p - WKProcessAssertionBackgroundTaskManager: Ignored request to start a new background task because RunningBoard has already started the expiration timer", self);
     
    172179        [_backgroundTask addObserver:self];
    173180
    174         NSError *acquisitionError = nil;
    175         if (![_backgroundTask acquireWithError:&acquisitionError])
    176             RELEASE_LOG_ERROR(ProcessSuspension, "WKProcessAssertionBackgroundTaskManager: Failed to acquire FinishTaskInterruptable assertion for own process, error: %{public}@", acquisitionError);
    177         else
    178             RELEASE_LOG(ProcessSuspension, "WKProcessAssertionBackgroundTaskManager: Successfully took a FinishTaskInterruptable assertion for own process");
     181        _backgroundTaskWasInvalidated = false;
     182        [_backgroundTask acquireWithInvalidationHandler:nil];
     183        RELEASE_LOG(ProcessSuspension, "WKProcessAssertionBackgroundTaskManager: Took a FinishTaskInterruptable assertion for own process");
    179184    } else if (_assertionsNeedingBackgroundTask.computesEmpty()) {
    180185        // Release the background task asynchronously because releasing the background task may destroy the ProcessThrottler and we don't
     
    197202    ASSERT(assertion == _backgroundTask.get());
    198203    RELEASE_LOG_ERROR(ProcessSuspension, "WKProcessAssertionBackgroundTaskManager: FinishTaskInterruptable assertion was invalidated, error: %{public}@", error);
     204    _backgroundTaskWasInvalidated = true;
    199205}
    200206
     
    320326    if (!pid) {
    321327        RELEASE_LOG_ERROR(ProcessSuspension, "%p - ProcessAssertion: Failed to acquire RBS %{public}@ assertion '%{public}s' for process because PID is invalid", this, runningBoardAssertionName, reason.utf8().data());
     328        m_wasInvalidated = true;
    322329        return;
    323330    }
     
    330337    [m_rbsAssertion addObserver:m_delegate.get()];
    331338    m_delegate.get().invalidationCallback = ^{
    332         RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion() RBS %{public}@ assertion for process with PID=%d was invalidated", this, runningBoardAssertionName, pid);
     339        RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion: RBS %{public}@ assertion for process with PID=%d was invalidated", this, runningBoardAssertionName, pid);
    333340        processAssertionWasInvalidated();
    334341    };
    335 
     342}
     343
     344void ProcessAssertion::acquireAsync(CompletionHandler<void()>&& completionHandler)
     345{
     346    assertionsWorkQueue().dispatch([protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
     347        protectedThis->acquireSync();
     348        if (completionHandler)
     349            RunLoop::main().dispatch(WTFMove(completionHandler));
     350    });
     351}
     352
     353void ProcessAssertion::acquireSync()
     354{
    336355    NSError *acquisitionError = nil;
    337356    if (![m_rbsAssertion acquireWithError:&acquisitionError]) {
    338         RELEASE_LOG_ERROR(ProcessSuspension, "%p - ProcessAssertion: Failed to acquire RBS %{public}@ assertion '%{public}s' for process with PID=%d, error: %{public}@", this, runningBoardAssertionName, reason.utf8().data(), pid, acquisitionError);
     357        RELEASE_LOG_ERROR(ProcessSuspension, "%p - ProcessAssertion: Failed to acquire RBS assertion '%{public}s' for process with PID=%d, error: %{public}@", this, m_reason.utf8().data(), m_pid, acquisitionError);
    339358        RunLoop::main().dispatch([weakThis = makeWeakPtr(*this)] {
    340359            if (weakThis)
     
    342361        });
    343362    } else
    344         RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion: Successfully took RBS %{public}@ assertion '%{public}s' for process with PID=%d", this, runningBoardAssertionName, reason.utf8().data(), pid);
     363        RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion: Successfully took RBS assertion '%{public}s' for process with PID=%d", this, m_reason.utf8().data(), m_pid);
    345364}
    346365
    347366ProcessAssertion::~ProcessAssertion()
    348367{
    349     RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion() Releasing process assertion '%{public}s' for process with PID=%d", this, m_reason.utf8().data(), m_pid);
     368    RELEASE_LOG(ProcessSuspension, "%p - ~ProcessAssertion: Releasing process assertion '%{public}s' for process with PID=%d", this, m_reason.utf8().data(), m_pid);
    350369
    351370    if (m_rbsAssertion) {
     
    362381    RELEASE_LOG(ProcessSuspension, "%p - ProcessAssertion::processAssertionWasInvalidated() PID=%d", this, m_pid);
    363382
     383    m_wasInvalidated = true;
    364384    if (m_invalidationHandler)
    365385        m_invalidationHandler();
     
    368388bool ProcessAssertion::isValid() const
    369389{
    370     return m_rbsAssertion && m_rbsAssertion.get().valid;
     390    return !m_wasInvalidated;
    371391}
    372392
Note: See TracChangeset for help on using the changeset viewer.